var jwebForm={
	/********************************************/
	/** GENERAL *********************************/
	/********************************************/
	submit:function(formId,rn,val,strConfirm){
		// get form object
		var form=document.getElementById(formId);
		if(!form||!form.tagName){
			return;
			}
		// confirm
		if(strConfirm&&!confirm(strConfirm)){
			return;
			}
		// submit once
		if(!form.getAttribute('jwebformmultiplesubmit')){
			var anSubmitted='jwebformsubmitted';
			if(form.getAttribute(anSubmitted)){
				alert("Av säkerhetsskäl går denna\nbegäran bara att göra en gång,\nuppdatera sidan för att börja om!");
				return;
				}
			form.setAttribute(anSubmitted,1)
			}
		// show being submitted
		var target=form.getAttribute('target');
		if(!target||(/_(self|parent|top)/).test(target)){
			setTimeout(function(){jweb.tip.showProgress()},100);
			}
		// add submit hidden
		if(rn){
			this.addHidden(form,rn,val);
			}
		// add rte
		this.rte.prepareForSubmit();
		// submit
		form.submit();
		},
	submitOnEnter:function(evt,formId){
		try{if(jweb.event.get().keyCode==13){
			this.submit(formId);
			}}
		catch(e){}
		},
	addHidden:function(form,rn,val){
		var hdn=document.createElement('input');
			hdn.type='hidden';
			hdn.name=rn;
			hdn.value=val;
		form.appendChild(hdn);
		},
	maxLength:function(o,d){
		if(o.value.length>d){
			o.value=o.value.substr(0,d);
			alert('Max '+d+' tecken');
			}
		},
	/********************************************/
	/** AUTOCOMPLETE ****************************/
	/********************************************/
	autocomplete:{
		/**********************/
		_data:[],
		_inp:0,
		_inpfocus:0,
		_sel:0,
		_selfocus:0,
		_str:0,
		/**********************/
		init:function(id,source,isurl){
			var inp,self=this;
			this._data[id]={source:source,isurl:isurl};
			inp=document.getElementById(id);
			inp.onkeyup=function(event){self._keyup(event)};
			inp.onfocus=function(){self._inpfocus=1;};
			inp.onblur=function(){self._inpfocus=0;self._blur();};
			},
		/**********************/
		_keyup:function(e){
			e=jweb.event.get();
			if(this._sel&&this._sel.options.length){
				if(40==e.keyCode){ // down
					this._sel.options[0].selected=true;
					this._sel.focus();
					return;
					}
				if(38==e.keyCode){ // up
					this._sel.options[this._sel.options.length-1].selected=true;
					this._sel.focus();
					return;
					}
				}
			this._close(0);
			if(13==e.keyCode)return; // esc
			this._str=e.target.value.toLowerCase();
			this._inp=e.target;
			if(!this._str.length)return;
			var data=this._data[e.target.id];
			if(data.isurl){
				var self=this,url=data.source+this._str;
				jweb.ajax.post(url,self._open,1);
				}
			else{
				this._open(data.source);
				}
			},
		_blur:function(){
			var self=this;
			setTimeout(function(){
				if(!self._inpfocus&&!self._selfocus){
					self._close(0);
					}
				},200);
			},
		_open:function(csv){
			var self=jwebForm.autocomplete; // ajax pajjar scopet
			csv=csv.split(',');
			if(!self._sel){
				self._sel=document.createElement('SELECT');
				self._sel.style.position='absolute';
				self._sel.style.height='100px';
				self._sel.multiple=true;
				self._sel.onkeydown=function(event){
					if(13==jweb.event.get().keyCode){
						self._close(1);
						}
					};
				self._sel.onclick=function(){self._close(1);};
				self._sel.onfocus=function(){self._selfocus=1;};
				self._sel.onblur=function(){self._selfocus=0;self._blur();};
				document.body.appendChild(self._sel);
				}
			var i=-1,j=csv.length,hit=0,opt;
			var data=self._data[self._inp.id];
			while(++i<j){
				if(!csv[i].length)continue;
				if(csv[i]==self._str)continue;
				if((csv[i].indexOf(self._str)!==0)&&!data.isurl)continue; // sorterad (hårdkodad) lista och ej match
				opt=document.createElement('OPTION');
				opt.value=csv[i];
				opt.innerHTML=csv[i];
				self._sel.appendChild(opt);
				hit=1;
				}
			if(hit){
				var s=jweb.xy.size(self._inp);
				var p=jweb.xy.pos(self._inp);
				self._sel.style.top=(p.y+s.y)+'px';
				self._sel.style.left=(p.x)+'px';
				self._sel.style.visibility='visible';
				self._sel.selectedIndex=-1;
				}
			},
		_close:function(transfer){
			if(!this._sel){
				return;
				}
			if(transfer){
				var tmp=this._sel.selectedIndex;
				if(tmp>-1){
					this._inp.value=this._sel.options[tmp].value;
					}
				this._inp.focus();
				}
			while(this._sel.firstChild){
				this._sel.removeChild(this._sel.firstChild);
				}
			this._sel.style.visibility='hidden';
			}
		},
	/********************************************/
	/** TEXTAREA EXPAND *************************/
	/********************************************/
	textareaExpand:function(o){
		var an='jwebforminitialheight';
		var ih=o.getAttribute(an);
		if(!ih){
			ih=parseInt(o.style.height);
			o.setAttribute(an,ih);
			}
		var ch=o.scrollHeight;
		o.style.height=((ch<ih)?ih:ch)+'px';
		},
	/********************************************/
	/** PASSWORD STRENGTH ***********************/
	/********************************************/
	passwordStrength:function(o,id){
		var l=o.value.length;
		var uc=0,lc=0,oc=0,d=0,ord,i=-1;
		while(++i<l){
			ord=o.value.charCodeAt(i);
			if(ord>47&&ord<58) d++;
			else if(ord>64&&ord<91) uc++;
			else if(ord>96&&ord<123) lc++;
			else oc++;
			}
		var types=uc?1:0;
			types+=lc?1:0;
			types+=d?1:0;
			types+=oc?1:0;
		var p=20+(types*21);
		if(l<7){
			p-=(6-l)*11;
			}
		else{
			p+=(l-6)*8;
			}
		p=(p<0)?0:((p>100)?100:p);
		document.getElementById(id).innerHTML='Ungefärlig styrka '+p+'%';
		},
	/********************************************/
	/** SELECT FILTER ***************************/
	/********************************************/
	selectFilterLib:{},
	selectFilterKeyup:function(i,s){
		var selecteds=[];
		var j,k,l,o,os=this.selectFilterLib[s.id];
		var vals=i.value.replace(/(^,+|,+$)/g,'').replace(/,+/g,',').toLowerCase().split(',');
		for(j=0;j<s.options.length;j++){
			if(s.options[j].selected){
				selecteds.push(s.options[j].value);
				}
			}
		s.innerHTML=''
		for(l=0;l<vals.length;l++){
			for(j=0;j<os.length;j++){
				o=os[j].cloneNode(true);
				if(!vals[l]||(o.innerHTML.toLowerCase().indexOf(vals[l])>-1)){
					for(k=0;k<selecteds.length;k++){
						if(o.value==selecteds[k]){
							o.selected=true;
							break;
							}
						}
					s.appendChild(o);
					}
				}
			}
		},
	selectFilterInit:function(ids,idi){
		var s=document.getElementById(ids);
		var i=document.getElementById(idi);
		this.selectFilterLib[ids]=s.cloneNode(true).options;
		if(s.style.width){
			var w=parseInt(s.style.width);
			}
		else{
			var w=jweb.xy.size(s).x+16;
			}
		if(w<100){
			w=100;
			}
		s.style.width=w+'px';
		i.style.width=(w-8)+'px'; // 4padding + 4border
		i.onkeyup=function(){
			jwebForm.selectFilterKeyup(this,s);
			}
		if(i.value){
			this.selectFilterKeyup(i,s);
			}
		},
	selectStep:function(id,dir,submit){
		var s=document.getElementById(id);
		var i=s.selectedIndex;
		if((i==0)&&(dir<0)){ // left step on first
			return;
			}
		if((i==(s.options.length-1))&&(dir>0)){ // right step on last
			return;
			}
		s.options[i+dir].selected=true;
		if(submit){
			this.submit(s.form.id);
			}
		},
	/********************************************/
	/** CHECKBOX SHIFTSELECT ********************/
	/********************************************/
	_cbCache:[],
	_cbIndexLast:-1,
	cbSel:function(e){
		e=jweb.event.get();
		var cb=e.target,an='jwebformcbindex';
		if((cb.tagName=='INPUT')&&(cb.type=='checkbox')){
			var index=parseInt(cb.getAttribute(an));
			if(!this._cbCache.length){
				var tmp=document.getElementsByTagName('INPUT'),i=tmp.length,j=0;
				while(--i>-1){
					if(tmp[i].type=='checkbox'){
						tmp[i].setAttribute(an,j);
						this._cbCache[j]=tmp[i];
						if(tmp[i]==cb)index=j; // ?
						j++;
						}
					}
				}
			if(e.shiftKey&&(this._cbIndexLast>-1)){
				var checked=!!this._cbCache[this._cbIndexLast].checked;
				var inc=(this._cbIndexLast>index)?1:-1;
				for(var i=index;;i+=inc){
					this._cbCache[i].checked=checked;
					if(i==this._cbIndexLast)break;
					}
				}
			this._cbIndexLast=index;
			}
		},
	/********************************************/
	/** TABLE ***********************************/
	/********************************************/
	table:{
		_anIsOpened:'jwebformtableisopened',
		_limBox:0,
		_limBoxTimeout:0,
		init:function(data){
			var tab=document.getElementById(data.id),self=this;
			tab.onclick=function(event){self._click(event,data)};
			var r,c,td;
			for(r=0;r<tab.rows.length;r++){
				for(c=0;c<tab.rows[r].cells.length;c++){
					td=tab.rows[r].cells[c];
					if(this._isEditable(td,data)){
						td.style.cursor='pointer';
						td.setAttribute('jwebtip','Redigerbar<br>'+(td.getAttribute('jwebtip')||''));
						}
					}
				}
			},
		_click:function(e,data){
			e=jweb.event.get();
			var td=e.target;
			while(td&&('TD'!=td.tagName)){
				td=td.parentNode;
				}
			if(!this._isEditable(td,data))return;
			var self=this;
			var rawVal=td.innerHTML;
			var col=data.cols[td.cellIndex];
			var rn=data.rn
				+'['+td.parentNode.getAttribute(data.an)+']'
				+'['+col.name+']';
			td.innerHTML='';
			td.setAttribute(this._anIsOpened,1);
			if(col.options){
				// options
				var sel=document.createElement('SELECT'),opt;
				td.appendChild(sel);
				sel.focus();
				sel.multiple=true;
				for(var i=0;i<col.options.length;i++){
					opt=document.createElement('OPTION');
					opt.value=col.options[i];
					opt.innerHTML=col.options[i];
					sel.appendChild(opt);
					opt.selected=((new RegExp('(^|,)'+opt.value+'(,|$)','i')).test(rawVal));
					}
				if(col.multiple){
					sel.size=col.options.length;
					sel.name=rn+'[]';
					}
				else{
					sel.multiple=false;
					sel.name=rn;
					}
				}
			else{
				// text
				var ta=document.createElement('TEXTAREA');
				ta.name=rn;
				ta.value=rawVal.replace(/&amp;/ig,'&').replace(/&lt;/ig,'<').replace(/&gt;/ig,'>');
				ta.onkeyup=function(){
					self._taSize(this);
					self._taLimit(this,col.max);
					};
				ta.id='jwebFormTable';
				td.appendChild(ta);
				ta.focus();
				this._taSize(ta);
				}
			},
		_isEditable:function(td,data){
			if(!td)									return 0;
			if('TD'!=td.tagName)					return 0;
			if(!td.parentNode.getAttribute(data.an))return 0;
			if(!data.cols[td.cellIndex])			return 0;
			if(td.getAttribute(this._anIsOpened))	return 0;
			return 1;
			},
		_taSize:function(ta){
			ta.style.width='100%';
			ta.style.height='100%';
			ta.scrollWidth; // not my fault
			ta.scrollHeight;
			ta.style.width=ta.scrollWidth+'px';
			ta.style.height=ta.scrollHeight+'px';
			},
		_taLimit:function(ta,lim){
			if(!lim){
				return;
				}
			if(!this._limBox){
				this._limBox=document.createElement('DIV');
				this._limBox.id='jwebFormTableLimBox';
				document.body.appendChild(this._limBox);
				}
			
			clearTimeout(this._limBoxTimeout);
			
			var p=jweb.xy.pos(ta);
			var s=jweb.xy.size(ta);
			var self=this;
			
			this._limBox.style.visibility='visible';
			this._limBox.style.top=(p.y+s.y)+'px';
			this._limBox.style.left=(p.x)+'px';
			this._limBox.className='';
			
			if(ta.value.length>=lim){
				ta.value=ta.value.substr(0,lim);
				this._limBox.className='full';
				}
			this._limBox.innerHTML=ta.value.length+' tecken av '+lim;
			this._limBoxTimeout=setTimeout(function(){self._limBox.style.visibility='hidden';},5000);
			}
		},
	/********************************************/
	/** RTE *************************************/
	/********************************************/
	rte:{
		/********************************************/
		_frames:{},
		/********************************************/
		init:function(rn,css){
			var ifr=document.getElementById(rn+'_iframe');
			this._frames[rn]={
				w:ifr.contentWindow,
				d:ifr.contentWindow.document,
				i:document.getElementById(rn+'_textarea'),
				e:document.getElementById(rn+'_entities'),
				a:0
				};
			this.cmap.init();
			this._frames[rn].d.open();
			this._frames[rn].d.write([
				'<html><head>'
				,'<style type="text/css">'
				,css
				,'</style>'
				,'</head>'
				,'<body onclick="parent.jwebForm.rte.activate(\'',rn,'\')" id="jwebFormRteBody">'
				,this._frames[rn].i.value
				,'</body></html>'
				].join(''));
			this._frames[rn].d.close();
			},
		/********************************************/
		activate:function(rn,callback){
			if(!this._frames[rn].a){
				if(typeof document.body.contentEditable!='undefined'){
					this._frames[rn].d.body.contentEditable=true;
					}
				else{
					try{
						this._frames[rn].d.designMode='on';
						}
					catch(e){
						var self=this;
						setTimeout(function(){self.activate(rn,callback)},100);
						return;
						}
					}
				this._frames[rn].a=1;
				this._frames[rn].w.focus();
				}
			if(callback){
				callback();
				}
			},
		/********************************************/
		edit:function(rn,cmd,val){
			if(this._frames[rn].a){
				if('createlink'==cmd){
					val=prompt('Ange adress','http://');
					}
				this._frames[rn].w.focus();
				this._frames[rn].d.execCommand(cmd,false,val);
				this._frames[rn].w.focus();
				}
			else{
				var self=this;
				this.activate(rn,function(){self.edit(rn,cmd,val)});
				}
			},
		/********************************************/
		prepareForSubmit:function(){
			for(var rn in this._frames){
				if(this._frames[rn].a){
					this._frames[rn].i.value=this._frames[rn].d.body.innerHTML;
					}
				}
			},
		/********************************************/
		/** RTE CMAP ********************************/
		/********************************************/
		cmap:{
			_data:0,
			/********************************************/
			init:function(){
				if(!this._data){
					this._data={
						o:document.getElementById('jwebFormRteCMap'),
						rn:0, // the rn at cMap opening
						rng:0 // the range at cMap opening, if needed (ie)
						};
					}
				},
			/********************************************/
			setOpeningState:function(rn){
				this._data.rn=rn;
				if(ua.ie){
					if(jwebForm.rte._frames[rn].a){
						this._data.rng=jwebForm.rte._frames[rn].d.selection.createRange();
						}
					else{
						var self=this;
						jwebForm.rte.activate(rn,function(){jwebForm.rte.cmap.setOpeningState(rn)});
						}
					}
				},
			/********************************************/
			open:function(rn,button){
				var xy=jweb.xy.pos(button);
				this._data.o.style.left=xy.x+'px';
				this._data.o.style.top=xy.y+'px';
				this._data.o.style.display='block';
				this.setOpeningState(rn);
				},
			/********************************************/
			mouseout:function(evt,button){
				evt=jweb.event.get();
				if(jweb.event.isMouseLeave(evt,button)){
					this._data.o.style.display='none';
					}
				},
			/********************************************/
			click:function(evt){
				evt=jweb.event.get();
				var td=evt.target;
				if(td.tagName=='TD'&&td.id!='heading'){
					if(this._data.rng){
						jwebForm.rte._frames[this._data.rn].w.focus();
						this._data.rng.pasteHTML(td.innerHTML);
						this._data.rng.collapse();
						this._data.rng.select();
						}
					else{
						jwebForm.rte.edit(this._data.rn,'insertHTML',td.innerHTML);
						}
					this._data.o.style.display='none';
					}
				}
			/********************************************/
			}
		}
	};