var view_pnl;
var lst_pnl;
var map_pnl;
var btn_pnl;
var grid;
var info;
var cusnm_tf;
var addr_tf;
var editrow;
var editcol;

// 明細のデータ構造定義
var Detail = Ext.data.Record.create([
    {name: 'cusnm' , type: 'string'},
    {name: 'addr'  , type: 'string'},
]);

Ext.onReady(function (){
    Ext.BLANK_IMAGE_URL = 'http://oo-com.com/route/images/default/s.gif';
    Ext.QuickTips.init();

    // 短い別名の定義
    var fm = Ext.form;
    var xg = Ext.grid;
    var sm = new xg.CheckboxSelectionModel();

    // 入力フィールドの作成
    cusnm_tf = new fm.TextField({
        allowBlank: true,
        style: 'ime-mode:active;'
    });
    addr_tf = new fm.TextField({
        allowBlank: false,
        style: 'ime-mode:active;'
    });
    cusnm_tf.addListener('specialkey',function(t,e){
        // 上書きキー以外は通常の処理
        if (   (e.getKey() != e.ENTER)
            && (e.getKey() != e.UP)
            && (e.getKey() != e.DOWN)
            && (e.getKey() != e.LEFT)
            && (e.getKey() != e.RIGHT)
        ){
            return;
        }

        var store = grid.getStore();
        var pos   = getCursorPos(t.getEl());
        switch (e.getKey()){
            // Enterキー押下時の処理
            case e.ENTER:
                grid.startEditing(editrow,2);
                break;
            // ↑キー押下時の処理
            case e.UP:
                if (editrow == 0) return;
                editrow--;
                grid.startEditing(editrow,1);
                break;
            // ↓キー押下時の処理
            case e.DOWN:
                if (editrow == (store.getCount()-1)) return;
                editrow++;
                grid.startEditing(editrow,1);
                break;
            // ←キー押下時の処理
            case e.LEFT:
                if (pos > 0) return;
                if (editrow == 0) return;
                editrow--;
                grid.startEditing(editrow,2);
                break;
            // →キー押下時の処理
            case e.RIGHT:
                if (pos < getTextLength(t)) return;
                grid.startEditing(editrow,2);
                break;
        }

        // デフォルトイベントハンドリング/イベントバブリングの停止
        e.stopEvent();
        // IEの場合のデフォルトイベント停止
        if (Ext.isIE){
            e.browserEvent.keyCode = 0;
            e.browserEvent.returnValue = false;
        }
        return;
    });
    addr_tf.addListener('specialkey',function(t,e){
        // 上書きキー以外は通常の処理
        if (   (e.getKey() != e.ENTER)
            && (e.getKey() != e.UP)
            && (e.getKey() != e.DOWN)
            && (e.getKey() != e.LEFT)
            && (e.getKey() != e.RIGHT)
        ){
            return;
        }

        var store = grid.getStore();
        var pos   = getCursorPos(t.getEl());
        switch (e.getKey()){
            // Enterキー押下時の処理
            case e.ENTER:
                if (editrow < (store.getCount()-1)){
                    editrow++;
                    grid.startEditing(editrow,1);
                } else{
                    grid_addrow();
                    return;
                }
                break;
            // ↑キー押下時の処理
            case e.UP:
                if (editrow == 0) return;
                editrow--;
                grid.startEditing(editrow,2);
                break;
            // ↓キー押下時の処理
            case e.DOWN:
                if (editrow == (store.getCount()-1)) return;
                editrow++;
                grid.startEditing(editrow,2);
                break;
            // ←キー押下時の処理
            case e.LEFT:
                if (pos > 0) return;
                grid.startEditing(editrow,1);
                break;
            // →キー押下時の処理
            case e.RIGHT:
                if (editrow == (store.getCount()-1)) return;
                if (pos < getTextLength(t)) return;
                editrow++;
                grid.startEditing(editrow,1);
                break;
        }

        // デフォルトイベントハンドリング/イベントバブリングの停止
        e.stopEvent();
        // IEの場合のデフォルトイベント停止
        if (Ext.isIE){
            e.browserEvent.keyCode = 0;
            e.browserEvent.returnValue = false;
        }
        return;
    });
    cusnm_tf.addListener('show',function(t){
        t.getEl().addListener('keydown',funcKeyDown);
    });
    cusnm_tf.addListener('hide',function(t){
        t.getEl().removeListener('keydown',funcKeyDown);
    });
    addr_tf.addListener('show',function(t){
        t.getEl().addListener('keydown',funcKeyDown);
    });
    addr_tf.addListener('hide',function(t){
        t.getEl().removeListener('keydown',funcKeyDown);
    });

    // 列モデルの定義
    var cm = new xg.ColumnModel([
        sm,
        {
            header: "得意先名",
            dataIndex: 'cusnm',
            id: 'cusnm',
            width: 90,
            align: 'left',
            editor: cusnm_tf
        },{
            header: "住所",
            dataIndex: 'addr',
            id: 'addr',
            width: 165,
            editor: addr_tf
        }
    ]);

    // デフォルトで各列はソート不可
    cm.defaultSortable = false;

    // データストアの作成
    var store = new Ext.data.Store({
        // HTTPでXMLデータをロード
        url: 'route.xml',
        listeners: {
            'update' : function(a, rec, c) {rec.commit(true);}
        },
        // URLの戻りはXMLを期待。XmlReaderを使用
        reader: new Ext.data.XmlReader(
            {
                // XMLのレコードは "detail" タグを想定
                record: 'detail'
            },
            Detail
        )
    });

    // gridの作成
    grid = new xg.EditorGridPanel({
        store: store,
        cm: cm,
        sm: sm,
        width:  299,
        height: 300,
        frame: false,
        clicksToEdit: 1,
        enableColumnMove: false,
        monitorResize: true,
        stripeRows: true
    });
    grid.addListener('beforeedit',function(e){
        editrow = e.row;
        editcol = e.column;
        var sm = grid.getSelectionModel();
        sm.clearSelections();
    });

    // 広告ウインドウの作成
    info = new Ext.Panel({
        title: 'お知らせ',
        width: 299,
        frame: false,
        contentEl: 'infoarea',
        bodyStyle: 'background-color:#d6eef8;'
    });

    // リストパネルの作成
    lst_pnl = new Ext.Panel({
        title: '目的地入力',
        region: 'west',
        split: true,
        width: 300,
        collapsible: true,
        titleCollapse: true,
        items: [grid,info],
        bodyStyle: 'background-color:#d6eef8;'
    });

    // 地図パネルの作成
    map_pnl = new Ext.Panel({
        region: 'center',
        split: true,
        collapsible: false,
        contentEl: 'maparea'
    });

    // ボトムボタンパネルを作成
    btn_pnl = new Ext.Panel({
        region: 'south',
        collapsible: true,
        split: false,
        border: true,
        header: true,
        height: 80,
        width: 100,
        hideCollapseTool: false,
        contentEl: 'btnarea',
        bodyStyle: 'background-color:#d6eef8;'
    });

    // ビューの作成
    view_pnl = new Ext.Viewport({
        layout: 'border',
        items: [lst_pnl,map_pnl,btn_pnl]
    });
    lst_pnl.addListener('resize',function(t,aw,ah,rw,rh){
        grid.setWidth(aw);
        info.setHeight(ah - grid.getSize().height);
        info.setWidth(aw);
    });
    map_pnl.addListener('resize',function(t,aw,ah,rw,rh){
        resize(aw,ah);
    });
    info.setHeight(lst_pnl.getInnerHeight() - grid.getSize().height);
    if (map){
        map.panTo(map.getCenter());
    }

    // 初期入力枠の作成
    var store = grid.getStore();
    grid.stopEditing();
    for (i=0; i<13; i++){
        var p = new Detail({
            cusnm: '',
            addr: ''
        });
        store.add(p);
    }
    grid.startEditing(0, 1);
});

// ファンクションキー定義
Ext.getDoc().addListener('keydown',funcKeyDown);

// F1によるヘルプ定義
Ext.getBody().addListener('help',function(e){
    e.browserEvent.returnValue = false;
    return false;
});

// リサイズ処理
function resize(nw,nh){
    if (map_pnl){
        if (!nw) nw = map_pnl.getInnerWidth();
        if (!nh) nh = map_pnl.getInnerHeight();
        // mapareaのサイズ設定
        Ext.get('gmapfld').setSize(nw,nh);
    }

    if (map){
        var loc = map.getCenter();
        map.checkResize();
        map.setCenter(loc);
    }
}

function funcKeyDown(e){
    var char = e.getCharCode();

    // イベント発生時にSHIFT/ALT/CTRLが押下されている場合は処理対象外
    if (e.hasModifier()) return true;

    // ファンクションキー(F1～F12)の範囲外は処理対象外
    if (char < 112 || char > 123) return true;

    // デフォルトイベントハンドリング/イベントバブリング停止
    e.stopEvent();
    // IEの場合のデフォルトイベント停止
    if (Ext.isIE){
        e.browserEvent.keyCode = 0;
        e.browserEvent.returnValue = false;
    }

    // ファンクションキーのハンドリング処理を記述
    var funckey = char - 111;
    switch (funckey){
        case 1:
            onF1();
            break;
        case 2:
            onF2();
            break;
        case 3:
            onF3();
            break;
        case 4:
            onF4();
            break;
        case 5:
            onF5();
            break;
        case 6:
            onF6();
            break;
        case 7:
            onF7();
            break;
        case 8:
            onF8();
            break;
        case 9:
            onF9();
            break;
        case 10:
            onF10();
            break;
        case 11:
            onF11();
            break;
        case 12:
            onF12();
            break;
    }

    return false;
}

function onF1(){
    return void(0);
}

function onF2(){
    return void(0);
}

function onF3(){
    return void(0);
}

function onF4(){
    return void(0);
}

function onF5(){
    return void(0);
}

function onF6(){
    return void(0);
}

function onF7(){
    return void(0);
}

function onF8(){
    return void(0);
}

function onF9(){
    return void(0);
}

function onF10(){
    return void(0);
}

function onF11(){
    return void(0);
}

function onF12(){
    return void(0);
}

function grid_addrow(){
    var p = new Detail({
        cusnm: '',
        addr: ''
    });
    var store = grid.getStore();
    grid.stopEditing();
    store.add(p);
    grid.startEditing(store.getCount()-1, 1);
}

function grid_deleterow(){
    var sm = grid.getSelectionModel();
    var store = grid.getStore();
    Ext.Msg.confirm(
        '選択行削除',
        '選択された'+sm.getCount()+'行を削除しますか',
        function(btn) {
            if (btn=='yes') {
                sm.each(function(rec){store.remove(rec);});
            }
        }
    );
}

function grid_copyrow(){
    var sm = grid.getSelectionModel();
    var store = grid.getStore();
    sm.each(function(rec){
        var newrec = new Detail({
            cusnm: rec.get('cusnm'),
            addr: rec.get('addr')
        });
        store.add(newrec);
    });
    sm.clearSelections();
}

function grid_insertrow(){
    var sm = grid.getSelectionModel();
    var store = grid.getStore();
    var selrec = sm.getSelected();
    for (i = 0; i < store.getCount(); i++){
        if (selrec == store.getAt(i)){
            var newrec = new Detail({
                cusnm: '',
                addr: ''
            });
            store.insert(i,newrec);
            break;
        }
    }
    sm.clearSelections();
}

function getCursorPos(elm){
    var pos = 0;
    if (Ext.isIE){
        var d = Ext.getDoc().dom.selection.createRange();
        var r = elm.dom.createTextRange();
        r.setEndPoint('EndToStart', d);
        pos = r.text.length;
    }
    return pos;
}

function getTextLength(obj){
    var t = obj.getValue();
    return t.length;
}
