//ユーザ表のデータを扱うオブジェクト。
//一部のシステム表へのアクセスも行う。
//検索機能(通信を伴う)は、ここに実機能を持つ。
//オブジェクト自体は単体で成立しており、画面はこのオブジェクトの内部にある表データを表示する、と言う仕組みとする。

//検索条件のリクエストは、この内部で生成する。
//引数やメンバとして持つリクエストは、実際のリクエストと形状、形態が異なる。
//検索条件を配列として持つ。
//loadJoin時に、これらから実際のリクエストオブジェクトを再生成する。
//引数のリクエストのメンバは、
//	db_id,
//	table_id,
//	Criteria
//の3つとする。
//前述２つは必須、Criteriaは省略された場合、あるいは空配列である場合、条件なしとして処理する。
//Criteriaは配列にオブジェクトを持ち、オブジェクトの内容は、
//	col_table,
//	col_relats,
//	column_id,
//	Not,
//	Mode,
//	Criteria
//とする。
//即ち、リクエストの配列要素と対応している。
//尚、Criteriaはパース済みの検索条件配列である。
	
var _tableData ={
	_loadedJoinedData : null,
	_loadedSingleDatas :{},
	_req : null,
	_getReq:function(){
		return this._req;
	},
	_setReq:function( req ){
		this._req = req;
	},
	_loadJoin:function( after , req ){
		var wkReq = req;
		if( ! wkReq ){
			wkReq = this._req;
		}else{
			this._req = wkReq;
		}

		var url = _urlMap.action.sTblJ;
		var realRq = {
			db_id:wkReq.db_id,
			table_id:wkReq.table_id
		};


		if( wkReq.Criteria && wkReq.Criteria.constructor == Array ){
			for( var i = 0 ; _U.isIdx( i , wkReq.Criteria ) ; i++ ){
				var C = wkReq.Criteria[i];
				realRq[ "col_table[" + i + "]" ] = C.col_table;
				realRq[ "col_relats[" + i + "]" ] = C.col_relats;
				realRq[ "column_id[" + i + "]" ] = C.column_id;
				realRq[ "Not[" + i + "]" ] = C.Not;
				realRq[ "Mode[" + i + "]" ] = C.Mode;

				for( var j = 0 ; _U.isIdx( j , C.Criteria ) ; j ++ ){
					realRq[ "Criteria[" + i + "][" + j + "]" ] = C.Criteria[ j ];
				};
			};
		};

		_disp.request( "php/" + url , realRq , function( obj ){
			_tableData._loadedJoinedData = obj;
			if( after && after.constructor == Function ){
				after();
			};
		} );
	},
	_loadSingle:function( after , req ){
		var wkReq = req;
		if( ! wkReq ){
			wkReq = this._req;
		}

		var url = _urlMap.action.sTbl;

		_disp.request( "php/" + url , wkReq , function( obj ){
			_tableData._loadedSingleDatas[obj.table_id] = obj;
			if( after && after.constructor == Function ){
				after();
			};
		} );
	},
	_getJoinedTableData:function(){
		return this._loadedJoinedData;
	},
	_getSingleTableData:function(table_id){
		return this._loadedSingleDatas[table_id];
	},
	//対象テーブルを複数指定して連続ロードする。
	_loadSingleChain:function( after , aryParams ){
		var idx = 0;
		var functionLoad = function(){
			if( _U.isIdx( idx , aryParams ) ){
				_tableData._load( functionLoad , aryParams[ idx ] );
			}else{
				after();
			};
			idx ++ ;
		};
		functionLoad();
	},
	_getJoinedTableInfo : function( tableId ){
		var joinInfo = _sysData._getData( "rlt" , _sysData._getMode.joinTbl )[tableId];
		var rltObj = _sysData._getData( "rlt" , _sysData._getMode.rlt );
		var tblTbl = _sysData._getData( "tbl" );
		var colTbl = _sysData._getData( "col" );

		//joinInfoを元に、関連付け情報を付与して返す。
		/*戻り値のデータ型は以下とする。
		[
			{
				tableId: <tableId>,
				tableName: <tableName>,
				strRlt:"<表名>.<列名> = <表名>.<列名> AND <表名>.<列名> = <表名>.<列名> ･･･",
				rlts:[ ･･･rlationids･･･ ]
			}
		]
		relationは最終的な関連付け情報を用い、表名については、登場順に1,2等と設定することとする。
		尚、tableId自体も戻り値に含まれるので留意する。
		*/
		var myName = _sysData._tblFind( tblTbl , [{key:"id",value:tableId }],true)[0].name;

		var ret = [{
			tableId: tableId,
			tableName: myName,
			strRlt:"",
			rlts:[]
		}];
		var tableCnts = {tableId:1};
		var rlts2TName = {"":myName};
		var tableCntsWk = {};

		//一旦、tableの数のみ確認する。
		for( var i = 0 ; _U.isIdx( i , joinInfo ) ; i ++ ){
			if( ! tableCnts[ joinInfo[ i ].table ] ){
				tableCnts[ joinInfo[ i ].table ] = 0;
			};
			tableCnts[ joinInfo[ i ].table ] ++ ;
		};

		//数が2以上であれば、表名の後ろに_1,_2のように数字を付与する。
		for( var i = 0 ; _U.isIdx( i , joinInfo ) ; i ++ ){
			var table = _sysData._tblFind( tblTbl , [{key:"id",value:joinInfo[ i ].table }],true)[0];
			var tName = table.name;
			if( tableCnts[ joinInfo[ i ].table ] > 1 ){
				if( ! tableCntsWk[ joinInfo[ i ].table ] ){
					tableCntsWk[ joinInfo[ i ].table ] = 0;
				};
				tableCntsWk[ joinInfo[ i ].table ]++;
				tName += "_" + tableCntsWk[ joinInfo[ i ].table ];
			};
			var strRlts = joinInfo[ i ].rlts.join();
			rlts2TName[ strRlts ] = tName;

			//一時作業用に関連付け配列をコピーし、末尾の値を取得すると共に、末尾の値を配列から除去する。
			var wkRlts = joinInfo[ i ].rlts.concat();
			var myRltId = wkRlts.pop();

			var myRltTbl = rltObj[ joinInfo[ i ].table ];
			var rltInfo = _sysData._tblFind( myRltTbl , [{key:"id",value:myRltId }],true)[0];

			var cTableName = rlts2TName[ wkRlts.join() ];

			var strRlt = "";
			for( var j = 0 ; _U.isIdx( j , rltInfo.cols ) ; j ++ ){
				var myColName = _sysData._tblFind( colTbl , [{key:"id",value:rltInfo.cols[j].myCId }],true)[0].name;
				var cColName = _sysData._tblFind( colTbl , [{key:"id",value:rltInfo.cols[j].tCId }],true)[0].name;
				if( strRlt != "" ){
					strRlt +=" AND "
				};
				strRlt += (
					cTableName + "." + cColName + " = " +
					tName + "." + myColName
				);
			};
			ret.push({
				tableId: joinInfo[ i ].table,
				tableName: tName,
				strRlt:strRlt,
				rlts:joinInfo[ i ].rlts.concat()
			});
		};
		return ret;
	},
	_dataConv4HtmlStr( data , type ){
		if( _U.find( type , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) == -1 ){
			return "";
		};
		if( data === null || data === undefined ){
			return "";
		};
		if( _U.find( type , [ 1 , 2 , 3 , 8 ] ) != -1 ){
			return data.toString();
		};

		var numCastErr;
		var num;
		try{
			num = data - 0;
		}catch(e){
			numCastErr = true;
			num = 0;
		};
		if( isNaN( num ) ){
			numCastErr = true;
			num = 0;
		};

		if( type == 7 ){
			if( num > 0 ){
				return "true";
			}else if( num < 0 ){
				return "false";
			};
			return "";
		};
		//残りはDateにキャストする。
		if( numCastErr ){
			return "";
		};
		var dt = new Date( num );

		var y = ( "0000" + dt.getFullYear() ).slice( -4 );
		var m = ( "00" + ( dt.getMonth() + 1 ) ).slice( -2 );
		var d = ( "00" + dt.getDate() ).slice( -2 )

		var h = ( "00" + dt.getHours() ).slice( -2 );
		var mi = ( "00" + dt.getMinutes() ).slice( -2 );
		var s = ( "00" + dt.getSeconds() ).slice( -2 );

		//ミリ秒は本ｼｽﾃﾑでは利用されない。
		//ただし、型変換時などではミリ秒が入っている可能性がある。
		//var ms = d.getMilliseconds();
		var ret ="";
		if( type != 6 ){
			ret += y + "/" + m + "/" + d;
		};
		if( type == 4 ){
			ret += " ";
		};
		if( type != 5 ){
			ret += h + ":" + mi + ":" + s;
		};
		return ret;
	},
	_dataConv4ReqStr( value , type ){
		var num;
		if( _U.find( type , [ 3 , 8 ] ) != -1 ){
			return value.toString();
		};
		if( _U.find( type , [ 1 , 2 ] ) != -1 ){
			if( value == '' )return value;
			try{
				num = value - 0;
			}catch(e){
				return "";
			};
			if( isNaN( num ) ){
				return "";
			};
			return num.toString();
		};
		if( type == 7 ){
			if( value === true ){
				return "1";
			}else if( value === false ){
				return "-1";
			}else if( value === null || value === undefined ){
				return "0";
			};
			try{
				num = value - 0;
			}catch(e){
				return "0";
			};
			if( isNaN( num ) ){
				return "0";
			};

			if( num > 0 ){
				return "1";
			}else if( num < 0 ){
				return "-1";
			};
			return "0";
		};
		if( _U.find( type , [ 4 , 5 , 6 ] ) != -1 ){
			if( type == 6 ){
				value = "1970/1/1 "+value;
			}

			var d = new Date( value );
			if( d.toString() === "Invalid Date" ){
				return "";
			}
			if( type == 5 ){
				//0時0分0秒にする。
				//setUTCMilliseconds(0)
				d.setHours(0 , 0 , 0 , 0 );
			}else if( type == 6 ){
				//1970年1月1日にする。
				d.setFullYear(1970 , 0 , 1);
			};
			return d.valueOf().toString();
		};
		return "";
	},
	//true,falseを返す実装とする。
	dataValidation:function( value , type ){
		var num;
		if( _U.find( type , [ 1 , 2 ] ) != -1 ){
			//数値にキャストする。
			try{
				num = value - 0;
			}catch(e){
				return false;
			};
			if( isNaN( num ) ){
				return false;
			};
			if( type == 1 ){
				return ! isNaN( parseInt( num ) );
			};
			return true;
			
		}else if( _U.find( type , [ 4 , 5 , 6 ] ) != -1 ){
			//dateに変換してみる。
			//通らない場合と、日付で時間が0でない場合、
			//通らない場合と、時間で日付が1970/1/1でない場合にエラーとする。
			if( type == 6 ){
				value = "1970/1/1 "+value;
			}
			var d = new Date( value );
			if( d.toString() === "Invalid Date" ){
				return false;
			}
			var valOf = d.valueOf();

			if( type == 5 ){
				//0時0分0秒にする。
				//setUTCMilliseconds(0)
				d.setHours(0 , 0 , 0 , 0 );
			}else if( type == 6 ){
				//1970年1月1日にする。
				d.setFullYear(1970 , 0 , 1);
			};

			return valOf == d.valueOf();


		};
		return true;
	}
};

