
var _records;
function setFieldRecords(objct){
    _records = objct;
}
function fieldRecords(){
	return _records;
}

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

function gotTable(answer){
    //alert("gotTable->"+answer); //##
    var obj = JSON.parse(answer);
    obj = pureRecords(obj); // $row の数値添字を取り除く
    //if (debugMode()) alert("gotTable:"+encodeObject(obj)); //##
    setFieldRecords(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 gotArchive(answer){
    //alert("gotArchive->"+answer); //##
    var obj = decodeObject(answer);// NOA 型式の文字列をオブジェクトに展開
    setFieldRecords(obj);
    showRecords();
	
	function decodeEncodedCR(array){
		// obj 中の encode された改行を decode する
		for (var i=0,ct=array.length; i < ct; i++){
			var newObj = new Object();
			var obj = array[i];
			for (key in obj){
				var val = obj[key];
				newObj[key] = transferToCR(val);
			}
			array[i] = newObj;
		}
		return array;
	}
}
function getArchive(path){
	// 選択されたユーザのバックアップ・データをサーバへリクエスト
    var args = new Object();
    args['owner'] = document.getElementById("userPopup").value;
    args['tableType'] = "FIELD";
    args['filename'] = path;
    
    _callServer("GET_ARCHIVE", "sysServer.php", args, gotArchive);
}

function put_Archive_Done(answer){
    alert(answer); // 成功メッセージ
}
function putArchive(filename){
	// データ・ソースを文字列ファイルとして保存
    var recs = fieldRecords();
    if (! recs){
        alert("データ・ソースが読み込まれていません");
        return;
    }
    
    var array = new Array();
    for (i in recs){
        var obj = recs[i];
        array.push(obj);
    }
    var args = new Object();
    args["owner"] = document.getElementById("userPopup2").value;
    args["folder"] = "FIELD_SOURCE";
    args["value"] = encodeObject(array); // NOA 型式の文字列にする

    _postServer("PUT_ARCHIVE_FILE", "postServer.php", args, put_Archive_Done);
}

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

function mergedWithField(answer){
	// 各テーブルの存在がチェックされた
    //alert("mergedWithField ===\n"+answer);//##
    if (answer && (answer.length > 0)){
        //showMessage("_message", answer);
        elmFor("messageArea").innerHTML = answer;
    }

    mergeCycle();
}
function mergeWithField(obj){
	// データ・ソースを DB とマージ
    obj['owner'] = document.getElementById("userPopup2").value;
    
    _callServer("MERGE_FIELD", "sysServer.php", obj, mergedWithField);
}

var _num;
function mergeCycle(){
	// Ajax で DB との間でリカーシブルに merge を行う
	var array = fieldRecords();
    
    // どういう訳か array.length が undefined になるので、以下の方法で array の数を取得
    var count = 0;
    for (num in array) count++;
    
	if (_num < count){
        // if (_num < array.length){
		var obj = array[_num++];
        mergeWithField(obj);
	} else {
        hideMessage("_message");
        
        // DB 内容を再表示
        var logname = document.getElementById("userPopup").value;
		var tableName = "FieldTable";
		var order = "`tag`,`label`";
        getTable(logname, tableName, order);
        
        elmFor("messageArea").innerHTML = "";
		alert("データへの書込み終了しました");
    }
}
function save(){
	// ユーザポップアップとソースポップアップに応じたデータを書込む
	var src = document.getElementById("sourcePopup2").value;
	if (src == "バックアップ"){
		putArchive("FIELD");
	} else if (src == "テンプレート"){
		putArchive("./FIELD.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)
				replaceFieldTable();
			else
				mergeCycle();
		}
	}
}

function replacedFieldTable(answer){
	// DB の FieldTable が空になった
    //alert("replacedFieldTable ===\n"+answer);//##
    mergeCycle();
}
function replaceFieldTable(){
	// DB の FieldTable を空にしてからデータソースを書込む
    var args = new Object();
    args["owner"] = document.getElementById("userPopup2").value;
    args["table"] = "FieldTable";
    
    _callServer("CLEAR_TABLE", "sysServer.php", args, replacedFieldTable);
}

/*
function removedFieldTable(answer){
    alert("removedFieldTable ===\n"+answer);//##
    showRecords();
}
function removeFieldTable(obj){
	// obj を PriceList から削除
    var args = new Object();
    args['tag'] = obj.tag;
    args['id'] = obj.id;
    args['owner'] = obj.owner;
    
    alert("REMOVE_FIELD"); 
    
    _callServer("REMOVE_FIELD", "sysServer.php", args, removedFieldTable);
}

function puttedFieldTable(answer){
    // DB 内容を再表示
    alert("puttedFieldTable:\n"+answer);//##
    
    var logname = document.getElementById("userPopup").value;
    var tableName = "FieldTable";
    var order = "`tag`,`label`";
    getTable(logname, tableName, order);
}
function putFieldTable(obj){
	// obj を FieldTable に追加
	// FieldTable に同じ tag, id があれば上書き
    var args = new Object();
    obj.owner = document.getElementById("userPopup").value;
    args['owner'] = obj.owner;
    args['value'] = encodeObject(obj);
    
    alert("PUT_FIELD"); 
    
    _callServer("PUT_FIELD", "sysServer.php", args, puttedFieldTable);
}
 */

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



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('FIELD')");
}

function load(){
	// ユーザポップアップとソースポップアップに応じたデータを読込む
    var logname = document.getElementById("userPopup").value;
	var src = document.getElementById("sourcePopup").value;
    
    if (src == "テンプレート"){
        // バックアップデータを表示
        var filename = "./FIELD.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 = "FieldTable";
		var order = "`tag`,`label`";
        getTable(logname, tableName, order);
    }
}

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

function removeRecord(row){
	// row 行レコードを削除
	var array = fieldRecords();
	var obj = array[row];
	if (confirm(obj.tag + " を削除していいですか")){
		// array.splice(row, 1) ではどういう訳かエラーになるので以下を実行
        var newArray = new Array();
        for (num in array){
            if (num != row) newArray.push(array[num]);
        }
        setFieldRecords(newArray);
		
		setEditorId("");
        showRecords();
	}
}

function changeRecord(row){
	// row 行レコードを変更
	var obj = new Object();
	obj.tag = document.getElementById("tag").value;
	obj.buttonType = document.getElementById("buttonType").value;
	obj.menuType = document.getElementById("menuType").value;
	obj.menuAction = document.getElementById("menuAction").value;
	obj.hitAndRun = document.getElementById("hitAndRun").value;
	obj.fieldType = document.getElementById("fieldType").value;
	obj.direction = document.getElementById("direction").value;
	obj.disabled = document.getElementById("disabled").value;
	obj.editor = document.getElementById("editor").value;
	obj.id = document.getElementById("id").value;
	obj.script = document.getElementById("script").value;
	obj.bgcolor = document.getElementById("bgcolor").value;
	obj.label = document.getElementById("label").value;
	obj.numbering = document.getElementById("numbering").value;
	obj.study = document.getElementById("study").value;
	obj.fontSize = document.getElementById("fontSize").value;
	obj.fontFamily = document.getElementById("fontFamily").value;
	obj.color = document.getElementById("color").value;
    
    // 新規レコードの場合もあるので obj は新たに起こしたものを使う
    fieldRecords()[row] = obj;
	
	setEditorId("");
    showRecords();
}

function setSubFieldValue(tag, key){
    // ポップアップメニュー値の変更をフィールドへ反映
    var item = document.getElementById(tag).value;
    if (key == "buttonType")
        var array = buttonTypes(); // lib.js
    else if (key == "menuType")
        var array = menuTypes(); // lib.js
    else if (key == "menuAction")
        var array = menuPositions(); // lib.js
    else if (key == "fieldType")
        var array = fieldTypes(); // lib.js
    else
        return;
    
    var index = indexOfArray(array, item);
    document.getElementById(key).value = index;
}
function setSubFieldStatus(tag, key){
    // チェックボックスの状態をフィールドへ反映
    var status = (document.getElementById(tag).checked) ? 1 : 0;
    document.getElementById(key).value = status;
}

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

function openEditor(row){
	// row 行レコードの編集パネルを開く
	var obj = fieldRecords()[row];
    //alert("openEditor:"+row+"->"+obj); //##
	if (!obj){
        obj = new Object();
        obj.tag = "新規レコード";
        // obj は「変更」ボタンが押されてから fieldRecords に追加される
	}
    //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.tag + " を編集"); // tag
    
	// contents
	makeField(tbl, "label", obj, true);
	makeField(tbl, "tag", obj, true);
	makeField(tbl, "buttonType", obj, true);
	makeField(tbl, "menuType", obj, true);
	makeField(tbl, "menuAction", obj, true);
	makeField(tbl, "hitAndRun", obj, true);
	makeField(tbl, "fieldType", obj, true);
	makeField(tbl, "direction", obj, true);
	makeField(tbl, "disabled", obj, true);
	makeField(tbl, "editor", obj, true);
	makeField(tbl, "id", obj, true);
	makeField(tbl, "script", obj, true);
	makeField(tbl, "bgcolor", obj, true);
	makeField(tbl, "numbering", obj, true);
	makeField(tbl, "study", obj, true);
	makeField(tbl, "fontSize", obj, true);
	makeField(tbl, "fontFamily", obj, true);
	makeField(tbl, "color", obj, true);
	makeField(tbl, "owner", obj, false);
	makeField(tbl, "updateTime", obj, 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, obj, status){
		var tr = newTR(tbl, "", "");
        var td = newTD(tr, "", key);
        var val = (obj[key]) ? obj[key] : "";
		if (status){
            var td = newTD(tr, "", "");
            if (key == "buttonType"){
                var array = buttonTypes(); // lib.js
                var selectedItem = array[val * 1];
                var pu = newPopupMenu(td, "buttonTypeMenu", array, selectedItem);
                var action = "setSubFieldValue('buttonTypeMenu','" +  key + "')";
                pu.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "true");
            } else if (key == "menuType"){
                var array = menuTypes(); // lib.js
                var selectedItem = array[val * 1];
                var pu = newPopupMenu(td, "menuTypeMenu", array, selectedItem);
                var action = "setSubFieldValue('menuTypeMenu','" +  key + "')";
                pu.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "true");
            } else if (key == "menuAction"){
                var array = menuActions(); // lib.js
                var selectedItem = array[val * 1];
                var pu = newPopupMenu(td, "menuAtionMenu", array, selectedItem);
                var action = "setSubFieldValue('menuAtionMenu','" +  key + "')";
                pu.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "disabled");
            } else if (key == "hitAndRun"){
                var array = [0, 1];
                var status = (val * 1) ? 1 : 0;
                var cb = newCHECKBOX(td, "hitAndRunMenu", "", status);
                var action = "setSubFieldStatus('hitAndRunMenu','" +  key + "')";
                cb.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "disabled");
            } else if (key == "fieldType"){
                var array = fieldTypes(); // lib.js
                var selectedItem = array[val * 1];
                var pu = newPopupMenu(td, "fieldTypeMenu", array, selectedItem);
                var action = "setSubFieldValue('fieldTypeMenu','" +  key + "')";
                pu.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "disabled");
            } else if (key == "disabled"){
                var array = [0, 1];
                var status = (val * 1) ? 1 : 0;
                var cb = newCHECKBOX(td, "disabledMenu", "", status);
                var action = "setSubFieldStatus('disabledMenu','" +  key + "')";
                cb.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "disabled");
            } else if (key == "study"){
                var array = [0, 1];
                var status = (val * 1) ? 1 : 0;
                var cb = newCHECKBOX(td, "studyMenu", "", status);
                var action = "setSubFieldStatus('studyMenu','" +  key + "')";
                cb.setAttribute("onchange", action);
                var fd = newFIELD(td, key, "", "1", val);
                fd.setAttribute("disabled", "disabled");
            } else {
                var fd = newFIELD(td, key, "", "100", val);
            }
		} else {
			var td = newTD(tr, "", obj[key]);
		}
	}
}

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

function find(){
	// 検索を実行
	var key = document.getElementById("keyF").value;
	var array = fieldRecords();
	var count = 0;
    for (i in array){
		var tr = document.getElementById("row"+i);
		var obj = array[i];
		var found = false;
		if (key.length){
			var st = obj.tag + obj.label + obj.script;
			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 showRecords(){
	// レコードを表示する
	var elm = document.getElementById("resultArea");
	elm.innerHTML = "";
	var tbl = newTABLE(elm, "base-table");
	
	// title
	var tr = newTR(tbl, "title-bar", "");
	var td = newTD(tr, "", "");
	td.style.width = "10 px";
	var cb = newCHECKBOX(td, "", "", false);
	cb.setAttribute("onclick", "checkAll(this)");
	var td = newTD(tr, "", "id");
	var td = newTD(tr, "", "tag");
	var td = newTD(tr, "", "label");
	var td = newTD(tr, "", "script");
	var td = newTD(tr, "", "updateTime");
	
	// records
	array = fieldRecords();
    for (i in array){
		var obj = array[i];
		var tr = newTR(tbl, "row"+i, "");
        tr.style.fontSize = "10pt";
		
		// check box
		var td = newTD(tr, "checkArea."+i, "");
		td.style.width = "10 px";
		var cb = newCHECKBOX(td, "cb."+i, "", false);
		
		var td = newTD(tr, "", obj.id);

        var td = newTD(tr, "", "");
        var sp = newSPAN(td, "/alias-value");
        sp.innerHTML = obj.tag; 
		sp.setAttribute("onclick", "openEditor('"+i+"')");

		var td = newTD(tr, "", obj.label);
		var script = (obj.script) ? obj.script.substr(0,10)+"..." : "";
		var td = newTD(tr, "", script);
		//var td = newTD(tr, "", obj.menuType);
		//var td = newTD(tr, "", obj.menuAction);
		//var td = newTD(tr, "", obj.fieldType);
		var updateTime = (obj.updateTime) ? obj.updateTime : "";
		//	? obj.updateTime.substr(0,10)+"..." : "";
		var td = newTD(tr, "", updateTime);
		
		// 編集エリアを生成しておく
		var eid = editorIdForRow(i);
		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", "6");
	
	// save ボタンを表示
	showSaveButtons();
}

function initFieldTable(){
	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, "FieldTable 編集");
    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";
}
