import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
/**
 *
 * @author user
 */
public class InputBox {
    
    private boolean isSelect, isLockKeyboard, write, showBlink, addLetter, userNameWrite;
    private int mode, width, height, bIndex, sDistance, bDistance, cLetter, lMode = 1;
    private int[] clip;
    private long time, ptime;
    private char[] lLast;
    private char[][][] letters;
    private String value;
    private StringBuffer buff;
    private DrawText dt;
    
    public static final int STRING = 1;
    public static final int NUMERIC = 2;
    
    /*
     * Конструктор класса, инициализирует и принимает, wSize и hSizе - ширину и высоту экрана, value - строку для отображения и редактирования, режим редактирования (STRING или NUMERIC), и класс DrawText
     */
    public InputBox(int wSize, int hSize, String value, int mode, DrawText dt) {
        this.value = value;
        this.mode = mode;
        this.dt = dt;
        width = wSize;
        height = hSize;
        buff = new StringBuffer(value);
        bIndex = value.length();
        letters = new char[2][][];
        letters[0] = new char[][] {{'A', 'B', 'C'}, {'D', 'E', 'F'}, {'G', 'H', 'I'}, {'J', 'K', 'L'}, {'M', 'N', 'O'}, {'P', 'Q', 'R', 'S'}, {'T', 'U', 'V'}, {'X', 'Y', 'Z'}};
        letters[1] = new char[][] {{'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}, {'j', 'k', 'l'}, {'m', 'n', 'o'}, {'p', 'q', 'r', 's'}, {'t', 'u', 'v'}, {'x', 'y', 'z'}};
        clip = new int[4];
        checkDistance();
    }
    
    /*
     * 
     */
    public void setUserNameWrite(boolean flag) {
        showBlink = write = isLockKeyboard = userNameWrite = flag;
    }
    
    /*
     * Возвращает щирину TextBox'а
     */
    public int getWidth() {
        return width;
    }
    
    /*
     * Возвращает высоту TextBox'а
     */
    public int getHeight() {
        return height;
    }
    
    /*
     * Возвращает строку (Value)
     */
    public String getValue() {
        return value;
    }
    
    /*
     * Устанавливает строку (Value)
     */
    public void setValue(String value) {
        this.value = value;
        buff = new StringBuffer(value);
        bIndex = value.length();
        checkDistance();
    }
    
    /*
     * Приватная функция, добавляет символ в value
     */
    private void addSymbol(char ch) {
        if(!checkMaxLen(ch)) {
            buff.insert(bIndex, ch);
            value = buff.toString();
            moveBlink(2);
        }
    }
    
    /*
     * Приватная функция, изменяет последний символ value
     */
    private void setLastSymbol(char ch) {
        buff.setCharAt(buff.length()-1, ch);
        value = buff.toString();
        checkDistance();
    }
    
    /*
     * Приватная функция, добавляет число к value
     */
    private void addNumber(char ch) {
        if(mode == STRING) {
            setLastSymbol(ch);
            if(addLetter) addLetter = false;
        } else {
            addSymbol(ch);
        }
    }
    
    /*
     * Приватная функция, добавляет символ из ячейки массива letters
     */
    private void addLetter(char[] l) {
        if(l != lLast) {
            lLast = l;
            cLetter = 0;
            addLetter = false;
            ptime = 0;
        } else {
            if(System.currentTimeMillis()-ptime >= 1000) {
                cLetter = 0;
                addLetter = false;
                ptime = 0;
            }
        }
        if(!addLetter && !checkMaxLen(l[0])) ptime = System.currentTimeMillis();
        time = System.currentTimeMillis()-ptime;
        if(time < 1000) {
            if(!addLetter) {
                addSymbol(l[0]);
                addLetter = true;
            } else {
                setLastSymbol(l[cLetter]);
                ptime = System.currentTimeMillis();
            }
            cLetter++;
            if(cLetter == l.length) cLetter = 0;
        }
    }
    
    /*
     * Приватная функция, двигает курсор редактирования
     */
    private void moveBlink(int d) {
        if(d == 1 && bIndex > 0) bIndex--;
        if(d == 2 && bIndex < value.length()) bIndex++;
        checkDistance();
    }
    
    /*
     * Приватная функция, сдвигает строку value по горизонтали (если надо), для правильного отображения
     */
    private void checkDistance() {
        sDistance = width/2-dt.stringWidth(value)/2;
        bDistance = sDistance+dt.stringWidth(value.substring(0, bIndex));
    }
    
    /*
     * Приватная функция, возвращает true - если строка слишком длинная
     */
    private boolean checkMaxLen(int ch) {
        if(dt.stringWidth(value+ch) > width-4) return true;
        return false;
    }
    
    /*
     * Устанавливает выделение TextBox'а
     */
    public void setSelect(boolean flag) {
        isSelect = flag;
    }
    
    /*
     * Возвращает true - если клавиатура используется для ввода/редактирования текста
     */
    public boolean isLockKeyboard() {
        return isLockKeyboard;
    }
    
    /*
     * Цикличная функция, проверяет нажатие кнопок pressed и repeated
     */
    public void check(int pKey, int rpKey) {
        if(!write) {
            if(pKey == Canvas.KEY_NUM5 || pKey == -5 || pKey == 103) {
                showBlink = write = isLockKeyboard = true;
            }
        } else {
            
            if(pKey == -5 || pKey == 10) {
                if(!userNameWrite) showBlink = write = isLockKeyboard = false;
            }
            if(pKey == Canvas.KEY_POUND || pKey == 8) {
                if(bIndex > 0) {
                    buff.deleteCharAt(bIndex-1);
                    value = buff.toString();
                    moveBlink(1);
                }
            }
            
            switch(pKey) {
                case -3:
                    moveBlink(1);
                    break;
                case -4:
                    moveBlink(2);
                    break;
            }
            
            int cCode = (mode == STRING ? rpKey : pKey);
            if(cCode == Canvas.KEY_NUM0 ) addNumber('0');
            if(cCode == Canvas.KEY_NUM1 || cCode == 114) addNumber('1');
            if(cCode == Canvas.KEY_NUM2 || cCode == 116) addNumber('2');
            if(cCode == Canvas.KEY_NUM3 || cCode == 121) addNumber('3');
            if(cCode == Canvas.KEY_NUM4 || cCode == 102) addNumber('4');
            if(cCode == Canvas.KEY_NUM5 || cCode == 103) addNumber('5');
            if(cCode == Canvas.KEY_NUM6 || cCode == 104) addNumber('6');
            if(cCode == Canvas.KEY_NUM7 || cCode == 118) addNumber('7');
            if(cCode == Canvas.KEY_NUM8 || cCode == 98) addNumber('8');
            if(cCode == Canvas.KEY_NUM9 || cCode == 110) addNumber('9');
            
            if(mode == STRING) {
                
                if(pKey == Canvas.KEY_NUM0) addSymbol(' ');
                if(pKey == Canvas.KEY_NUM1 || pKey == 114) addSymbol('.');
                if(pKey == Canvas.KEY_NUM2 || pKey == 116) addLetter(letters[lMode][0]);
                if(pKey == Canvas.KEY_NUM3 || pKey == 121) addLetter(letters[lMode][1]);
                if(pKey == Canvas.KEY_NUM4 || pKey == 102) addLetter(letters[lMode][2]);
                if(pKey == Canvas.KEY_NUM5 || pKey == 103) addLetter(letters[lMode][3]);
                if(pKey == Canvas.KEY_NUM6 || pKey == 104) addLetter(letters[lMode][4]);
                if(pKey == Canvas.KEY_NUM7 || pKey == 118) addLetter(letters[lMode][5]);
                if(pKey == Canvas.KEY_NUM8 || pKey == 98) addLetter(letters[lMode][6]);
                if(pKey == Canvas.KEY_NUM9 || pKey == 110) addLetter(letters[lMode][7]);
                if(pKey == Canvas.KEY_STAR) lMode = (lMode == 0 ? 1 : 0);
                
            }
        }
    }
    
    /*
     * Цикличная функция, принимает класс Graphics и выводит TextBox по координатам x и y
     */
    public void paint(Graphics g, int x, int y) {
        getClip(g);
        g.setClip(x+2, y+2, width-4, height-4);
        if(!userNameWrite) {
            g.setColor(0xffffff);
        } else {
            g.setColor(0xe0e0e0);
        }
        g.drawRect(x+2, y+2, width-5, height-5);
        g.setClip(x+3, y+3, width-7, height-7);
        dt.drawString(g, x+sDistance, y+height/2-14/2, value);
        if(showBlink) g.drawLine(x+bDistance, y+height/2-14/2, x+bDistance, y+height/2+14/2-1);
        if(isSelect) {
            g.setClip(x, y, width, height);
            g.drawRect(x, y, width-1, height-1);
        }
        setClip(g);
    }
    
    /*
     * Приватная функция, заносит в массив текущий сетКлип класса Graphics
     */
    private void getClip(Graphics g) {
        clip[0] = g.getClipX();
        clip[1] = g.getClipY();
        clip[2] = g.getClipWidth();
        clip[3] = g.getClipHeight();
    }
    
    /*
     * Приватная функция, возвращает/устанавливает сетКлип из массива для класса Graphics
     */
    private void setClip(Graphics g) {
        g.setClip(clip[0], clip[1], clip[2], clip[3]);
    }
    
}
