﻿/**
 * @fileoverview 画面内の処理が同期・非同期通信の両方存在する場合に使用されるダブルクリック防止Javascript
 */
(function(){
if (typeof(DDP) == 'undefined') DDP = {};
if (typeof(DDP.Async) == 'undefined') DDP.Async = {};
if (!DDP.Async.updateControls) DDP.Async.updateControls = [];

// 非同期呼び出し回数
var _asyncCnt=0;
// 部品の状態保持(disabled)
var _statControl = new Array();
// トリガーとなったUpdatePanel
var _trigPanel="";
// submitが呼ばれたら１以上
var _submittedFlag=0;
// browserの種類,IE/FireFox/Other
var _browser="";
// BeginRequest->1 , 同期ボタン->0
var _disableMode="";
// 未実装（全てのUpdatePanelの上の子供の部品）
var _updateAll = new Array();
var _doc = document;
var _inited = false;

/**
 * 非同期通信発生時に使用される、Webコントロール使用可能・不可能を制御する関数。
 */
function BeginRequest() {
	_inited = true;
	//条件によって利用不可にする。
	if (_asyncCnt==0) {
		_disableMode="1";
		controlDisable();
	}
	_asyncCnt++;
}

/**
 * 非同期通信終了時に使用される、Webコントロール使用可能・不可能を制御する関数。
 */
function EndRequest() {
	if (!_inited) {
		_inited = true;
		_asyncCnt++;
	}
	_asyncCnt--;
	//条件によって利用可能にする。
	if (_asyncCnt==0) {
		controlEnable();
		_submittedFlag=0;
	}
}

/**
 * 使用不可能になっているWebコントロールを使用可能にする関数。
 */
function controlEnable() {
	var updatePan=new Array();
	var children=new Array();
	
	if (_trigPanel!=null&&_trigPanel!="") {
		children=DDP.Async.updateControls[_trigPanel];
	}
	
	if (children!=null) {
		for(var i=0,len=children.length;i<len;i++) {
			updatePan[children[i]]=true;
		}
	}
	//リンク
	for(var i=0,lLen=_doc.links.length;i<lLen;i++) {
		var elm = _doc.links[i];
		if (elm.target !="_blank" && elm.href.search("__doPostBack")>0) {
			var id="";
			if (elm.id!=null && elm.id!="") {
				id = elm.id;
			} else if (elm.title!=null && elm.title!="") {
				id = elm.title;
			}
			if (id=="") continue;
			var statCtrl = _statControl[id];
			if (_disableMode=="1") {
				if (statCtrl == null) {
					// nop
				} else if (statCtrl == elm.disabled) {
					// nop
				} else if (statCtrl != elm.disabled) {
					// UpdatePanelに乗っていなければ、元の状態に戻す。
					if (updatePan[id]==null) {
						elm.disabled = statCtrl;
					}
				}
			} else if (_disableMode=="0") {
				elm.disabled = statCtrl;
			}
		}
	}
	//input
	var inputElmlist = _doc.getElementsByTagName("input");
	for(var i=0,iLen=inputElmlist.length;i<iLen;i++) {
		var elm = inputElmlist[i];
		if (elm.type == "submit"||elm.type == "image") {
			var statCtrl = _statControl[elm.id];
			if (_disableMode=="1") {
				if (statCtrl == null) {
					// nop
				} else if (statCtrl == elm.disabled) {
					// nop
				} else if (statCtrl != elm.disabled) {
					// UpdatePanelに乗っていなければ、元の状態に戻す。
					if (updatePan[elm.id]==null) {
						elm.disabled = statCtrl;
					}
				}
			} else if (_disableMode=="0") {
				elm.disabled = statCtrl;
			}
		}
	}
	//select
	var selectElmlist = _doc.getElementsByTagName("select");
	for(var i=0,sLen=selectElmlist.length;i<sLen;i++) {
		var elm = selectElmlist.item(i);
		if (elm.addEventListener) continue;
		if (elm.outerHTML!="undefined" && elm.outerHTML.search("__doPostBack")<0) continue;
		var statCtrl = _statControl[elm.id];
		if (_disableMode=="1") {
			if (statCtrl == null) {
				// nop
			} else if (statCtrl == elm.disabled) {
				// nop
			} else if (statCtrl != elm.disabled) {
				// UpdatePanelに乗っていなければ、元の状態に戻す。
				if (updatePan[elm.id]==null) {
					elm.disabled = statCtrl;
				}
			}
		} else if (_disableMode=="0") {
			elm.disabled = statCtrl;
		}
	}  
	_disableMode="";
}

/**
 * 現在の状態を保管し、Webコントロールを使用不可能にする関数。
 */
function controlDisable() {
	//リンク
	for(var i=0,lLen=_doc.links.length;i<lLen;i++) {
		var elm = _doc.links[i];
		if (elm.target !="_blank" && elm.href.search("__doPostBack")>0) {
			if (elm.id!=null && elm.id!="") {
				_statControl[elm.id] = elm.disabled;
				elm.disabled = true;
			} else if (elm.title!=null && elm.title!="") {
				_statControl[elm.title] = elm.disabled;
				elm.disabled = true;
			}
		}
	}
	//input
	var inputElmlist = _doc.getElementsByTagName("input");
	for(var i=0;i<inputElmlist.length;i++){
		var elm = inputElmlist[i];
		if (elm.type == "submit"||elm.type == "image"){
			_statControl[elm.id] = elm.disabled;
			elm.disabled = true;
		}
	}
	//select
	var selectElmlist = _doc.getElementsByTagName("select");
	for(var i=0,sLen=selectElmlist.length;i<sLen;i++){
		var elm = selectElmlist[i];
		if (elm.addEventListener) continue;
		if (elm.outerHTML!="undefined" && elm.outerHTML.search("__doPostBack")<0) continue;
		_statControl[elm.id] = elm.disabled;
		elm.disabled = true; 
	}
}

var AsyncProtectDoubleClick = "";

/**
 * 画面load時にハンドラを設定する関数。
 * @param window 対象
 * @param load イベント名
 * @param function() 登録する関数
 */
$addHandler(window,'load', function() {
	AsyncProtectDoubleClick = $create(ProtectDoubleClick.AsyncProtectDoubleClick, {}, null, null, null);
});

Type.registerNamespace("ProtectDoubleClick");
ProtectDoubleClick.AsyncProtectDoubleClick = function() {
	//基本クラスを初期化する
	ProtectDoubleClick.AsyncProtectDoubleClick.initializeBase(this);
	this._instance = null;              //PageRequestManagerのインスタンス
	this._beginRequestHandler = null;   //非同期通信開始時に実行するハンドラー
	this._endRequestHandler = null;     //非同期通信終了時に実行するハンドラー
	this._protectList = null;           //既存のclick処理を退避するリスト
	this._submitHandler = null;         //クリック処理をフックするハンドラー
}
//メンバの追加
ProtectDoubleClick.AsyncProtectDoubleClick.prototype = {
	initialize:function() {
		ProtectDoubleClick.AsyncProtectDoubleClick.callBaseMethod(this,'initialize');
		this._setControlDoubleClick();
		
		//UpdatePanel内の非同期通信時に制御するイベントを登録
		//PageRequestManagerが生成されている場合、非同期通信用の制御メソッドを登録します。
		this._instance = Sys.WebForms.PageRequestManager.getInstance();
		if (null!=this._instance) {
			 this._beginRequestHandler = Function.createDelegate(this, this._onBeginRequest);
			 this._endRequestHandler = Function.createDelegate(this, this._onEndRequest);
			 this._instance.add_beginRequest(this._beginRequestHandler);
			 this._instance.add_endRequest(this._endRequestHandler);
		}
	},
	//同期通信時の二度押し制御を行うWebコントロールで、onclick処理に制御メソッドを定義
	_setControlDoubleClick : function() {
		if (null==this._submitHandler) {
			this._submitHandler = Function.createDelegate(this, this._controlSubmit);
		}
		this._protectList = new Array();
		//全てのリンクのクリックイベントに_controlSubmitメソッドを登録
		for(var i=0,lLen=_doc.links.length;i<lLen;i++){
			var elm=_doc.links[i];
			if (null!=elm.href && elm.href.search("__doPostBack")>0) {
				elm.onclick = this._submitHandler;
			}
		}
		//ボタンは制御しない
		var inputElmlist = _doc.getElementsByTagName("input");
		if (inputElmlist!=null) {
		}
		//全てのselectに_controlSubmitメソッドを登録
		var selectElmlist = _doc.getElementsByTagName("select");
		for(var i=0,sLen=selectElmlist.length;i<sLen;i++) {
			//onchange属性がないなら（AutoPostBackがFalse）メソッドを登録しない
			var selelm= selectElmlist[i];
			if (selelm.addEventListener) continue;
			if (selelm.onchange !=null && selelm.outerHTML!="undefined" && selelm.outerHTML.search("__doPostBack")>0) {
				if (selelm.addEventListener) { 
					// FireFox用
					selelm.addEventListener("change", this._submitHandler, false); 
				} else if (selelm.attachEvent) {
					// IE用
					selelm.attachEvent("onchange", this._submitHandler);
				} else {
					formTag.onchange = this._submitHandler;
				}
			}
		}
		// formタグのコレクション分、for文を回す
		var formElmList=_doc.getElementsByTagName("form");
		for(var i=0,fLen=formElmList.length;i<fLen;i++) {
			var formTag = formElmList.item(i);
			if (formTag.addEventListener) { 
				// FireFox用
				formTag.addEventListener("submit", this._submitHandler, false);
				_browser="FireFox";
			} else if (formTag.attachEvent) {
				// IE用
				formTag.attachEvent("onsubmit", this._submitHandler);
				_browser="IE";
			} else {
				formTag.onclick = this._submitHandler;
				_browser="";
			}
		}
	},
	/**
	 * 2度押し制御コントロールのクリック時処理関数。（アクセス中は処理が中断される.非同期通信時は利用しません
	**/
	_controlSubmit : function(e) {
		if (_submittedFlag>0||AsyncProtectDoubleClick._isAccessing()) {
			if (_browser=="FireFox" || _browser=="IE") {
				if (_disableMode!="") return;
				_disableMode="0";
				controlDisable();
			}
			alert("処理中です。暫くお待ちください。");
			return false;
		}
		var rc=true;
		if (_submittedFlag>0) {
			return false;
		}
		_submittedFlag++;
		if (_browser=="FireFox" || _browser=="IE") {
			//_disableMode="0";
			//setTimeout('controlDisable()',300);
		}
		return rc;
	},
	/**
	 * 同期通信時に通信中かどうかを判定する関数
	 * @return readyState 通信状態
	**/
	_isAccessing : function() {
		return (_doc.readyState != null && _doc.readyState != "complete");
	},
	/**
	 * 非同期通信開始イベント
	 * @param sender イベント発行元
	 * @param args イベント引数
	**/      
	_onBeginRequest : function(sender,args) {
		var tmp=sender._postBackSettings.panelID.split('|');
		if (tmp.length==2) {
			var _arr=tmp[0].split('$');
			_trigPanel="";
			for(var i=0,aLen=_arr.length-1;i<aLen;i++) {
				_trigPanel=_trigPanel+_arr[i]+"_";
			}
			_trigPanel=_trigPanel+_arr[_arr.length-1];
		} else {
			_trigPanel="";
		}
		BeginRequest();
	},
	/**
	 * 非同期通信終了イベント
	 * @param sender イベント発行元
	 * @param args イベント引数
	**/
	_onEndRequest : function(sender,args) {
		EndRequest();
	},
	/**
	 * コンポーネントの破棄を処理する関数
	**/
	dispose: function() {
		ProtectDoubleClick.AsyncProtectDoubleClick.callBaseMethod(this, 'dispose');
		if (null!=this._instance) {
			if (null!=this._beginRequestHandler) {
				this._instance.remove_beginRequest(this._beginRequestHandler);
			}
			if (null!=this._endRequestHandler) {
				this._instance.remove_endRequest(this._endRequestHandler);
			}
		}
	}
}
//オブジェクトの登録
ProtectDoubleClick.AsyncProtectDoubleClick.registerClass('ProtectDoubleClick.AsyncProtectDoubleClick', Sys.Component);
if (typeof(Sys) !== 'undefined')
	Sys.Application.notifyScriptLoaded();
})();

