var DOCUMENT_FORMS=new Array(),
FORM_TEMPLATES=
	{
		cid:{
				f_type:"text",
				f_rule:/^c|с?\d+$/,
				f_min:1
			},
		fio:{
				f_type:"text",
				f_min:5
			},
		login:{
				f_type:"text",
				f_rule:/^[a-zA-Z0-9._]+$/,
				f_min:3
			},
		jur_status:{
				f_type:"select",
				f_values:new Array(1,2)
			},
		sex:{
				f_type:"radio",
				f_values:new Array('m','f')
			},
		smoking:{
				f_type:"radio",
				f_values:new Array(0,1,2)
			},
		mail:{
				f_type:"text",
				f_rule:/^[a-zA-Z0-9._\-]+\@[a-zA-Z0-9._\-]+\.\w{2,4}$/,
				f_min:6
			},
		phone:{
				f_type:"text",
				f_rule:/\d/,
				f_min:6
			},
		pwd:{
				f_type:"password",
				f_rule:/[a-zA-Z0-9._\-]+/,
				f_min:6
			},
		pwd2:{
				f_type:"password",
				f_rule:/[a-zA-Z0-9._\-]+/,
				f_min:6
			},
		file_img:{
				f_type:"file"
			},
		date:{
				f_type:"text",
				f_rule:/^\d{1,2}\.\d{1,2}\.\d{2,4}$/,
				f_min:6
			},
		hour:{
				f_type:"text",
				f_rule:/\d*/,
				f_min:1
			},
		minute:{
				f_type:"text",
				f_rule:/\d*/,
				f_min:1
			},
		city:{
				f_type:"text",
				f_min:1
			},
		street:{
				f_type:"text",
				f_min:1
			},
		house:{
				f_type:"text",
				f_min:1,
				f_rule:/\d*/
			},
		subway:{
				f_type:"text",
				f_min:1
			}
	},
FULL_PARAMS=new Array("f_type","f_template","f_rule","f_min","f_max","f_values","f_errblock","f_addcheck","f_onclick","f_skip","f_onfocus")

function DOCUMENT_FORM(formName,formObject,formFields,formSubmiting,formChecking,iframeSrc,iframeHandler){
	if (!document.forms[formName] || !formFields) return false
	
	DOCUMENT_FORMS[DOCUMENT_FORMS.length]=this
	this.form=document.forms[formName]
	this.form.obj=this
	this.fields=formFields
	this.suggestedFields=[]
	this.result={}
	this.iframeSrc=iframeSrc?iframeSrc:"/cssjs/iframe.php"
	this.iframeHandler=iframeHandler
	this.checkRes=false
	this.iframeForm=''
	this.formObject=formObject
	
	
	this.fileSeeking=function(){
		var fields=this.fields,
			form=this.form,
			res=false
		for (fName in fields){
			var fParam=fields[fName],
				fieldData=this.getFieldData(fParam)
				
			if (fieldData.f_type=='file'){
				var f=$id(fName)||form[fName],
					par=$id(fName+"_container")
					par.innerHTML='<iframe src="'+this.iframeSrc+'?handler='+this.iframeHandler+'" id="iframe_form" name="iframe_form" frameborder="0"/>'
					res=true
				}
			}
			
		return res
		}
	
	
	
	this.putEvents=function(){
		var fields=this.fields,
			form=this.form
		for (fName in fields){
			 var f=$id(fName)||form[fName],
			 	fData=fields[fName]
			 if (!f) break
			 var onclickFunction=function(){
				 var errBlock=$id(this.id+"_error")
				 if (errBlock){
					 errBlock.className='hidden'
					 errBlock.innerHTML=''
				 	}	
			 	} 
			 EVENTS.append(f,["onclick","onkeypressed"],onclickFunction)
			 if (fData.f_onclick && typeof fData.f_onclick=="function") {
				 EVENTS.append(f,["onclick","onkeypressed"],fData.f_onclick);
			 	}
			if (fData.f_onfocus && typeof fData.f_onfocus=="function") {
				 EVENTS.append(f,["onfocus"],fData.f_onfocus);
			 	}
			 if (fData.f_suggest){
				 this.suggestedFields.push(f)
				 
				 SUGGEST_EXT.append(f,fData.f_suggest)
			 	}

			}
		}
	
	
	this.checking=function()
	{
		var fields=this.fields,
			form=this.form,
			res=true,
			toFocus="";
		
		for (fName in fields)
		{
			
			var fParam=fields[fName],
				f=$id(fName)||form[fName]			
			
			if (f.disabled) continue
			if (!f) break
			if (fParam.f_type=="radio") continue;
			var fVal=f.value,
				errBlock=$id(fParam.errblock)||$id(fName+"_error");
			
			f.obj=this
			
			
			fParam.err=this.checkField(fVal,fParam)
			
			
			if (!fParam.err && fParam.f_template=="pwd2" && fName=="userpwd2" && fields.userpwd && form.userpwd.value!=form.userpwd2.value)
				fParam.err="значение не совпадает"
			
			if (fParam.err) {
				res=false
				if (this.writeError(errBlock,fParam.err))
					/* f.onclick=this.clearErrorByClick
					f.onkeypress=this.clearErrorByClick */
					EVENTS.append(f,["onclick","onkeypress"],this.clearErrorByClick)
					
				if (!toFocus) toFocus=f
			} else this.clearError(errBlock)
			
		}
		if (toFocus && toFocus.focus && typeof toFocus.focus=="function") {
			toFocus.focus()
			}

		return res
	}
	
	this.preSubmiting=function(){
		
		var submitRes,
			obj=this.obj
		if (obj.isSuggesting()) {
			return false
			}
		obj.checkRes=obj.checking()
		
		if (obj.checkRes)
			var timerID=setTimeout(obj.formObject+'.doSubmit()',200)
			
		return false

		}
	this.doSubmit=function(){		
		if (this.checkRes)
			this.submiting.call(this.form);
		return false;
		}
	
	this.submiting=function(){
		var submitRes,
			form=this.obj,
			formHTML=form.form,
			formFields=form.fields,
			res=false
			
		if (formChecking)
			this.checkRes=$function(formChecking)
		else
			this.checkRes=form.checking()
		
		
		
		if (!this.checkRes)
			return false
		
		if (this.obj.hasFile)
			{
			var iframeName="iframe_form"
			iframeForm=window.frames[iframeName].iframe_form?window.frames[iframeName].iframe_form
					:
					document.getElementById(iframeName).contentDocument.forms[0]
					
			formFields['R']={f_type:"controlField"}
			
			var iFields=""
			for (var fName in formFields){

				var f=$id(fName)||formHTML[fName]
				if (!f || form.fields[fName].f_type=='file') break
				var fVal=f.value
				//if (!iframeForm[fName])
					iFields+='<input type="hidden" value="'+fVal+'" name="'+fName+'"/>'
								
				
				}
				
			iFields+='<input type="hidden" value="'+(formHTML['R'].value)+'" name="R"/>'
			var iframePaste=window.frames[iframeName]['paste']?window.frames[iframeName]['paste']:
				document.getElementById(iframeName).contentDocument.getElementById("paste")
			iframePaste.innerHTML=iFields
			//iframeForm.innerHTML+=iFields
			//alert(iframeForm.innerHTML);
			iframeForm.submit()
			
			
			return false
			}
		else {		
			form.getResult()
			//var params=new Array()
			//params[0]=form.result
			if (formSubmiting) submitRes=form.userSubmit?form.userSubmit():$function(formSubmiting,form.result)					
			}


	return false
	}
	
	this.checkField=function(val,params){
		
		var fullData=this.getFieldData(params),
			res=''
		
		if (fullData.f_skip) return res;
			
		if (
				(fullData.f_max && val.length>fullData.f_max) ||
				(fullData.f_min && val.length<fullData.f_min) ||
				(fullData.f_rule && val.search(fullData.f_rule)<0 && !(fullData.f_min==0 && val==0)) ||
				(fullData.f_values && !in_array(fullData.f_values,val))
				
			)	res='некорректное значение'
		
		if (fullData.f_addcheck && res==''){
			for (var i in fullData.f_addcheck){
				var addCheckFunc=fullData.f_addcheck[i]
					res=$function(addCheckFunc,[val])
				}		
			}
		return res

		}
	
	this.getFieldData=function(params){
		var fieldData={}
		for (var i in FULL_PARAMS)
			fieldData[FULL_PARAMS[i]]=(params[FULL_PARAMS[i]]!=null)?params[FULL_PARAMS[i]]:null
		
		if (FORM_TEMPLATES[fieldData.f_template])
			{
				var templateData=FORM_TEMPLATES[fieldData.f_template]
				for (t in templateData) {
					if (fieldData[t]==null) fieldData[t]=templateData[t]
					}
			}
		return fieldData
		}
	
	this.writeError=function(errBlock, errText)
	{
		errBlock=$id(errBlock)
		if (!errBlock) return false
		errBlock.className="error showed"
		errBlock.innerHTML=errText
		return true
	}
	
	this.clearError=function (errBlock)
	{
		errBlock=$id(errBlock);
		if (!errBlock){
			return false;
			}
		errBlock.innerHTML="";
		errBlock.className="error hidden";
		return false;
	}
	
	this.clearErrorByClick=function (e)
	{
		var form=this.obj,
		errBlock=$id(form.fields[this.id].errblock)||$id(this.id+'_error')
		form.clearError(errBlock)
		/* if (this.onclick) this.onclick=null
		if (this.onkeypressed) this.onkeypressed=null */
	}
	
	this.getResult=function(){
		var fields=this.fields,
			form=this.form
		
		for (fName in fields){
			var fParam=fields[fName],
				fieldData=this.getFieldData(fParam),
				f=$id(fName)||form[fName];
			
			if (!f) {
				break;
				}
			/* if (fParam.f_type=="textarea") {
				this.result[fName]=NtoBR(f.value)
				} */
			this.result[fName]=f.value;
			if (fieldData.f_type=="radio"){
				this.result[fName]=getRadioValue(fName);
				}
			if (this.result[fName]==undefined
				|| this.result[fName]==null) {
				this.result[fName]==''
				}
			//alert (fName+"="+f.value)
			}
		return this.result
	}
	
	this.isSuggesting=function(){
		var res=0
		for (var i=0;i<this.suggestedFields.length; i++){
			var f=this.suggestedFields[i]
			if (f.suggestData.block)
				res++
				
			}
		return res
		}
	
	
		this.hasFile=this.fileSeeking()
		this.putEvents()
		this.form.onsubmit=this.preSubmiting
		//EVENTS.append(this.form,"onsubmit",this.preSubmiting)
	
	
//	this.form.onkeyup=this.checking
	return false
	
}


/* SUGGEST
====================================*/

	var SUGGEST_EXT={
		pressTimer:false,
		settings:{
			itemStateClasses:["passive","active"],
			pressTime:200
			},
		append:function(f,fData){
			f=$id(f)
			if (!f) {
				return false;
				}
			
			
			f.suggestObj=this;
			f.suggestData=fData;
			f.suggestControl=this.suggestControl;
			f.suggestData.prevValue=f.value;		
			
			
			if (!fData.isPseudo){
				this.suggestControl.buildPseudoInputContainer(f);
				var pseudoInputContainer=f.suggestData.pseudoInputContainer,
					pseudoInput=f.suggestData.pseudoInput;
				EVENTS.append(f,["onfocus","onclick"],this.suggestControl.focusPseudoInput);
				this.append(pseudoInput,concatObjects(fData,{isPseudo:true,mainField:f}));
				}
			else{
				EVENTS.append(f,["onkeyup"],this.doSuggest);
				EVENTS.append(f,["onkeydown"],this.catchKey);
				}
			
			
			return false;
			},
		catchKey:function(e){
			if (this.suggestData.isPseudo){
				this.suggestData.mainField.suggestObj.catchKey.call(this.suggestData.mainField,e);
				
				return false;
				}
			else{
				}

			var keyPressed=getKeyPressed(e)
			this.suggestData.symbolPressed=false
			this.suggestData.mustKillBlock=false
			SUGGEST_EXT.startPressTimer(this)
			switch (keyPressed){
				case "ENTER":
					this.suggestControl.getValue.call(this)
					this.suggestData.mustKillBlock=true
					break;
				case "ARROWUP":
					this.suggestControl.moveHighLight.call(this,-1)
					break;
				case "ARROWDOWN":
					this.suggestControl.moveHighLight.call(this,1);					
					break;
				case "ESC":
					this.suggestControl.killBlock.call(this,true)
					break;
				case "TAB":
					this.suggestControl.killBlock.call(this,true)
					return false
					break;
				case "HOME":
					return false
					break;
				case "END":
					return false
					break;
				default:
					this.suggestData.symbolPressed=true
					break;
				}
			return false
			},
			
		doSuggest:function(e){
			if (this.suggestData.isPseudo){
				this.suggestData.mainField.suggestObj.doSuggest.call(this.suggestData.mainField,e);
				return false;
				}
			var value=this.suggestData.pseudoInput.value;
			
			if (this.suggestData.mustKillBlock){
				this.suggestData.mustKillBlock=false
				this.suggestControl.killBlock.call(this,true)
				
				//this.suggestControl.hidePseudoInputContainer.call(this);
				return false
				}

				

			var data=this.suggestData,
				params={
					todo:data.todo,
					value:value,
					target:this.id,
					resultformat:"xml"
				}
			if (data.prepare){
				params=concatObjects(params,$function(data.prepare,this))
				}

			if (this.suggestData.symbolPressed && this.suggestData.prevValue!=value && !SUGGEST_EXT.pressTimer){
				//here must be analyse of neccessity of ajax request
				setAjaxRequest("POST", data.handler, getParamString(params), this.suggestObj.catchResult)
				}
			else {
				//alert("1."+this.suggestData.symbolPressed+" 2."+(this.suggestData.prevValue!=value)+" 3."+(!SUGGEST_EXT.pressTimer))
				//this.suggestObj.doSuggest.call(this)
				//alert("fuckedup");
				}
				
			
			return false
			},
			
		catchResult:function(reqXML){			
			if (!reqXML) {
				return false;
				}
			var xmlData=parseLineXML(reqXML),
				headData=xmlData.head,
				bodyData=xmlData.body,
				f=$id(headData.target);
			if (!headData.request) {
				return false;
				}
			var fieldValue=f.suggestData.pseudoInput.value;
			
			if (!f || !fieldValue || f.suggestData.pseudoInputContainer.isHidden) {
				return false;
				}
			f.suggestData.items=bodyData;
			f.suggestControl.killBlock.call(f);
			if (bodyData.length!=0 && (fieldValue.search(headData.request)==0)){
				f.suggestControl.refreshBlock.call(f,bodyData);
				}
			return false;
			},
			
		suggestControl:{
			
			buildBlock:function(){
				
				var block=setChild(document.body,this.id+"_suggest","suggest","DIV"),
					blockList=setChild(block,block.id+"_list","","UL"),
					pos=getWhereIs(this)
				
				setPosition(block,{left:pos.left,top:pos.top+this.offsetHeight})
				block.style.width=this.offsetWidth-2+"px"
				blockList.highLighted=null
				blockList.itemBlocks=[]
				block.list=blockList
				this.suggestData.block=block
				//EVENTS.append(this,"onblur",this.suggestControl.killBlockByBlur)
				//this.suggestControl.buildPseudoInputContainer.call(this)
				return block
				},
			buildPseudoInputContainer:function(f){
				if (f.suggestData.pseudoInputContainer)
					return false;
				var container=setChild(document.body,f.id+"_pseudo-input-container","pseudo-input-container hidden","DIV"),
					pseudoInput=setChild(container,f.id+"_pseudo-input",null,"INPUT"),
					pos=getWhereIs(f);
				/* container.style.width=f.offsetWidth+"px";
				container.style.height=30+"px";
				setPosition(container,{left:pos.left,top:pos.top-32}) */
				pseudoInput.value=f.value;
				EVENTS.append(pseudoInput,"onblur",f.suggestControl.killBlockByBlur)
				//pseudoInput.focus();
				f.suggestData.pseudoInput=pseudoInput;
				f.suggestData.pseudoInputContainer=container;
				f.suggestControl.refreshPseudoInputContainer.call(f);
				//testObject(pos);
				return container;
				},
			refreshPseudoInputContainer:function(){
				var piContainer=this.suggestData.pseudoInputContainer,
					pseudoInput=this.suggestData.pseudoInput,
					pos=getWhereIs(this);				
				piContainer.style.width=this.offsetWidth+"px";
				piContainer.style.height=30+"px";
				setPosition(piContainer,{left:pos.left,top:pos.top-32});
				},
			focusPseudoInput:function(){
				
				this.suggestControl.refreshPseudoInputContainer.call(this);

				var piContainer=this.suggestData.pseudoInputContainer,
					pseudoInput=this.suggestData.pseudoInput;
					
				//this.value="";
				toggleClass(piContainer,1);
				piContainer.isHidden=false;
				
				if (pseudoInput) {
					if (pseudoInput.focus){
						pseudoInput.focus();
						}
					moveCaretToEnd(pseudoInput);
					}
				this.suggestData.symbolPressed=true
				this.suggestObj.doSuggest.call(this)
				
				},
			hidePseudoInputContainer:function(){
				var piContainer=this.suggestData.pseudoInputContainer,
					pseudoInput=this.suggestData.pseudoInput;
				if (pseudoInput)
					pseudoInput.blur();
				if (piContainer)
					toggleClass(piContainer,0);
				piContainer.isHidden=true;
				
				},
			showPseudoInputContainer:function(){
				var piContainer=this.suggestData.pseudoInputContainer
				if (piContainer)
					toggleClass(piContainer,1);
				},
			refreshBlock:function(items){
				
					//items=this.suggestData.items
				var value=this.suggestData.pseudoInput.value;
				if (!items || !value)
					return false;
				if (items.length==1 && items[0].value.toLowerCase()==value.toLowerCase()) {
					return false;
					}
				if (!this.suggestData.block) this.suggestControl.buildBlock.call(this)
				var block=this.suggestData.block,
					blockList=block.list
				for (var i=0;i<items.length;i++){
					var Item=items[i],
						itemBlock=setChild(blockList,blockList.id+"_item"+i,"","LI","<span>"+Item.value+"</span>");
					itemBlock.itemNum=i
					itemBlock.itemData=Item
					itemBlock.acceptorField=this
					this.suggestData.block.list.itemBlocks[i]=itemBlock
					onmouseoverFunction=function(){
						var hlPrev
						this.acceptorField.suggestData.isMouseOver=true
						hlPrev=this.acceptorField.suggestData.block.list.highLighted;
						if (hlPrev){
							toggleClass(hlPrev,0,SUGGEST_EXT.settings.itemStateClasses)
							}
						
						this.acceptorField.suggestData.block.list.highLighted=this
						toggleClass(this,1,SUGGEST_EXT.settings.itemStateClasses)
						}
					onmouseoutFunction=function(){					
						this.acceptorField.suggestData.isMouseOver=false
						toggleClass(this,0,SUGGEST_EXT.settings.itemStateClasses)
						this.acceptorField.suggestData.block.list.highLighted=null
						}
					onclickFunction=function(){
						this.acceptorField.suggestControl.getValue.call(this.acceptorField);
						this.acceptorField.suggestControl.killBlock.call(this.acceptorField);
						this.acceptorField.suggestControl.hidePseudoInputContainer.call(this.acceptorField);
						//this.acceptorField.focus()
						return false
						}
					EVENTS.append(itemBlock,"onmouseover",onmouseoverFunction)
					EVENTS.append(itemBlock,"onmouseout",onmouseoutFunction)
					EVENTS.append(itemBlock,"onclick",onclickFunction)
					//this.suggestControl.moveHighLight.call(this,-1)
					//itemBlock.onclick=onclickFunction
					
					}
				return false
				},
				
			killBlock:function(needHidePseudoContainer){
				if (needHidePseudoContainer){
					this.suggestControl.hidePseudoInputContainer.call(this);
					}
				if (!this.suggestData.block)
					return false;				
				unsetChild(this.suggestData.block)
				this.suggestData.block=null
				

				return false
				},
			killBlockByBlur:function(){
				//this.suggestControl.killBlock.call(this)
				
				if (this.suggestData.mainField.suggestData.isMouseOver) {					
					/* if (this.focus){
						this.focus();
						} */	
					
					this.suggestData.mainField.isMouseOver=false
					}
				else{
					
					this.suggestControl.killBlock.call(this.suggestData.mainField,true);
					}
				return false
				},
				
			moveHighLight:function(direction){
				var value=this.suggestData.pseudoInput.value;
				if (!this.suggestData.block){
					//return
					if (value)
						this.suggestControl.refreshBlock.call(this)
					return false;
					}
				var hlPrev,
					hlPrevNum=-1;
				hlPrev=this.suggestData.block.list.highLighted;
				if (hlPrev){
					toggleClass(hlPrev,0,SUGGEST_EXT.settings.itemStateClasses)
					hlPrevNum=hlPrev.itemNum
					}
				var hlNewNum=hlPrevNum+direction,
					hlMinNum=0,
					hlMaxNum=this.suggestData.block.list.itemBlocks.length-1,
					hlNew
					
					if (hlNewNum<hlMinNum) hlNewNum=hlMaxNum
					if (hlNewNum>hlMaxNum) hlNewNum=hlMinNum
				hlNew=this.suggestData.block.list.itemBlocks[hlNewNum];
				if (hlNew){
					toggleClass(hlNew,1,SUGGEST_EXT.settings.itemStateClasses)
					this.suggestData.block.list.highLighted=hlNew
					}
				this.suggestControl.getValue.call(this)
				return false;
				},
			getValue:function(){
				if (this.suggestData.block){
					var hl=this.suggestData.block.list.highLighted;
					if (hl && hl.itemData){
						this.value=hl.itemData.value;
						}
						
						if (this.suggestData.past && hl && hl.itemData){
							this.suggestData.past.call(this,hl.itemData)
							}
					}

				return false
				}			
			},
			startPressTimer:function(f){				
				if (this.pressTimer) this.clearPressTimer()
				//alert (f)
				if (f) this.lastSuggestedField=f
				else {
					this.lastSuggestedField=false;
					return false;
					}
				this.pressTimer=setTimeout('SUGGEST_EXT.clearPressTimer(); if(SUGGEST_EXT.lastSuggestedField) SUGGEST_EXT.doSuggest.call(SUGGEST_EXT.lastSuggestedField);',this.settings.pressTime);
				return false;
				},
			clearPressTimer:function(){				
				clearTimeout(this.pressTimer)
				this.pressTimer=false
				}
			
		
		}
