package idv.Zero.KerKerInput.Methods;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.view.KeyEvent;
import idv.Zero.KerKerInput.KerKerInputCore;
import idv.Zero.KerKerInput.Keyboard;
import idv.Zero.KerKerInput.R;
public class CJInput extends idv.Zero.KerKerInput.IKerKerInputMethod {
private StringBuilder inputBufferRaw = new StringBuilder();
private List<CharSequence> _currentCandidates;
private String _dbpath;
private int _currentPage;
private int _totalPages;
private HashMap<CharSequence, CharSequence> keyNames;
private SQLiteDatabase db;
private boolean copying = false;
private String _name;
public void initInputMethod(KerKerInputCore core) {
super.initInputMethod(core);
_currentPage = 0;
_currentCandidates = new ArrayList<CharSequence>();
final Context c = core.getFrontend();
_name = c.getString(R.string.changjei5);
_dbpath = c.getDatabasePath("cj5.db").toString();
keyNames = new HashMap<CharSequence, CharSequence>();
try
{
db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
loadKeyNames();
db.close();
}
catch(SQLiteException ex)
{
db = null;
System.out.println("Error, no database file found. Copying...");
new Thread(new Runnable() {
public void run() {
copying = true;
// Create the database (and the directories required) then close it.
db = c.openOrCreateDatabase("cj5.db", 0, null);
db.close();
try {
OutputStream dos = new FileOutputStream(_dbpath);
InputStream dis = new FileInputStream("/sdcard/cj5.db");
byte[] buffer = new byte[32768];
while (dis.read(buffer) > 0)
{
dos.write(buffer);
}
dos.flush();
dos.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
db.setLocale(Locale.TRADITIONAL_CHINESE);
loadKeyNames();
copying = false;
}
}).start();
}
}
public void onEnterInputMethod()
{
if (!copying && !db.isOpen())
{
db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
db.setLocale(Locale.TRADITIONAL_CHINESE);
}
inputBufferRaw.delete(0, inputBufferRaw.length());
updateCandidates();
}
public void onLeaveInputMethod()
{
if (db != null && db.isOpen())
db.close();
}
public String getName()
{
return _name;
}
public Keyboard getDesiredKeyboard() {
return new Keyboard(_core.getFrontend(), R.xml.kb_cj, R.id.mode_normal);
}
public void commitCurrentComposingBuffer() {
commitText(getCompositeString());
}
public boolean onKeyEvent(int keyCode, int[] keyCodes) {
return handleCJInput(keyCode, keyCodes);
}
private boolean handleCJInput(int keyCode, int[] keyCodes) {
if (keyCode == Keyboard.KEYCODE_DELETE)
{
if (inputBufferRaw.length() > 0)
{
inputBufferRaw.deleteCharAt(inputBufferRaw.length() - 1);
}
else
_core.getFrontend().sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
}
else if (keyCode == 10)
{
if (inputBufferRaw.length() > 0)
commitText(getCompositeString());
else
_core.getFrontend().sendKeyChar((char) keyCode);
}
else if(((keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) || (keyCode == 32)) && inputBufferRaw.length() > 0)
{
if (keyCode == 32)
{
if (_currentCandidates.size() > 0)
keyCode = KeyEvent.KEYCODE_0;
else
_core.getFrontend().sendKeyChar((char) keyCode);
}
if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9)
{
int CANDIDATES_PER_PAGE = (_currentCandidates.size() / _totalPages);
if ((_currentPage * CANDIDATES_PER_PAGE + keyCode - KeyEvent.KEYCODE_0 - 1) < _currentCandidates.size())
{
commitCandidate(_currentPage * CANDIDATES_PER_PAGE + keyCode - KeyEvent.KEYCODE_0);
inputBufferRaw.delete(0, inputBufferRaw.length());
}
}
}
else
{
char c = (char)keyCode;
inputBufferRaw.append(c);
}
_core.setCompositeBuffer(getCompositeString());
updateCandidates();
return true;
}
private CharSequence getCompositeString() {
StringBuilder str = new StringBuilder();
int length = inputBufferRaw.length();
for(int i=0;i<length;i++)
str.append(keyNames.get(Character.toString(inputBufferRaw.charAt(i))));
return str.toString();
}
private void updateCandidates() {
if (inputBufferRaw.length() == 0)
{
_core.hideCandidatesView();
return;
}
if (db == null)
return;
Cursor currentQuery = null;
try
{
currentQuery = db.rawQuery("Select val from NewCJ3 where key >= '" + inputBufferRaw.toString() + "' AND key < '" + inputBufferRaw.toString() + "zzz'", null);
if (currentQuery.getCount() == 0)
{
inputBufferRaw.deleteCharAt(inputBufferRaw.length() - 1);
_currentCandidates.clear();
_core.setCompositeBuffer(getCompositeString());
_core.showPopup(R.string.no_such_mapping);
_core.hideCandidatesView();
updateCandidates();
return;
}
else
{
int count = Math.min(currentQuery.getCount(), 50);
int colIdx = currentQuery.getColumnIndex("val");
_currentCandidates = new ArrayList<CharSequence>(count);
currentQuery.moveToNext();
for(int i=0;i<count;i++)
{
String ca = currentQuery.getString(colIdx);
_currentCandidates.add(ca);
currentQuery.moveToNext();
}
_core.setCandidates(_currentCandidates);
_core.showCandidatesView();
}
}
catch(Exception e) {}
finally
{
if (currentQuery != null)
currentQuery.close();
}
}
public void commitCandidate(int selectedCandidate)
{
commitText(_currentCandidates.get(selectedCandidate));
}
private void commitText(CharSequence str)
{
_core.getConnection().commitText(str, 1);
_core.hideCandidatesView();
inputBufferRaw.delete(0, inputBufferRaw.length());
}
public void setTotalPages(int totalPages)
{
_totalPages = totalPages;
}
public void setCurrentPage(int currentPage)
{
_currentPage = currentPage;
}
private void loadKeyNames()
{
if (db == null)
return;
Cursor currentQuery = db.rawQuery("Select * from keyname", null);
if (currentQuery.getCount() == 0)
return;
else
{
int count = currentQuery.getCount();
int colKey = currentQuery.getColumnIndex("key");
int colVal = currentQuery.getColumnIndex("val");
currentQuery.moveToNext();
for(int i=0;i<count;i++)
{
keyNames.put(currentQuery.getString(colKey), currentQuery.getString(colVal));
currentQuery.moveToNext();
}
}
currentQuery.close();
// Make sure if user pressed any keys during database init gets reflected.
_core.setCompositeBuffer(getCompositeString());
updateCandidates();
}
}