/*************************************************************************
 * 動的プルダウンを実行するためのJavaScriptです。
 *
 * @og.rev 5.2.0.0 (2010/09/01) Javaスクリプトで登録したイベントを発動させる
 * Revision: $Id$
 *************************************************************************/
var colMap;
var notFireCols;
var jH_evElm;

$(function(){
	if( ! ( typeof( EC_NAME ) == "undefined" ) ) {
		// 初期化処理だけは、予め要素オブジェクトを取得しておき、ここから子カラムを取得する。
		jH_evElm = $( ".h_evElm" );

		makeColMapping();

		setEvent( "textarea,select,input[type=\"text\"]", "change", function(){ makeColumn( this ); }, ".h_evCol", true, addEvColCls );
		setEvent( "input[type=checkbox],input[type=radio]", "click", function(){ makeColumn( this ); }, ".h_evCol", true );
	}
});

/**
 * 親カラムをキーにしたイベントカラムの一覧を作成します。
 *
 * 親カラムを連想配列のキーとして、子カラムの一覧を配列として保持します。
 *
 * @og.rev 5.2.0.0 (2010/09/01) 新規作成
 *
**/
function makeColMapping() {
	if( colMap ){ return; }

	colMap = new Object();
	for( var i=0; i<EC_EVCOL.length; i++ ) {
		var evCols = EC_EVCOL[i].split(",");
		for( var j=0; j<evCols.length; j++ ) {
			var evc = evCols[j];
			if( evc.charAt(0) == "_" ) {
				evc = evc.substring(1);
				if( notFireCols ) { notFireCols += ","; }
				notFireCols += evc;
			}
			var cCols = colMap[evc];
			if( !cCols ) { cCols = new Array(); }
			cCols[cCols.length] = EC_NAME[i];
			colMap[evc] = cCols;
		}
	}
}

/**
 * 親カラムに対してクラスを付加します。
 *
 * @og.rev 5.2.0.0 (2010/09/01) 新規作成
 *
**/
function addEvColCls() {
	for( var evCol in colMap ) {
		$("#"+evCol+",[id^="+evCol+"__]").addClass("h_evCol");
	}
}

/**
 * イベントカラムが設定されたタグ(spanタグ)を検索し、親カラムにイベントを登録します。
 *
 * @og.rev 5.1.7.0 (2010/06/01) 新規作成(動的プルダウン実装見直し)
 *
 * @param evCol	イベントが発生した親カラムのオブジェクト
**/
function makeColumn( evCol ) {
	if( jH_evElm && isEndInitEvent() ) { jH_evElm = null; }

	var jEvCol = $( evCol );
	var evColId = jEvCol.attr("id");
	var evColName = evColId.split("__")[0];

	var cColNameArr = colMap[evColName];
	if( !cColNameArr ) { return; }

	// イベントカラムでカラム名の頭文字が'_'で始まっている場合、初回イベント発行を行わない。
	if( !isEndInitEvent() && notFireCols && notFireCols.indexOf( evColName ) >= 0 ) { return; }

	for( var i=0; i<cColNameArr.length; i++ ) {
		var suffix = ( evColId == evColName ? "" : "__" + evColId.split("__")[1] );
		var cid = cColNameArr[i]+suffix;
		var cname = cid.split("__")[0];
		var jTag = isEndInitEvent() ? $( ".h_evElm[h_evCid="+cid+"]" ) : jH_evElm.filter( "[h_evCid="+cid+"]" );
		var writable = jTag.attr("h_evWrtbl");
		eventColumn( jEvCol, jTag, cid, cname, suffix, writable );
	}
}

/**
 * Ajax動的カラム変更用の共通JavaScript
 * 
 * カラムにeventColumnをセットした時に親側にID指定でChangeイベントとして登録されます。
 * ※イベント処理用のJSP用に送られるパラメーターに関しては、jsp/common/eventColumnMaker.jspの
 *   コメントを参照して下さい。
 *
 * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
 *
 * @param jEvCol	イベントが発生した親カラムのjQueryオブジェクト
 * @param jTag		置き換え要素をラップしたspanタグのjQueryオブジェクト
 * @param cid		変更対象の子要素(inputタグなど)のID
 * @param cname		子のカラム名
 * @param suffix	__ + 行番号(一覧表示の場合のみ)
 * @param writable	書き込み可能かどうか
**/
function eventColumn( jEvCol, jTag, cid, cname, suffix, writable ){
	if( !jTag || jTag.length == 0 ) {
		alert( "[SYSTEM_ERROR] : イベントカラムで置き換え対象の要素が存在しません" );
		return;
	}

//	if( cid == null || cid == "" || cname == null || cname == "" ) {
//		alert( "[SYSTEM_ERROR] : 子要素のIDまたはNAMEがセットされていません" );
//		return;
//	}

	if( !isEndInitEvent() ) {
		var evVal = jEvCol.val();
		if( !evVal || evVal == null || evVal == "" ) { return; }
	}

	try {
		var url = eval( "EC_" + cname + "_URL" );
	}
	catch( e ) {
		alert( "[SYSTEM_ERROR] : イベントを処理するURLが指定されていません。(変数未定義)" );
		return;
	}
	if( !url || url == "" ) {
		alert( "[SYSTEM_ERROR] : イベントを処理するURLが指定されていません。" );
		return;
	}

	// SQL文をパースして{@xxx}をxxxのvalue値に変更する。一覧での利用では同一行のカラムになる。
	//（リクエスト変数はテキストボックスで一度受ける必要がある）
	// 又、パースして得られたvalue値をJSPのリクエスト変数としてURLの後ろに付ける
	var param = "";
	try { param = ( writable ? eval( "EC_" + cname + "_EDITPARAM" ) : eval( "EC_" + cname + "_RENDPARAM" ) ); } catch( e ) {}
	if( param != null && param != "" ) {
		url += "?";
		var _pos1 = 0, _pos2 = 0, _repClm, _rep, _clm;
		while( (_pos1 = param.indexOf("{@",_pos2)) != -1){
			_pos2 = param.indexOf("}",_pos1);
			_clm = param.substring(_pos1+2,_pos2);
			if( _clm.indexOf(".") < 0 ) {
				_repClm = "{@"+_clm+"}";
				_rep = suffix == "" ? $('#'+_clm).val() : $('#'+_clm+suffix).val();
				_rep = ( _rep == null ? "" : _rep );
				param = param.replace(_repClm,_rep);
				url += _clm + "=" +  encodeURIComponent(_rep) +"&";
			}
			_pos2 = _pos1+1; // 4.3.6.2 (2009/04/15)
		}
	}

	// 子がSelectタグの場合、最上部に空のoptionが存在すればEC_NOVALUEをtrueで送る
	var noVal = function(){
		_firstOption = jCol.children('option').get(0);
		if( _firstOption == null || _firstOption.value != "" ){ return false; }
		return true;
	}

	// 4.3.6.5 (2009/05/08) must,mustAnyを引数でJSPに送る。
//	var mustOrMustAny = function(){
//		var _haveClasses = jCol.attr("class");
//		if( _haveClasses && _haveClasses.indexOf("must") >= 0 ){
//			if( _haveClasses.indexOf("mustAny") >= 0 )	{ return "mustAny"; }
//			else										{ return "must"; }
//			return "";
//		}
//	}

	var columnFocus = function() {
		jCol.attr("isfocus","true");
	}

	if( cid != null && cid != "" ) {
		var jCol = jTag.find( "#"+cid );
	}
	else {
		var jCol = new Array(0)
	}

	if( jCol.length > 0 && isEndInitEvent() ) {
		jCol.bind("focus",columnFocus);
	}

	var val = "";
	if( jCol.length > 0 ) {
		if( isEndInitEvent() )	{ val = ( jCol.val() == null ? "" : jCol.val() ); }
		else					{ val = ( jTag.attr( "h_evVal" ) == null ? "" : jTag.attr( "h_evVal" ) ); }
	}

	var renderer = "";
	try { renderer = eval( "EC_" + cname + "_RENDERER" ); } catch( e ) {}

	var editor = "";
	try { editor = eval( "EC_" + cname + "_EDITOR" ); } catch( e ) {}

	// 5.2.0.0 (2010/09/01) 属性値が正しく引き継がれないバグを修正
	var ATTRS = [ "title", "style", "tabindex", "readonly", "disabled"
				, "onClick", "onChange", "onBlur", "onFocus", "ondblClick", "onMouseDown", "onMouseUp"
				, "onMouseMove", "onMouseOut", "onMouseOver", "onSelect", "onKeydown", "onKeypress", "onKeyup" ];
	var optAttrs = "";
	if( jCol.length > 0 ) {
		for( var i=0; i<ATTRS.length; i++ ) {
			var optAtt = jCol.attr(ATTRS[i]);
			if( optAtt != null ) {
				var vtype = typeof( optAtt );
				var isAdd = false;
				if( vtype == "function" ) {
					optAtt = optAtt.toString();
					isAdd = optAtt.length > 0 ? true : false;
					// 関数の場合は、文字列表現として"function anonymous(){...}"という関数定義が返るため、
					// ( FUNCTION )(); 形式で関数を実行するように変更
					optAtt = "(" + optAtt + ")()";
				}
				else if( vtype == "boolean" ) {
					isAdd = optAtt;
				}
				else {
					isAdd = optAtt.length > 0 ? true : false;
				}

				if( isAdd ) {
					optAttrs += ATTRS[i] + "='" + optAtt + "' ";
				}
			}
		}
	}

	// JSPを呼び出して処理する
	$.ajax({
		url: url,
		data: {
			"EC_CID"		: ( cid == null ? "" : cid ),
			"EC_CNAME"		: ( cname == null ? "" : cname ),
			"EC_RENDERER"	:renderer,
			"EC_EDITOR"		: editor,
			"EC_PARAM"		: param,
			"EC_SQL"		: param,
			"EC_WRITABLE"	: ( writable == null ? "" : writable ),
			"EC_CVALUE"		: val,
			"EC_NOVALUE"	: ( jCol.length == 0 ? "" : noVal() ),
//			"EC_MUST"		: ( jCol.length == 0 ? "" : mustOrMustAny() ),
			"EC_CLASS"		: ( jCol.length == 0 ? "" : jCol.attr("class") ),
			"EC_SIZE"		: ( jCol.length == 0 ? "" : jCol.attr("size") ),
			"EC_MAXLENGTH"	: ( jCol.length == 0 ? "" : jCol.attr("maxlength") ),
			"EC_OPTATTRS"	: optAttrs
		},
		type: 'POST',
		dataType: 'html',
		async : isEndInitEvent(),
		error: function(r,s,e){
			alert('EventColumnError:'+r+':'+s+':'+e+':'+cname);
		},
		success: function(data,status){
			var jNewCol = $(data);

			if( jCol.length > 0 ) {
				if( isEndInitEvent() ) {
					jCol.unbind("focus",columnFocus);
				}
				bindOldEvents( jNewCol.get(0), jQuery.data( jCol.clone(true).get(0),"events" ) );
			}

			jTag.empty().append( jNewCol );

			if( jCol.length > 0 ) {
				jTag.find("input,select,textarea").attr( "name", cid ).attr( "id", cid );

				if( isEndInitEvent() ) {
					// 置き換え先の要素にフォーカスが当たっていた場合は、フォーカスを復活
					if( jCol.attr("isfocus") ) {
//						jNewCol.focus();
						jNewCol.get(0).focus();
						// IEの場合、置き換え先の要素がテキストボックスの場合は、もう１度フォーカスする必要がある。
						if( $.browser.msie ) {
							jNewCol.get(0).focus();
						}
					}
				}
				// 初回読み込み時に置き換えられた要素はchangeイベントを発行
				if( !isEndInitEvent() ) {
					jNewCol.change();
				}
			}

			// ヘッダー固定再計算(処理が重いので、見直しの必要あり)
			if( suffix != null && suffix != "" ) {
				$('table#viewTable').resizeView();
			}
		}
	});
}

function bindOldEvents( newCol, oldEvents ) {
	for ( var type in oldEvents ) {
		for ( var handler in oldEvents[type] ) {
			jQuery.event.add( newCol, type, oldEvents[type][handler], oldEvents[type][handler].data );
		}
	}
}
