var _disp = new function(){
	var cssNodeDef = {attr:{
		tagname:"link",
		rel:"stylesheet",
		type:"text/css"
	}}

	var id = {
		//エラー時の特殊画面
		FEr:"FEr",
		//管理系
		DBMng:"DBMng",
		TMng:"TMng",
		CMng:"CMng",
		SMng:"SMng",
		RMng:"RMng",
		//操作系
		TLst:"TLst",
		LstV:"LstV",
		DtV:"DtV",

		//サブ画面系
		SrchInf:"SrchInf",
		blkUpd:"blkUpd",
		Info:"Info",
	};

	this.id = id;
	this.mode = {
		view:"view",
		edit:"edit",
		add:"add",
		blk:"blk"
	};
	var getFuncAryForDisp = function( bl ){
		return function( each ){
			_D.show( each , bl );
		};
	};
	var menuBtnCtrl = function( dispId ){
		var aryMngBtns =[
			_D.g("btn_db_mng"),
			_D.g("btn_tbl_mng"),
			_D.g("btn_srt_mng"),
			_D.g("btn_rlt_mng")
		];
		aryMngBtns.forEach( getFuncAryForDisp( dispId != id.DBMng && dispId != id.FEr ) );
		_D.show( _D.g("btn_tbl_list") , dispId != id.DBMng && dispId != id.TLst && dispId != id.FEr );
		_D.show( _D.g("btn_list_view") , ( dispId == id.CMng || dispId == id.DtV ) && dispId != id.FEr  );
	};
	var _ = function(){
		var ary=[
			_D.g("btn_db_mng"),
			_D.g("btn_tbl_mng"),
			_D.g("btn_srt_mng"),
			_D.g("btn_rlt_mng"),
			_D.g("btn_tbl_list"),
			_D.g("btn_list_view"),
		];
		var onclickfunc = function(){
			_disp.dipsCtrl( this.dataset.id );
		};
		_D.g("btn_db_mng").dataset.id = id.DBMng;
		_D.g("btn_tbl_mng").dataset.id = id.TMng;
		_D.g("btn_srt_mng").dataset.id = id.SMng;
		_D.g("btn_rlt_mng").dataset.id = id.RMng;
		_D.g("btn_tbl_list").dataset.id = id.TLst;
		_D.g("btn_list_view").dataset.id = id.LstV;
		ary.forEach(
			function( elm ){
				elm.onclick = onclickfunc;
			}
		);

	}();
	delete _;



	//これらはエラー時の画面遷移で利用する。
	var currentDispObj = null;
	var currentDispId;

	this.dipsCtrl = function( dispId , optionalArgs ){
		currentDispId = dispId;
		//呼ばれたら、ひとまずメインエリアをクリア
		_D.g("main").innerHTML = "";
		//メニューのボタンの表示を切り替える
		menuBtnCtrl( dispId );

		var cssId = "link_css_"+dispId;
		var link = _D.g( cssId );
		if( ! link ){
			link = _D.aCAndCN( document.head , cssNodeDef );
			link.id = cssId;
			link.href = "css/"+ _urlMap.css[ dispId ]+"?now=" + Date.now();
		};

		//idに応じて個別の処理を実行
		for( var key in id ){
			if( id[ key ] == dispId ){
				currentDispObj = _eachDisp[ key ];
				break;
			};
		};
		currentDispObj.setId( this.dbId , this.tblId, this.rowId );
		currentDispObj.init( optionalArgs );

	};
	this.sub = function( id , mode ){
	};

	var nodeDefInfoBtn = {
		attr:{
			tagname : "input",
			type : "button",
			className : "info_btn",
		}
	};
	var addInfoBtn = function( arg ){
		if( arg && arg.str && arg.func ){
			var btn = _D.aCAndCN( _D.g("btn_area") , nodeDefInfoBtn );
			btn.value = arg.str;
			btn.onclick = function(){
				_disp.infoClose();
				arg.func();
			};
		};
	};

	var focusCancel = function(){
		var targ = document.activeElement;
		if( targ && _D.par( targ ) != _D.g("btn_area") ){
			targ.blur();
		};
	};

	//第３引数には、{str:"OK",func:function(){何かの処理}}を配列で設定する。省略時は別途、this.infoCloseを明示的に呼び出すこと。
	//尚、既に表示中の場合は、指定された内容で表示が更新される。
	this.info = function( strMain , strDetail , aryBtnAndFnc ){
		var str ="";
		if( !strMain || strMain.constructor != String ){
			strMain = '';
		};
		var ary = strMain.split( "\r\n" );
		for( var i = 0 ; _U.isIdx( i , ary ) ; i ++ ){
			if( i != 0 ){
				str+="<br />"
			}
			str += _U.htmlEscape( ary[i] );
		};

		_D.g("inf_main").innerHTML = str;
		this.infoDetailChg( strDetail );

		_D.g("btn_area").innerHTML = "";
		if( aryBtnAndFnc && aryBtnAndFnc.constructor == Array ){
			aryBtnAndFnc.forEach( addInfoBtn );
		};
		_D.show( _D.g("sub_dialog") , true );
		_D.show( _D.g("inf_frm") , true );

		if( document.activeElement ){
			document.activeElement.blur(); 
		};

		document.addEventListener("focus", focusCancel, true);
	};

	this.infoDetailChg = function( argStr , add ){
		var str ="";
		if( argStr && argStr.constructor == String ){
			var ary = argStr.split( "\r\n" );
			for( var i = 0 ; _U.isIdx( i , ary ) ; i ++ ){
				if( i != 0 ){
					str+="<br />"
				}
				str += _U.htmlEscape( ary[i] );
			};
		};
		if( add ){
			_D.g("inf_detail").innerHTML +="<br />"+ str;
		}else{
			_D.g("inf_detail").innerHTML = str;
		};
	};
	this.infoClose = function(){
		_D.show( _D.g("sub_dialog") , false );
		_D.show( _D.g("inf_frm") , false );
		document.removeEventListener("focus", focusCancel, true);
	};
	var dbId = null;
	Object.defineProperty( this , "dbId" , {
		get : function(){ return dbId;} ,
		set : function( val ){
			dbId = val;
			//対象テーブル、対象行は初期化する。
			this.tblId = null;
			this.rowId = null;
			this.tblName = null;
			if( val ){
				var dbTable = _sysData._getData("db");
				for( var i = 0 ; _U.isIdx( i , dbTable ) && dbTable[i].id != val ; i++ );
				this.dbName = dbTable[i].name;
			}else{
				this.dbName = null;
			};
			if( currentDispObj ){
				currentDispObj.setId( this.dbId , this.tblId, this.rowId );
			};		}
	});
	var dbName = null;
	Object.defineProperty( this , "dbName" , {
		get : function(){ return dbName;} ,
		set : function( val ){
			dbName = val;
			if( dbName ){
				_D.g("c_db").innerHTML = _U.htmlEscape( dbName );
				_D.show( _D.g("top_c_db") , true );
			}else{
				_D.show( _D.g("top_c_db") , false );
			};
		}
	});

	var tblId = null;
	Object.defineProperty( this , "tblId" , {
		get : function(){ return tblId;} ,
		set : function( val ){
			tblId = val;
			//対象行は初期化する。
			this.rowId = null;
			if( val ){
				var tables = _sysData._getData("tbl");
				for( var i= 0 ; _U.isIdx( i , tables ) ; i ++ ){
					if( tables[i].id == val ){
						this.tblName = tables[i].name;
						break;
					};
				};
				//後でtableNameを設定する処理を追加する事。
			}else{
				this.tblName = null;
			};
			if( currentDispObj ){
				currentDispObj.setId( this.dbId , this.tblId, this.rowId );
			};
		}
	});

	var tblName = null;
	Object.defineProperty( this , "tblName" , {
		get : function(){ return tblName;} ,
		set : function( val ){
			tblName = val;
			if( tblName ){
				_D.g("c_tbl").innerHTML = _U.htmlEscape( tblName );
				_D.show( _D.g("top_c_tbl") , true );
			}else{
				_D.show( _D.g("top_c_tbl") , false );
			};
		}
	});

	var rowId = null;
	Object.defineProperty( this , "rowId" , {
		get : function(){ return rowId;} ,
		set : function( val ){
			rowId = val;
			if( currentDispObj ){
				currentDispObj.setId( this.dbId , this.tblId, this.rowId );
			};
		}
	});

	//リクエストは基本、これを通す。
	//通信エラー等の画面遷移も、ここで処理する。
	this.request = function( url , requestValue , func , funcErr ){
		this.showMessageEz( "cmmn_0" , [url] );
		var after = function( xhr ){
			var obj;
			if ( xhr && xhr.readyState==4 && xhr.status>=200 && xhr.status < 300 ){
				obj = xhr.response;
				if( ! obj ){
					obj = _msg.getMessage("cmmn_E0" ,[url] ).main;
					obj.discription += "\r\nJSON parse error.";
				};
			}else{
				obj = _msg.getMessage("cmmn_E0" ,[url] ).main;
				
				if( xhr && xhr.status ){
					obj.discription += "\r\nstatus : "+xhr.status;
				};
			};


			if( obj.mode != "I" && obj.mode != "W" ){
				_disp.showMessage( obj , function(){ if( funcErr ){ funcErr( obj );}; } );
				return;
			};
			if( obj.mode == "W" ){
				_disp.showMessage( obj , function(){ func( obj ); } );
				return;
			};
			_disp.infoClose();
			func( obj );
		};
		_X.requestJson( url , requestValue , after , true );

	};

	//エラーモードを判別し、ここから再読み込みや遷移の指示を出す。
	var errAndChg = function( errMode ){
		if( errMode == "F" ){
			document.body.innerHTML = "";
			document.body.innerHTML = "FATAL ERROR";
			return;
		};
		if( errMode == "D" ){
			_disp.dipsCtrl( _disp.id.DBMng );
			return;
		};
		if( errMode == "T" ){
			if( currentDispId != _disp.id.DBMng ){
				_disp.dipsCtrl( _disp.id.TLst );
			}else{
				currentDispObj.reload();
			}
			return;
		};
		currentDispObj.reload();
	};
	//funcOk,funcCancelが省略された場合にこれを用いるケースがある。
	var dummyFunc = function(){};
	var createBtnObj = function( obj , str , func ){
		var wkFunc;
		if( obj.mode == "I" ||  obj.mode == "W" ){
			if( func && func.constructor == Function ){
				wkFunc = func;
			}else{
				wkFunc = dummyFunc;
			};
		}else{
			if( func && func.constructor == Function ){
				wkFunc = function(){
					func();
					errAndChg( obj.mode );
				};
			}else{
				wkFunc = function(){ errAndChg( obj.mode ); };
			};
		};
		return { str:str , func:wkFunc };
	};
	//オブジェクトを指定してinfoを呼び出す。
	//オブジェクトはmode,type,error,discriptionが設定されている事を期待する。
	//typeが無い場合は、サーバ応答と想定し、全てOKボタンのみとなる。
	//ただし、modeがI,W以外の場合は、原則的に自動で画面遷移させるため、funcOk,funcCancelは省略可

	this.showMessage = function( obj , funcOk , funcCancel ){

		if( ! obj.hasOwnProperty( "type" ) ){
			obj.type = "O";
		};

		var aryBtn =[];
		var wkFunc;
		if( obj.type == "O" || obj.type == "OC" ){
			aryBtn.push( createBtnObj( obj , "OK" , funcOk ) );
		};
		if( obj.type == "OC" ){
			aryBtn.push( createBtnObj( obj , "Cancel" , funcCancel ) );
		};
		this.info( obj.error , obj.discription , aryBtn );
	};
	this.showMessageEz = function( id , aryInf , funcOk , funcCancel ){
		var msg = _msg.getMessage( id , aryInf );
		this.showMessage( msg.main , funcOk , funcCancel );
	};

}();


var _eachDisp={
		//管理系
		DBMng:"DBMng",
		TMng:"TMng",
		CMng:"CMng",
		SMng:"SMng",
		RMng:"RMng",
		//操作系
		TLst:"TLst",
		LstV:"LstV",
		DtV:"DtV"
};
