package com.classicube;
import android.text.Editable;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;

public class CCView extends SurfaceView {
    SpannableStringBuilder kbText;
    MainActivity activity;

    public CCView(MainActivity activity) {
        // setFocusable, setFocusableInTouchMode - API level 1
        super(activity);
        this.activity = activity;
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return activity.handleTouchEvent(ev) || super.dispatchTouchEvent(ev);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo attrs) {
        // BaseInputConnection, IME_ACTION_GO, IME_FLAG_NO_EXTRACT_UI - API level 3
        attrs.actionLabel = null;
        attrs.inputType   = MainActivity.calcKeyboardType(activity.keyboardType);
        attrs.imeOptions  = MainActivity.calcKeyboardOptions(activity.keyboardType);

        kbText = new SpannableStringBuilder(activity.keyboardText);

        InputConnection ic = new BaseInputConnection(this, true) {
            boolean inited;

            void updateText() {
                activity.pushCmd(MainActivity.CMD_KEY_TEXT, kbText.toString());
            }

            @Override
            public Editable getEditable() {
                if (!inited) {
                    // needed to set selection, otherwise random crashes later with backspacing
                    // set selection to end, so backspacing after opening keyboard with text still works
                    Selection.setSelection(kbText, kbText.toString().length());
                    inited = true;
                }
                return kbText;
            }

            @Override
            public boolean setComposingText(CharSequence text, int newCursorPosition) {
                boolean success = super.setComposingText(text, newCursorPosition);
                updateText();
                return success;
            }

            @Override
            public boolean deleteSurroundingText(int beforeLength, int afterLength) {
                boolean success = super.deleteSurroundingText(beforeLength, afterLength);
                updateText();
                return success;
            }

            @Override
            public boolean commitText(CharSequence text, int newCursorPosition) {
                boolean success = super.commitText(text, newCursorPosition);
                updateText();
                return success;
            }

            @Override
            public boolean sendKeyEvent(KeyEvent ev) {
                // getSelectionStart - API level 1
                if (ev.getAction() != KeyEvent.ACTION_DOWN) return super.sendKeyEvent(ev);
                int code = ev.getKeyCode();
                int uni = ev.getUnicodeChar();

                // start is -1 sometimes, and trying to insert/delete there crashes
                int start = Selection.getSelectionStart(kbText);
                if (start == -1) start = kbText.toString().length();

                if (code == KeyEvent.KEYCODE_ENTER) {
                    // enter maps to \n but that should not be intercepted
                } else if (code == KeyEvent.KEYCODE_DEL) {
                    if (start <= 0) return false;
                    kbText.delete(start - 1, start);
                    updateText();
                    return false;
                } else if (uni != 0) {
                    kbText.insert(start, String.valueOf((char) uni));
                    updateText();
                    return false;
                }
                return super.sendKeyEvent(ev);
            }

        };
        //String text = MainActivity.this.keyboardText;
        //if (text != null) ic.setComposingText(text, 0);
        return ic;
    }
}
