
// See
// - http://javascriptist.net/docs/pract_keyboard_event.html
//   > クロスブラウザでのJavaScriptキーボードイベントの扱い方 - JavaScriptist
//
// - http://yotsuba-system.com/ponta/archives/50
//   > textareaのカーソル位置にテキストを挿入する | ポンタの技術日記

MYAPP.namespace('MYAPP.katoy.vkey2.keytops');

/**
 * 
 */
MYAPP.katoy.vkey2.keytops = function() {

    // dependencies

    // private properties nad methods
    var Constr,
    keys = [];  // キートップ

    // キーコードと修飾キーの状態から 文字を得る。
    function get_charactor(keycode, shift, capslock, kana) {
        if (keycode === 13) { // return
            return '\n';
        } else if (keycode === 9) {
            return '\t';
        }

        var c = String.fromCharCode(keycode).toLowerCase(),
        ccode = c.charCodeAt(0);

        // See http://e-words.jp/p/r-ascii.html
        if ((ccode < 32) || ((127 < ccode) && (ccode < 255))) {
            c = '';
        } else {
            var mode = 0;
            if (shift && capslock) {
                mode = 0;
            } else if (shift || capslock) {
                mode = 1;
            }

            if (mode === 1) {
                c = c.toUpperCase();
            }
        }
        return c;
    }

    // キートップの表示を切り替える。
    function set_keytops(shift, capslock, kana) {
        var base = 0;

        if (kana) {
            base = 2;
        }

        var mode = 0;
        if (shift) {
            mode += 1;
        }
        if (capslock) {
            mode += 1;
        }
        mode = mode % 2;

        var sh = 0;
        if (shift) {
            sh += 1;
        }

        $('#keyboard li').each(function(index, el) {
            // var p = base + sh;
            // console.log(this.id + ":" + p);
            var c;
            if (keys[this.id]) {
                if (kana) {
                    c = keys[this.id][base + sh];
                } else {
                    c = keys[this.id][base + sh];
                    if ('abcdefghijklmnopqrstuvwxyz'.indexOf(c.toLowerCase()) >= 0) {
                        c = keys[this.id][base + mode];
                    }
                }
                $(this).html(c);
            }
        }
        );
    }

    // 指定位置の後ろに文字列を挿入する。
    function insertTextAtPosision(obj, pos, txt) {
        obj.focus();
        if (jQuery.browser.msie) {
            pos.text = txt;
            pos.select();
        } else {
            var s = obj.value,
            np = pos + txt.length;

            obj.value = s.substr(0, pos) + txt + s.substr(pos);
            obj.setSelectionRange(np, np);
        }
    }
    // 指定位置の前の文字を削除する。
    function deleteTextBeforPosision(obj, pos) {
        if (pos !== 0) {
            obj.focus();
            if (jQuery.browser.msie) {
            // TODO
            } else {
                var s = obj.value,
                np = pos - 1;
                obj.value = s.substr(0, pos - 1) + s.substr(pos);
                obj.setSelectionRange(np, np);
            }
        }
    }
    // 指定位置の文字を削除する。
    function deleteTextAtPosision(obj, pos) {
        obj.focus();
        if (jQuery.browser.msie) {
        // TODO
        } else {
            var s = obj.value;
            if (pos != s.lengrh) {
                obj.value = s.substr(0, pos) + s.substr(pos + 1);
                obj.setSelectionRange(pos, pos);
            }
        }
    }

    // カーソル位置を得る。
    function getCaretPosition(obj) {
        obj.focus();
        var pos;
        if (jQuery.browser.msie) {
            pos = document.selection.createRange();
        } else {
            pos = obj.selectionStart;
        }
        return pos;
    }

    // カーソルを移動する
    function moveCaretPosition(obj, arrow) {
        obj.focus();
        var pos = getCaretPosition(obj);
        if (jQuery.browser.msie) {
        // TODO
        } else {
            var np = pos;
            if (arrow === 0) {
                np -= 1;
            } else if (arrow == 2) {
                np += 1;
            }
            obj.setSelectionRange(np, np);
        }
    }

    // 108 キー
    function init_108() {
        // html でのキーの ID => [ANK-Normal, Ank-Capslock, Kana-Normal, Kana-Capslock]
        keys.key_f01 = ['F1', 'F1', 'F1', 'F1'];
        keys.key_f02 = ['F2', 'F2', 'F2', 'F2'];
        keys.key_f03 = ['F3', 'F3', 'F3', 'F3'];
        keys.key_f04 = ['F4', 'F4', 'F4', 'F4'];
        keys.key_f05 = ['F5', 'F5', 'F5', 'F5'];
        keys.key_f06 = ['F6', 'F6', 'F6', 'F6'];
        keys.key_f07 = ['F7', 'F7', 'F7', 'F7'];
        keys.key_f08 = ['F8', 'F8', 'F8', 'F8'];
        keys.key_f09 = ['F9', 'F9', 'F9', 'F9'];
        keys.key_f10 = ['F10', 'F10', 'F10', 'F10'];
        keys.key_f11 = ['F11', 'F11', 'F11', 'F11'];
        keys.key_f12 = ['F12', 'F12', 'F12', 'F12'];

        keys.key_kanji = ['漢字', '漢字', '漢字', '漢字'];
        keys.key_1 = ['1', '!', 'ぬ', 'ぬ'];
        keys.key_2 = ['2', '"', 'ふ', 'ふ'];
        keys.key_3 = ['3', '#', 'あ', 'ぁ'];
        keys.key_4 = ['4', '$', 'う', 'ぅ'];
        keys.key_5 = ['5', '%', 'え', 'ぇ'];
        keys.key_6 = ['6', '&amp;', 'お', 'ぉ'];
        keys.key_7 = ['7', '&quot;', 'や', 'ゃ'];
        keys.key_8 = ['8', '(', 'ゆ', 'ゅ'];
        keys.key_9 = ['9', ')', 'よ', 'ょ'];
        keys.key_0 = ['0', '~', 'わ', 'を'];
        keys.key_minus = ['=', '-', 'ほ', ''];
        keys.key_hat = ['^', '-', 'へ', '々'];
        keys.key_en = ['¥', '|', 'ー', ''];

        keys.key_q = ['q', 'Q', 'た', 'た'];
        keys.key_w = ['w', 'W', 'て', 'て'];
        keys.key_e = ['e', 'E', 'い', 'ぃ'];
        keys.key_r = ['r', 'R', 'す', 'す'];
        keys.key_t = ['t', 'T', 'か', 'か'];
        keys.key_y = ['y', 'Y', 'ん', 'ん'];
        keys.key_u = ['u', 'U', 'な', 'な'];
        keys.key_i = ['i', 'I', 'に', 'に'];
        keys.key_o = ['o', 'O', 'ら', 'ら'];
        keys.key_p = ['p', 'P', 'せ', ''];
        keys.key_at = ['@', '`', '”', ''];
        keys.key_lblacket = ['[', '{', '○', '「'];

        keys.key_a = ['a', 'A', 'ち', 'ち'];
        keys.key_s = ['s', 'S', 'と', 'と'];
        keys.key_d = ['d', 'D', 'し', 'し'];
        keys.key_f = ['f', 'F', 'は', 'は'];
        keys.key_g = ['g', 'G', 'き', 'き'];
        keys.key_h = ['h', 'H', 'く', 'く'];
        keys.key_j = ['j', 'J', 'ま', 'ま'];
        keys.key_k = ['k', 'K', 'の', 'の'];
        keys.key_l = ['l', 'L', 'り', 'り'];
        keys.key_semic = [';', '+', 'れ', '』'];
        keys.key_colon = [':', '*', 'け', 'ヶ'];
        keys.key_rblacket = [']', '}', 'む', '「'];

        keys.key_z = ['z', 'Z', 'つ', 'っ'];
        keys.key_x = ['x', 'X', 'さ', 'さ'];
        keys.key_c = ['c', 'C', 'そ', 'そ'];
        keys.key_v = ['v', 'V', 'ひ', 'ひ'];
        keys.key_b = ['b', 'B', 'こ', 'こ'];
        keys.key_n = ['n', 'N', 'み', 'み'];
        keys.key_m = ['m', 'M', 'も', 'も'];
        keys.key_colon = [',', '<', 'ね', '、'];
        keys.key_dot = ['.', '>', 'る', '。'];
        keys.key_slash = ['/', '?', 'め', '・'];
        keys.key_bslash = ['\\', '_', 'ろ', '｜'];

    }
    // one-time init procedures
    init_108();

    // public API -- constructor
    Constr = function(obj) {
        this.elements = this.toArray(obj);
    };

    // public API -- prototype
    Constr.prototype = {
        constructor: MYAPP.katoy.vkey2.keytops,
        version: '1.0',
        toArray: function(obj) {
            var a = [];
            if (typeof obj !== 'undefined') {
                for (var i = 0, len = obj.length; i < len; i += 1) {
                    a[i] = obj[i];
                }
            }
            return a;
        },

        get_charactor: get_charactor,
        set_keytops: set_keytops,
        insertTextAtPosision: insertTextAtPosision,
        deleteTextBeforPosision: deleteTextBeforPosision,
        deleteTextAtPosision: deleteTextAtPosision,
        getCaretPosition: getCaretPosition,
        moveCaretPosition: moveCaretPosition
    };
    // return the constroctor
    return Constr;
}();
