
/////////////////////////////////////////////////////////
/// Ajax による処理 ///////////////////////////////////////

function gotArchive(answer){
    //alert("gotArchive->"+answer); //##
    
    var obj = decodeObject(answer);// NOA 型式の文字列をオブジェクトに展開
    setMenuObjects(obj);
    showRecords();
}
function getArchive(path){
	// 選択されたユーザのバックアップ・データをサーバへリクエスト
    var args = new Object();
    args['owner'] = document.getElementById("userPopup").value;
    args['tableType'] = "MENU";
    args['filename'] = path;
    
    _callServer("GET_ARCHIVE", "sysServer.php", args, gotArchive);
}

function putArchiveDone(answer){
    alert(answer); // 成功メッセージ
}
function putArchive(filename){
	// データ・ソースを文字列ファイルとして保存
    var recs = menuRecords();
    if (! recs){
        alert("データ・ソースが読み込まれていません");
        return;
    }
    
    var array = new Array();
    for (i in recs){
        var ary = recs[i];
        // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
        var obj = new Object();
        obj.owner = ary[0];
        obj.tag = ary[1];
        obj.menu = ary[2];
        obj.value = ary[3];
        obj.public = ary[4];
        obj.freq = ary[5];
        array.push(obj);
    }
    
    var args = new Object();
    args.owner = document.getElementById("userPopup2").value;
    args.folder = "MENU_SOURCE";
    args.filename = filename; // ここではタイムスタンプの後につける識別名
    args.value = encodeObject(array);
    
    _postServer("PUT_ARCHIVE_FILE", "postServer.php", args, putArchiveDone);
}

function gotTable(answer){
    //alert("gotTable->"+answer); //##
    var obj = eval('(' + answer + ')');
    obj = pureRecords(obj); // $row の数値添字を取り除く
    // alert("gotTable:"+encodeObject(obj)); //##
    setMenuObjects(obj);
    showRecords();
    showMessageBar("");
	
	function pureRecords(objects){
		// $row の数値添字を取り除く
		var recs = new Array();
		for (var i=0,ct=objects.length; i < ct; i++){
			var obj = objects[i];
			var array = new Array();
			for (key in obj){
				if (! isDigit(key)) array[key] = obj[key];
			}
			recs.push(array);
		}
		return recs;
	}
}
function getTable(owner, table, order){
	// table の内容をサーバへリクエスト
    var args = new Object();
    args['owner'] = owner;
    args['table'] = table;
    args['order'] = order;
    
    _callServer("GET_TABLE_SOURCE", "sysServer.php", args, gotTable);
}

function loadedBackupedArchive(answer){
    //alert("loadedBackupedArchive->"+answer); //##
    
    var obj = JSON.parse(answer);
    // バックアップファイルのポップアップを表示
    showBackupSelector(obj);
}
function loadBackupedArchive(){
    // バックアップ・ファイル名リストをリクエスト
    var args = new Object();
    args['owner'] = document.getElementById("userPopup").value;
    args['folder'] = "MENU_SOURCE";
    
    _callServer("GET_ARCHIVED_LIST", "sysServer.php", args, loadedBackupedArchive);
}

function mergedWithMenu(answer){
	// 各テーブルの存在がチェックされた
    //alert("loadedBackupedArchive->"+answer); //##
    if (answer && (answer.length > 0)){
        //### メニュー項目１つずつの返事が返ってくるのでかなり頻繁
//        showMessage("_message", answer);
        elmFor("messageArea").innerHTML = answer;
    } 
    mergeCycle();
}
function mergeWithMenu(obj){
	// データ・ソースを DB とマージ
    obj.owner = document.getElementById("userPopup2").value;
    
    _callServer("MERGE_MENU", "sysServer.php", obj, mergedWithMenu);
}

function replacedMenuTable(answer){
	// DB の MenuTable が空になった
    console.log("replacedMenuTable", answer); //##
    if (answer && (answer.length > 0)){
        mergeCycle();
    } 
}
function replaceMenuTable(){
	// DB の MenuTable を空にしてからデータソースを書込む
    var args = new Object();
    args['owner'] = document.getElementById("userPopup2").value;
    args['table'] = "MenuTable";
    
    _callServer("CLEAR_TABLE", "sysServer.php", args, replacedMenuTable);
}

/// Ajax による処理 ///////////////////////////////////////
/////////////////////////////////////////////////////////

var _menuRecords;
function setMenuObjects(objct){
    // レコード数が１００を超えるほどになると処理がコケるので
    // なるべく軽くするためオブジェクト形式を配列形式に変換
    _menuRecords = new Array();
    //    alert("setMenuObjects->"+encodeObject(objct)); //##
    for (num in objct){
        var items = new Array();
        var obj = objct[num];
        // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
        items.push(obj.owner);
        items.push(obj.tag);
        items.push(obj.menu);
        items.push(obj.value);
        items.push(obj.public);
        items.push(obj.freq);
        _menuRecords.push(items);
    }
}
function setMenuRecords(array){
    _menuRecords = array;
}
function menuRecords(){
	return _menuRecords;
}

function load(){
	// ユーザポップアップとソースポップアップに応じたデータを読込む
    var logname = document.getElementById("userPopup").value;
	var src = document.getElementById("sourcePopup").value;
    
    if (src == "テンプレート"){
        // バックアップデータを表示
        var filename = "./MENU.txt";
        showController("テンプレート ( " + filename + " ) ");
        
        getArchive(filename);
    } else if (src == "バックアップ"){
        // 過去ログからピックアップ
        var filename = document.getElementById("filePop").value;
        showController(logname + " 用バックアップ ( " + filename + " ) ");
        
        getArchive(filename);
    } else if (src == "データベース"){
        showController(logname + " 用データベース ");
        
		var tableName = "MenuTable";
		var order = "`tag`,`menu`";
        getTable(logname, tableName, order);
    }
}

var _num;
function mergeCycle(){
	// Ajax で DB との間でリカーシブルに merge を行う
	var array = menuRecords();
    
    // どういう訳か array.length が undefined になるので、以下の方法で array の数を取得
    // ### menuTable.js では array.length が認識されているが念のため
    var count = 0;
    for (num in array) count++;
    
	if (_num < count){
        // if (_num < array.length){
		var ary = array[_num++];
        // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
        var obj = new Object();
        obj.owner = ary[0];
        obj.tag = ary[1];
        obj.menu = ary[2];
        obj.value = ary[3];
        obj.public = ary[4];
        obj.freq = ary[5];
        mergeWithMenu(obj);
	} else {
        hideMessage("_message");
        
        // DB 内容を再表示
        var logname = document.getElementById("userPopup").value;
		var tableName = "MenuTable";
		var order = "`tag`,`menu`";
        getTable(logname, tableName, order);
        
        elmFor("messageArea").innerHTML = "";
		alert("データへの書込み終了しました");
    }
}
function save(){
	// ユーザポップアップとソースポップアップに応じたデータを書込む
	var src = document.getElementById("sourcePopup2").value;
	if (src == "バックアップ"){
		putArchive("MENU");
	} else if (src == "テンプレート"){
		putArchive("./MENU.txt");
	} else if (src == "データベース"){
		var elm = document.getElementById("isOverWrite");
        var st = (elm.checked)
        ? "ここに表示されたデータによって完全に置換されます"
        : "ここに表示されたデータとマージされます。すでに同じ tag, menu を持つレコードは置換されません。差分のみが追加されます。";
		
		if (confirm("データベースは、" + st)){
			// データ・ソースを DB とマージ
			//showMergeLog(); // マージのログを表示するエリアを用意
			_num = 0; // _num を 0 にセットしてから mergeCycle() を廻す
			if (elm && elm.checked)
				replaceMenuTable(); //## GROUP では実施しないこと ##
			else
				mergeCycle();
		}
	}
}

function find(){
	// 検索を実行
	var key = document.getElementById("keyF").value;
	var count = 0;
	var array = menuRecords();
    for (i in array){
		var obj = array[i];
		var tr = document.getElementById("row"+i);
		var found = false;
		if (key.length){
            // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
			var st = obj[1] + obj[2];
			if (st.indexOf(key) >= 0) found = true;
		}
		
		if (found){ // key が含まれていた行の色を変える
			tr.style.backgroundColor = "#ff0";
			count++;
		} else
			tr.style.backgroundColor = "#fff";
	}
	
	if (count){
		alert(count + " 個の該当レコードを見つけました。黄色い行が該当レコードです。スクロールしてみてください");
	} else if (key.length > 0){
		alert(key + " を含むレコードは見つかりませんでした");
    }
}

function removeCheckedRecords(){
	// チェックされたレコードをすべて削除
	var array = new Array();
	var recs = menuRecords();
    for (i in recs){
		var elm = document.getElementById("cb."+i);
		if (! elm.checked)
			array.push(recs[i]); // チェックの入らないものだけをピックアップ
	}
	setMenuRecords(array);
    showRecords();
}

function removeRecord(row){
	// row 行レコードを削除
	var array = menuRecords();
	var obj = array[row];
	if (confirm(obj[2] + " を削除していいですか")){
		array.splice(row, 1);
		
		setEditorId("");
        showRecords();
        /*		var elm = document.getElementById("directEdit");
         if (elm && elm.checked){
         // 直接データベースの obj を削除
         removeMenuTable(obj);
         } else
         showRecords();
         */
    }
}

function changeRecord(row){
    // row 行レコードを変更
    // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
    var array = new Array();
    array[1] = document.getElementById("tag").value;
    array[2] = document.getElementById("menu").value;
    array[3] = document.getElementById("value").value;
    array[4] = document.getElementById("public").value;
    array[5] = document.getElementById("freq").value;
    
    // 新規レコードの場合もあるので obj は新たに起こしたものを使う
    menuRecords()[row] = array;
    
    setEditorId("");
    showRecords();
}

function showNewEditor(){
    // 新規レコード作成エディターを開く
    // ## 新規レコードボタンに showEditor(row) を action として設定しても
    // ## その時点では row が決まっていない可能性があるため、この機能を独立させる
    var row = menuRecords().length;
    openEditor(row);
}

function openEditor(row){
    // row 行レコードの編集パネルを開く
    var obj = menuRecords()[row];
    if (!obj){
        obj = new Array();
        // 0:owner 1:tag 2:menu 3:value 4:public 5:freq
        obj.push("");
        obj.push("新規レコード"); // 1:tag
        obj.push("");
        obj.push("");
        obj.push("");
        obj.push("");
        // obj は「変更」ボタンが押されてから menuRecords に追加される
    }
    //alert("openEditor->"+encodeObject(obj)); //##
    
    // 以前開いていたエディターあれば閉じる
    var old_eid = editorId();
    var isClosed = closeEditor();
    
    // 目的エディターが今閉じたエディターなら、閉じただけで終了
    var eid = editorIdForRow(row);
    
    if (isClosed && (eid == old_eid)) return;
    
    // エディターを開く領域を記憶
    setEditorId(eid);
    
    // レコード編集ペーンを表示
    var elm = document.getElementById(eid);
    elm.innerHTML = "";
    
    // Editor が見えないことがあるので該当位置へスクロールしておく
    var pos = getPosition(elm);
    window.scroll(0, pos.y - 30);
    
    var div = newDIV(elm, "");
    div.style.padding = "10px 10px";
    div.style.border = "thin solid #aaa";
    div.style.backgroundColor = "#ffc";
    div.style.marginBottom = "10px";
    var tbl = newTABLE(div, "subTable");
    tbl.style.textAlign = "left";
    tbl.style.fontSize = "10pt";
    
    // title
    var tr = newTR(tbl, "editor_title", "");
    var td = newTD(tr, "", "");
    td.setAttribute("colspan", "4");
    var img = newIMAGE(td, "icon", "./close.png", "close");
    img.setAttribute("onclick", "closeEditor()");
    var tx = newTEXT(td, "　" + obj[1] + " を編集"); // tag
    
    // contents
    makeField(tbl, "tag", obj[1], true);
    makeField(tbl, "menu", obj[2], true);
    makeField(tbl, "value", obj[3], true);
    makeField(tbl, "public", obj[4], true);
    makeField(tbl, "freq", obj[5], true);
    makeField(tbl, "owner", obj[0], false);
    
    // comment
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, "", "");
    var td = newTD(tr, "comment", "編集内容はバックアップやデータベースに書込まない限り保存されません ");
    td.setAttribute("colspan", "2");
    td.style.color = "#a63"; // brown
    
    // footer
    var tr = newTR(tbl, "editor_title", "");
    var td = newTD(tr, "controller", "");
    td.setAttribute("colspan", "5");
    td.style.textAlign = "right";
    var dataSource = document.getElementById("sourcePopup").value;
    var bt = newBUTTON(td, "", "削除");
    var action = "removeRecord('" + row + "')";
    bt.setAttribute("onclick", action);
    var bt = newBUTTON(td, "", "変更");
    var action = "changeRecord('" + row + "')";
    bt.setAttribute("onclick", action);
    
    function makeField(tbl, key, value, status){
        var tr = newTR(tbl, "", "");
        var td = newTD(tr, "", key);
        td.style.paddingRight = "10px";
        if (status){
            var td = newTD(tr, "", "");
            var val = (value) ? value : "";
            var fd = newFIELD(td, key, "", "100", val);
        } else {
            var td = newTD(tr, "", value);
        }
    }
}

function checkAll(elm){
    // checkBox の全てにチェックを入れる
    var status = elm.checked;
    var recs = menuRecords();
    for (i in recs){
        var elm = document.getElementById("checkArea."+i);
        elm.innerHTML = "";
        var cb = newCHECKBOX(elm, "cb."+i, "", status);
    }
}

function showRecords(){
    // レコードを表示する
    var elm = document.getElementById("resultArea");
    elm.innerHTML = "";
    var tbl = newTABLE(elm, "base-table");
    
    // title
    var tr = newTR(tbl, "title-bar", "");
    tr.style.fontSize = "11pt";
    var td = newTD(tr, "label-center", "");
    td.style.width = "10 px";
    var cb = newCHECKBOX(td, "", "", false);
    cb.setAttribute("onclick", "checkAll(this)");
    var td = newTD(tr, "label-left", "tag");
    var td = newTD(tr, "label-left", "menu");
    var td = newTD(tr, "label-left", "public");
    var td = newTD(tr, "label-left", "freq");
    
    var array = menuRecords();
    for (num in array){
        // if (num > 100) break;
        var ary = array[num];
        var tr = newTR(tbl, "row"+num, "");
        tr.style.fontSize = "10pt";
        
        // check box
        var td = newTD(tr, "checkArea."+num, "");
        td.style.width = "10 px";
        var cb = newCHECKBOX(td, "cb."+num, "", false);
        
        var td = newTD(tr, "", "");
        var sp = newSPAN(td, "/alias-value");
        sp.innerHTML = ary[1]; // tag
        sp.setAttribute("onclick", "openEditor('"+num+"')");
        
        var td = newTD(tr, "", ary[2]); // menu
        var td = newTD(tr, "", ary[4]); // public
        var td = newTD(tr, "", ary[5]); // freq
        
        // 編集エリアを生成しておく
        var eid = editorIdForRow(num);
        var tr = newTR(tbl, "", "");
        var td = newTD(tr, eid, "");
        td.setAttribute("colspan", "6");
        
    }
    
    // 編集エリアを生成しておく
    var eid = editorIdForRow(array.length);
    var tr = newTR(tbl, "", "");
    var td = newTD(tr, eid, "");
    td.setAttribute("colspan", "9");
    
    // save ボタンを表示
    showSaveButtons();
}

function showBackupSelector(filenames){
    // バックアップ・ファイルのリストを選択してファイルをロード
    var items = new Array();
    for (num in filenames){
        var name = filenames[num];
        if (name.charAt(0) == '.') continue;
        items.push(name);
    }
    var elm = document.getElementById("fileNamesArea");
    elm.innerHTML = "";
    var pu = newPopupMenu(elm, "filePop", items, "");
    
    // removeButtonArea の操作：バックアップファイルの削除ボタン
    var elm = document.getElementById("removeButtonArea");
    elm.innerHTML = " ";
    var bt = newBUTTON(elm, "", "サーバから削除");
    bt.setAttribute("onclick", "removeBackupFile('MENU')");
}

function initMenuTable(){
    var elm = document.getElementById("base");
    elm.innerHTML = "";
    
    // HEADER =====================================
    var div = newDIV(elm, "/yellow-header");
    var dv = newDIV(div, "/left-side");
    dv.setAttribute("onclick", "suser()");
    var sp = newSPAN(dv, "markArea");
    var tx = newTEXT(dv, "MenuTable 編集");
    var dv = newDIV(div, "/right-side");
    var im = newIMAGE(dv, "", "./Help.png", "?");
    im.setAttribute("onclick", "tableHelp()");
    im.style.height = "21px";
    
    // ロード・エリア ===============================
    var div = newDIV(elm, "loadButtonArea");
    div.style.paddingLeft = "10px";
    var sp = newSPAN(div, "userListArea"); // ユーザリストを表示
    var tx = newTEXT(div, " の ");
    var sp = newSPAN(div, "sourceListArea"); // データソースを表示
    var sp = newSPAN(div, "fileNamesArea"); // テンプレートのリストを表示
    var tx = newTEXT(div, " を ");
    var bt = newBUTTON(div, "", "読込む");
    bt.setAttribute("onclick", "load()");
    var sp = newSPAN(div, "removeButtonArea"); // テンプレートのリスト削除ボタン
    
    // セーブ・エリア ===============================
    var div = newDIV(elm, "saveButtonArea");
    div.style.paddingLeft = "10px";
    
    // メッセージ表示エリア
    var div = newDIV(elm, "messageArea");
    div.style.fontsize = "9pt";
    div.style.color = "#f00";
    
    // データ表示エリア
    var div = newDIV(elm, "controlArea");
    
    // FOOTER ======================================
    var div = newDIV(elm, "/yellow-footer");
    var dv = newDIV(div, "/left-side");
    dv.innerHTML = version();
    
    // ユーザ・ポップアップを読込む
    selectUserAndLoadStructure();
}

function version(){
    return "Ver.140627";
}
