package idv.Zero.KerKerInput.Methods;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
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 NoSeeing extends idv.Zero.KerKerInput.IKerKerInputMethod {
private StringBuilder inputBufferRaw = new StringBuilder();
private List<CharSequence> _currentCandidates;
private String _dbpath;
private int _currentPage;
private int _totalPages;
private boolean copying = false;
private SQLiteDatabase db;
public void initInputMethod(KerKerInputCore core) {
super.initInputMethod(core);
_currentPage = 0;
_currentCandidates = new ArrayList<CharSequence>();
final Context c = core.getFrontend();
_dbpath = c.getDatabasePath("noseeing.db").toString();
try
{
db = SQLiteDatabase.openDatabase(_dbpath, null, SQLiteDatabase.OPEN_READONLY);
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("noseeing.db", 0, null);
db.close();
try {
OutputStream dos = new FileOutputStream(_dbpath);
//InputStream dis = c.getResources().openRawResource(R.raw.noseeing);
InputStream dis = c.getResources().openRawResource(R.raw.bpmf); // Intentionally use wrong db here.
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);
copying = false;
}
}).start();
}
}
public void onEnterInputMethod()
{
if (!copying)
{
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.close();
}
public String getName()
{
return "嘸蝦米";
}
public Keyboard getDesiredKeyboard() {
return new Keyboard(_core.getFrontend(), R.xml.kb_noseeing, R.id.mode_normal);
}
public void commitCurrentComposingBuffer() {
commitText(getCompositeString());
}
public boolean onKeyEvent(int keyCode, int[] keyCodes) {
return handleNoSeeingInput(keyCode, keyCodes);
}
private boolean handleNoSeeingInput(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)
{
// Noseeing users tend to use SPACE to select first candidate
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(Character.toUpperCase(inputBufferRaw.charAt(i)));
}
return str.toString();
}
private void updateCandidates() {
if (inputBufferRaw.length() == 0)
{
_core.hideCandidatesView();
return;
}
if (db == null)
return;
try
{
//Cursor currentQuery = db.rawQuery("Select val from noseeing where key glob '" + inputBufferRaw.toString() + "*'", null);
Cursor currentQuery = db.rawQuery("Select val from noseeing 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
{
}
}
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;
}
}