var FormExt = Class.create({
	initialize: function(id){
		this.id=id;
		this.obj=$(this.id);
		this.validObj=null;
		this.multiFCK=null;
		this.multiFCKarr=null;
		this.captchaObj=null;		
		this.actionID=null;   
		this.submitCnt=0;
		this.ajaxObj='';
		this.timerID='';
		this.respMsgObj='';
		this.url=_SELF;
		this.authorization='RAEDP';
		this.fileUpload=null;
		this.eventFileUploadChange=null;
		this.submitCnt=0;
		this.keys=null;
	},
	
	setValidation:function(val){
		if (val){
			this.validObj=new Validation(this.id,{onSubmit:false,immediate:false});
		}
	},
	
	setFileUpload:function(elmID,url,recID,downloadUrl){
		if (url){
			this.fileUpload=new FileUpload(this.id,elmID,url,recID,downloadUrl);
			this.eventFileUploadChange=this.fileUploadNewItem.bindAsEventListener(this);
			Event.observe(elmID,'change',this.eventFileUploadChange);
		}
	},
	
	setUrl:function(val){
		this.url=val;
	},
	
	setRespMsgObj:function(id,ele,position){
		this.respMsgObj=new RespMsg(id,ele,position);
	},
	
	setMultiFCK:function(arr){
		if (arr.length>0){
			this.multiFCK=new MultiFCK(arr);
			this.multiFCKarr=arr;
		}
	},

	setCaptcha:function(url,id){
		this.captchaObj=new Captcha(url,id);
	},
	
	setActionID:function(actionID){
		this.actionID=actionID;
	},
	
	getActionID:function(){
		return this.actionID;
	},
	
	withValidation:function(){
		return this.validObj!=null?true:false;
	},
	
	withFileUpload:function(){
		return this.fileUpload!=null?true:false;
	},
	
	withMultiFCK:function(){
		return this.multiFCK!=null?true:false;
	},
	
	withCaptcha:function(){
		return this.captchaObj!=null?true:false;
	},
	
	submit:function(e){
		e.stop();
		//for FF, update the data, IE no need
		if (this.withMultiFCK()){
			this.multiFCK.updateLinkedField();
		}

		this.respMsgObj.hide();
		if (this.submitCnt==0){
			this.submitCnt++;

			if (this.withFileUpload()){
				if(!this.fileUpload.isUploading()){
					this.ajaxAction(e);
				} else {
					new PeriodicalExecuter(function(pe){   
						if(!this.fileUpload.isUploading()){
							this.ajaxAction(e);
							pe.stop(); 
						}
					}.bind(this),10); 
				}
			} else {
				this.ajaxAction(e);
			}				
		} else {
			alert("你的查詢經已送出，請耐心等待。");
		}
	},
	
	ajaxAction:function(e){
		switch(this.actionID){
			case 'add':
				if (!this.validate()){
					this.submitCnt=0;
					return false;
				}
				this.ajaxObj=new AjaxForm_ADD(this);
				this.ajaxObj.setPars(this.setParsByForm());
				return false;
				this.ajaxObj.setUrl(this.url);
				this.ajaxObj.setAjaxReqObj();
				break;
			case 'edit':
				if (!this.validate()){
					this.submitCnt=0;
					return false;
				}
				this.ajaxObj=new AjaxForm_EDIT(this);
				this.ajaxObj.setAsyn(false);
				this.ajaxObj.setPars(this.setParsByForm());
				this.ajaxObj.setUrl(this.url);
				this.ajaxObj.setAjaxReqObj();
				this.edit_cancel();
				break;
			case 'del':
				this.ajaxObj=new AjaxForm_DEL(this);
				this.ajaxObj.setPars(this.setParsByKey());
				this.ajaxObj.setUrl(this.url);
				this.ajaxObj.setAjaxReqObj();
				break;
			default:
				alert('ActionID not found');
		}
	},
	
	validate:function(){
		if (this.withValidation()){
			return this.validObj.validate();
		} else {
			return false;
		}
	},
	
	reset:function(e){
		var tmpActionID;
		if (this.withValidation()){
			this.validObj.reset();
		}
		
		if (this.withCaptcha()){
			this.captchaObj.reset();
		}
		
		if (this.withFileUpload()){
			this.fileUploadDestroy(e);
		}
		
		this.obj.reset();			
		if (this.actionID=='add'){
			//iff 'add', clear forms element
			this.setAddFrmDefaultValue();
			if (this.withMultiFCK()){
				this.multiFCK.setContent('');	
			}
			this.submitCnt=0;	
		} else {
			//if 'edit', it has rec to load from DB
			this.respMsgObj.hide();
			tmpActionID=this.getActionID();
			this.setActionID('reset');
			this.getPageInitValue();
			this.setActionID(tmpActionID);
		}
		this.setFrmDisable();
	},
	
	setAddFrmDefaultValue:function(){
		//this.setFrmDisable();
	},
	
	setFrmDisable:function(){
	},
	
	setFrmDefaultEvent:function(e){
		Event.observe(this.id, 'submit',this.submit.bindAsEventListener(this,e));
		Event.observe('resetBtn', 'click',this.reset.bindAsEventListener(this,e));
		/*
		//useless in this application
		Event.observe('buttonBack','click',previousPage);
		*/
	},
	
	setFrmEvent:function(e){
		this.setFrmDefaultEvent(e);
		/*
		//useless in this application
		if (this.hasAuthorization('E')){
			Event.observe('buttonEdit','click',this.edit.bindAsEventListener(this,e));
			Event.observe('buttonEdit_cancel','click',this.edit_cancel.bindAsEventListener(this,e));
		}
		if (this.hasAuthorization('D')){
			Event.observe('buttonDel','click',this.del.bindAsEventListener(this,e));
		}
		*/
	},

	getPageInitValue:function(){
		this.setFrmValue();
	},
	
	setFrmValue:function(){
		if (this.actionID=='detail'){
			this.ajaxObj = new AjaxForm_DETAIL(this);
		} else if (this.actionID=='reset'){
			this.ajaxObj = new AjaxForm_RESET(this);
		}
		
		this.ajaxObj.setPars(this.setParsByKey());
		this.ajaxObj.setUrl(this.url);
		this.ajaxObj.setAjaxReqObj();
	},
	
	edit:function(e){
		if (this.hasAuthorization('D')){
			$('buttonDelDiv').toggle();
		}
		if (this.hasAuthorization('E')){
			$('buttonEditDiv','buttonEditDiv_cancel').invoke('toggle');
		}
		this.respMsgObj.hide();
		this.enable();
		this.submitCnt=0;
		this.setActionID('edit');
	},
	
	edit_cancel:function(e){
		if (this.hasAuthorization('D')){
			$('buttonDelDiv').toggle();
		}
		if (this.hasAuthorization('E')){
			$('buttonEditDiv','buttonEditDiv_cancel').invoke('toggle');
		}
		if (this.withValidation()){
			this.validObj.reset();
		}
		
		if (this.withFileUpload()){
			this.fileUploadDestroy(e);
		}
		
		this.setActionID('detail');
		this.getPageInitValue();
		//this.disable();
		this.setActionID('edit');
	},
	
	del:function(e){
		if (!confirm ("閣下確定要刪除此資料嗎？")){
			return false;	
		}
		if (this.hasAuthorization('D')){
			$('buttonDelDiv').toggle();
		}
		if (this.hasAuthorization('E')){
			$('buttonEditDiv').toggle();
		}
		this.setActionID('del');
		this.submit(e);
	},
	
	disable:function(){
		this.setFrmDisable();
		this.obj.disable(); 
		if (this.withMultiFCK()){
			this.multiFCK.disable();
		}
	},
	
	enable:function(){
		this.obj.enable();
		if (this.withMultiFCK()){
			this.multiFCK.enable();
		}
		this.setFrmDisable();
	},
	
	setFrmData:function(result){
		var tmpName;
		var row=result.responseXML.getElementsByTagName('row')[0];
		if (!Object.isUndefined(row)){
			for (var k=0;k<row.childNodes.length;k++){
				//first 'if' check the node is exist or not, e.g. <onTopStartDate /> has no childNodes
				//second 'if' check is it a text node
				if ((row.childNodes[k].childNodes.length>0) && (row.childNodes[k].firstChild.nodeType==3)){
					tmpName=row.childNodes[k].nodeName;
					tmpValue=row.childNodes[k][_TEXT];
					this.setInputValue(tmpName,tmpValue);
				}
			}

			if (this.withFileUpload()){
				this.fileUpload.reset();
				var file=result.responseXML.getElementsByTagName('file');
				if(file.length>0){
					this.fileUploadLoadItem(file);			
				}
			}
		}
	},

	setInputValue:function(name,value){
		var index;
		//(isArray(FCKarr)) means there must a FCKeditor here
		//(typeof(FCKeditorAPI)!='undefined') the FCKeditor must be already exists (action=edit), otherwise set as a normal form is ok(action=add)
		if (this.withMultiFCK()){
			//(inArray(FCKarr,tmpName)) means this elements must be the FCKeditor element
			index=this.multiFCKarr.indexOf(name);
			if (index>=0){
				this.multiFCK.list[index].setContent(value);
			} else {
				Form.Element.setValue(name,value);					
			}
		} else {
			Form.Element.setValue(name,value);	
		}	
	},
	
	historyBack:function(){
		Element.history.go.delay(5, -2); 
		/*
		window.setTimeout(function() { 
			history.go(-2);
		},5000);
		*/
	},
	
	add:function(){
		Form.focusFirstElement(this.id);
		this.setAddFrmDefaultValue();
		this.enable();
	},
	
	detail:function(){
		this.getPageInitValue();
		if (this.hasAuthorization('D')){
			$('buttonDelDiv').toggle();
		}
		if (this.hasAuthorization('E')){
			$('buttonEditDiv').toggle();
		}
	},
	
	read:function(){
		this.getPageInitValue();
		this.disable(); 
		if (readCookie('groupID')<2){
			$('buttonDetailDiv').show();
		}
	},
	
	frmAction:function(){
		switch(this.actionID){
			case 'add':
				this.add();
				break;
			case 'detail':
				this.detail();		
				break;
			case 'read':
				this.read();
				break;
		}
	},
	
	setPageContent:function(){
		
	},
	
	setAuthorization :function(value){
		this.authorization=value;
	},
	
	hasAuthorization:function(action){
		return this.authorization.indexOf(action)>=0?true:false;
	},

	fileUploadDestroy:function(e){	
		this.fileUpload.destroy(this.obj,e);
	},

	fileUploadNewItem:function(e){
		obj=Event.element(e)
		this.fileUpload.newItem(obj);
		//IE cannot clear the <input type="file" value, so I should clear and insert it again by DOM and reset the onchange property
		Event.stopObserving(obj, 'change',this.eventUploadFileChange);
		obj.clear();
		obj.outerHTML=obj.outerHTML;
		this.eventFileUploadChange=this.fileUploadNewItem.bindAsEventListener(this);
		Event.observe(obj.id,'change',this.eventFileUploadChange);
	},
	
	fileUploadRemoveItem:function(err,msg,fileID,id,name,type,size,icon){
		this.fileUpload.removeItem(err,msg,fileID,id,name,type,size,icon);
	},
	
	fileUploadLoadItem:function(file){
		this.fileUpload.loadItem(file);
	},
	
	setParsByKey:function(){
		var pars=new Array();
		var inputElm='';
		for (var i=0;i<this.keys.length;i++){
			inputElm=this.obj[this.keys[i]]; 
			pars.push(this.keys[i] + '=' + encodeURIComponent($F(inputElm)));
		}
		return pars.join("&");
	},
	
	setParsByForm:function(){
		return Form.serialize(this.obj);
	},
	
	setKeys:function(){
		this.keys=arguments;
	}

}); 


var FileUpload = Class.create({
	initialize: function(id,elmID,url,recID,downloadUrl){
		this.frmID=id;
		this.frmObj=$(id);
		this.url=url;
		this.downloadUrl=downloadUrl;
		this.recID=recID;
		this.frmObj.action='';
		this.frmObj.method='post';
		//in IE, if you dynamically to change the "enctype" value, you must change the "encoding" value too,otherwise it will not work
		this.frmObj.enctype="multipart/form-data";
		this.frmObj.encoding="multipart/form-data";
		this.elmID=elmID;
		this.listID=this.elmID + '_list';
		this.counter=0;
		this.uploading=0;
		this.pars='';
		this.loadingIcon='<img src="' + _ROOT + '/__img/pro//loading_small2.gif" class="icon" />';
		this.ajaxListObj='';
		this.create();
	},
	
	setPars: function(val){
		this.pars=val;
		this.frmObj.action= this.url + '?' + this.pars;
	},
	
	create:function(){
		//The value of MAX_FILE_SIZE cannot be too large, otherwise it will show upload error(2), UPLOAD_ERR_FORM_SIZE
		this.frmObj.insert({top:'<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="' + _MAX_FILE_SIZE + '" />'});
		this.frmObj.insert({top:'<input type="hidden" id="fileID_list" name="fileID_list" value="" />'});
		$(this.elmID).insert({before:'<div id="' + this.listID + '" class="fileList"></div>'});
	},
	
	destroy:function(frmObj,e){
		//there are 2 ways to trigger the reset event,  or 
		//1.by user click reset button -> clear the server file data the has been submit
		//2.by system trigger reset after the form is successfully submited -> no need to clear file since the file handle in the 'add' action
		if (!Object.isUndefined(e)){
			var ajaxObj=new AjaxRequest('attReset');
			ajaxObj.setAsyn(true);
			ajaxObj.setPars('fileID_list='+encodeURIComponent(frmObj['fileID_list'].value));
			ajaxObj.setAjaxReqObj();
		}
		this.reset();
	},
	
	reset:function(){
		this.counter=0;
		$('fileID_list').value='';
		$(this.listID).update('');
		this.uploading=0;		
	},
	
	newItem:function(obj){
		//give a new name to the input element, because
		//1. reduce changes to the origional form elements
		//2. use the new name to update the checkbox list
		var orgID=obj.id;
		obj.setAttribute("id",orgID + '_' + this.counter);
		obj.setAttribute("name",orgID+ '_' + this.counter);
		this.uploading++;
		$(this.listID).insert({bottom:'<div id="' + obj.id + '_fileDesc" class="filedesc">' + this.loadingIcon + $(obj.id).value + '</div><iframe id="'+obj.id+'_hiddenIframe" name="'+obj.id+'_hiddenIframe" class="hiddenIframe" src="#"></iframe>'});
		this.frmObj.target=obj.id+'_hiddenIframe';
		this.setPars("id=" + encodeURIComponent(orgID + '_' + this.counter) + '&actionID=' +encodeURIComponent('upload'));
		this.frmObj.submit();
		//after submit the form, change back to the origional name
		obj.setAttribute("id",orgID);
		obj.setAttribute("name",orgID);
		this.counter++;
	},
	
	removeItem:function(err,msg,fileID,id,name,type,size,icon){
		this.frmObj['fileID_list'].value+='|'+fileID;		
		if (err == 0){
			$(id+'_fileDesc').innerHTML='<input type="checkbox" name="fileID[]" value="' + fileID + '" checked="checked" /><img src="' + icon + '" class="icon" /><a href="' + this.downloadUrl + '?fileID=' + fileID + '&actionID=manage" target="_blank">' + name + '</a><span>('+ type +')</span><span>' + size + '</span>';
		} else {
			$(id+'_fileDesc').firstChild.src=icon;
			$(id+'_fileDesc').firstChild.style.marginLeft='20px';
			$(id+'_fileDesc').innerHTML+= '<span class="err">上載時發生錯誤：' + err + ' ('+ msg +')</span>';
		}
		$(id+'_hiddenIframe').remove();
		this.uploading--;
	},
	
	isUploading:function(){
		return this.uploading>0?true:false;
	},
	
	loadItem:function(file){
		this.frmObj['fileID_list'].value='';
		var tmpName;
		var li = new Template('<div id="#{objID}_fileDesc" class="filedesc"><input type="checkbox" name="fileID[]" value="#{fileID}" checked="checked" /><img src="#{icon}" class="icon" /><a href="' + this.downloadUrl + '?fileID=#{fileID}&actionID=manage" target="_blank">#{name}</a><span>(#{type})</span><span>#{size}</span></div>'); 
		var iconValue;
		this.code='';
		for(var i=0;i<file.length;i++){
			var filei = file.item(i);
			iconValue=filei.childNodes[0][_TEXT]!=''?'accept':'delete';
			source={objID: this.elmID + "_" + this.counter,fileID:filei.childNodes[0][_TEXT], name:filei.childNodes[1][_TEXT], type:filei.childNodes[2][_TEXT], size:filei.childNodes[3][_TEXT], icon:filei.childNodes[5][_TEXT]};
			this.code+=(li.evaluate(source)) + "\r\n";
			this.frmObj['fileID_list'].value+='|' + filei.childNodes[0][_TEXT];	
			this.counter++;
		}
		$(this.listID).innerHTML=this.code;
	}
});	




var RespMsg = Class.create({
	initialize: function(id,ele,position){
		this.id=id;
		this.msg='';
		this.obj=$(this.id);
		
		this.template='\
			<div id="#{id}" style="display:none;" class="respMsg">\
				<div class="roundCorner">\
					<b class="xtop"><b class="xb1"></b><b class="xb2"></b><b class="xb3"></b><b class="xb4"></b></b>\
					<div id="#{id}_content" class="xboxcontent"><a href="#" onclick="return false;" id="#{id}_str"></a></div>\
					<b class="xbottom"><b class="xb4"></b><b class="xb3"></b><b class="xb2"></b><b class="xb1"></b></b>\
				</div>\
			</div>\
		';
		this.create(ele,position);
	},
	
	create:function(ele,position){
		var myTemplate=new Template(this.template);
		var arr={id:this.id};
		var str="$(ele).insert({" + position +":'" + myTemplate.evaluate(arr) + "'});";
		eval(str);
	},
	
	setContent:function(str){
		$(this.id + "_str").update(str);
	},
	
	show:function(){
		$(this.id).show();
		$(this.id+'_str').focus();
		$(this.id+'_str').blur();
		Effect.Pulsate(this.id);	
	},
	
	hide:function(){
		$(this.id+'_str').innerHTML='';
		$(this.id).hide();
	},
	
	fade:function(){
		Effect.Fade(this.id);		
	}
	
});	