
Array.prototype.inArray = function(v){
  for(var i in this){
    if(this[i] == v){
      return true;}
    }
  return false;
}

String.prototype.splitOrg=String.prototype.split;
String.prototype.split=function(delim,howMany)
{
	var str=this;
	if( howMany==0 )
	{
		var c=new Array();
		c[0]=str;
		return c;
	}


	var c=str.splitOrg(delim);

	if( howMany==null )
		return c;

	if( (c.length-1)<=howMany )
		return c;

	var rest="";
	for(var i=howMany;i<c.length;i++)
		rest=rest+c[i]+delim;

	if( rest.length>0 )
		rest=rest.substr(0,rest.length-1);

	while( c.length>howMany )
		c.pop();

	c.push(rest);
	return c;
}


String.prototype.pad=function(len, pad, dir) {

	if (typeof(len) == "undefined") { var len = 0; }
	if (typeof(pad) == "undefined") { var pad = ' '; }
	if (typeof(dir) == "undefined") { var dir = 'r'; }

	var str=this;

	if (len + 1 >= str.length) {

		switch (dir){

			case 'l':
				str = Array(len + 1 - str.length).join(pad) + str;
			break;

			case 'c':
				var right = Math.ceil((padlen = len - str.length) / 2);
				var left = padlen - right;
				str = Array(left+1).join(pad) + str + Array(right+1).join(pad);
			break;

			default:
				str = str + Array(len + 1 - str.length).join(pad);
			break;

		} // switch

	}

	return str;
};

String.prototype.trimNumber=function() {
	var s=this;
	while (s.substr(0,1) == '0' && s.length>1) { s = s.substr(1,9999); }
	return s;
}

String.prototype.ltrim=function(chars)
{
	if( chars==null ) chars="";
	chars = chars || "\\s";
	return this.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

String.prototype.rtrim=function(chars)
{
	if( chars==null ) chars="";
	chars = chars || "\\s";
	return this.replace(new RegExp("[" + chars + "]+$", "g"), "");

}
String.prototype.trim=function(chars)
{
	var str;
	str=this.rtrim(chars);
	str=this.ltrim(chars);
	return str;
}


//////////////////////////////////
// JSWorkspace

var JSWorkspace=function(container)
{
	var thisObj=this;

	if( container==null )
		this.gContainer=document;
	else
		this.gContainer=container;

	this.ajax=new GLM.AJAX();

	thisObj.iFrameShowCover=new Array();
	thisObj.iFrameArgs=new Array();
	thisObj.iFrameBusy=new Array();

	this.iFrameBusy["ajaxiframe"]=false;

	var repositionMethods=new Array();
	this.registerRepositionMethod=function(method)
	{
		repositionMethods.push(method);
	}

	this.doReposition=function()
	{
		for(var i=0;i<repositionMethods.length;i++) {
			repositionMethods[i]();
		}
	}

	this.showWaitCover=function(showWait)
	{
		if( showWait!=null )
		{
			var what=Element.extend(showWait['what']);
			var where=Element.extend(showWait['where']);

			what.show();

			if( showWait['left']!=null )
				what.setStyle({left: showWait['left']+"px"});
			else
				what.setStyle({left: where.cumulativeOffset()[0]+"px"});


			if( showWait['top']!=null )
				what.setStyle({top: showWait['top']+"px"});
			else
				what.setStyle({top: where.cumulativeOffset()[1]+"px"});


			if( showWait['width']!=null )
				what.setStyle({width: showWait['width']+"px"});
			else
				what.setStyle({width: where.getWidth()+"px"});


			if( showWait['height']!=null )
				what.setStyle({height: showWait['height']+"px"});
			else {
				what.setStyle({height: where.getHeight()+"px"});

				if( where==document.body && !Prototype.Browser.IE )
					what.setStyle({height: where.getHeight()+4+"px"});
			}

			if( showWait['hcenter']!=null )
			{
				what.setStyle({textAlign: "center"});
				what.down().setStyle({textAlign: "center"});
			}
			else
			{
				what.setStyle({textAlign: "left"});
				what.down().setStyle({textAlign: "left"});
			}

			if( showWait['vcenter']!=null )
			{
				what.setStyle({height: where.getHeight()+"px"});

				if( where==document.body )
				{

					var h1=what.down().getHeight();
					var h2=JSWorkspace.getViewportSize()[1];

					if( h1<h2 )
					{
						var tmp1=(parseInt(h2/2) - parseInt(h1/2));
						if( tmp1<0 ) tmp1=0;
							what.down().setStyle({marginTop: tmp1+"px"});
					}

					if( Prototype.Browser.IE )
						setTimeout("window.scrollTo(0, 0)",1);
					else
						where.scrollTo();
				}
				else
				{
					var h1=	what.down().getHeight();
					var h2=where.getHeight();
					if( h1<h2 )
					{
						what.down().setStyle({marginTop:(parseInt(h2/2) - parseInt(h1/2))+"px"});
					}
				}
			}
			return;
		}

	}

	this.hideWaitCover=function()
	{
		if( $(thisObj.waitCoverId)!=null )
			$(thisObj.waitCoverId).hide();
		thisObj.waitCoverBg.hide();
	}


	this.requestUpdateifrm=function(iframeName) {

		if( iframeName==null )
			iframeName="ajaxiframe";

		if( $(iframeName)==null )
			return;

		var args=thisObj.iFrameArgs[iframeName];

		var content=$(iframeName).contentWindow.document.body.innerHTML;

		var newArgs=new Array();
		newArgs['showWait']= thisObj.iFrameShowCover[iframeName];
		newArgs['client']=args;

		thisObj.iFrameBusy[iframeName]=false;

		if( !Prototype.Browser.IE && content.trim().startsWith('<pre>') ) {
			content=content.trim();
			content=content.substring(5,content.length-6);
		}

		thisObj.requestUpdate(content,newArgs);
	}

	this.requestUpdate=function(content,args) {
		var m=JSWorkspace.parseJSON(content);
		if( m!=null )
		{
			if( m["_redirect"]!=null )
				if( !m["_redirect"].empty() )
				{
					// TODO Add callback
					window.location=m["_redirect"];
					return;
				}

			if( m["_exception"]!=null )
				if( !m["_exception"].empty() )
				{
					// TODO Add callback

					var div=new Element("div");
					document.body.appendChild(div);
					div.absolutize();
					div.setStyle({top:"0px",left:"0px"});
					div.setStyle({width: '100%',height:'100%'});

					var p=new Element("p");
					div.appendChild(p);
					p.setStyle({backgroundColor: '#ffffff'});
					p.update(m["_exception"]);

					var a=new Element('a');
					a.update('zamknij');
					a.href='javascript:;';
					a.observe('click',function(e){Event.element(e).up().up().hide();});
					p.appendChild(a);


					div.show();
					return;
				}

			if( m["_noaccess"]!=null )
			{
				// TODO Add callback

				alert('Brak dostepu');
				return;
			}
		}

		var argsClient=args['client'];

		if( args['showWait'] )
		{
			var ar=args['showWait']['elementsToRemove'].elements;

			var goAhead=true;
			if( args.dontRemove!=null )
				if( args.dontRemove )
					goAhead=false;
			if( goAhead )
			for(var i=0;i<ar.length;i++)
			{
				ar[i].hide();
				ar[i].remove();
			}
		}

		if( argsClient ) {
			if( argsClient.destId )
				if( $(argsClient.destId)!=null )
					if( typeof($(argsClient.destId).update)=='function' )
						$(argsClient.destId).update(content);
			if( argsClient.dest )
				if( typeof(argsClient.dest.update)=='function' )
					argsClient.dest.update(content);
			if( typeof(argsClient.callback)=='function' )
				argsClient.callback(content,argsClient,args);
			if( argsClient.msg!=null )
				thisObj.coverElement({where:args.showWait.where,msg:argsClient.msg,hcenter:true,vcenter:true,coverTimeout:argsClient.msgTimeout,msgClass:argsClient.msgClass});
		}

		if( argsClient ) {
			if( argsClient.expression!=null )
				setTimeout(argsClient.expression,(argsClient.expressionTimeout!=null?argsClient.expressionTimeout:1));
		}


	//	content.evalScripts();

	}

	this.requestGetIframe=function(url,showWait,args) {

		var iframeName="ajaxiframe";

		if( args!=null )
			if( args.iframe!=null )
				iframeName=args.iframe;

		if( thisObj.iFrameBusy[iframeName] )
			return false;

		if( showWait!=null ) {
			showWait['elementsToRemove']=thisObj.coverElement({where:showWait.where,what:showWait.what,hcenter:showWait.hcenter,vcenter:showWait.vcenter,height:showWait.height,width:showWait.width});
			thisObj.iFrameShowCover[iframeName]=showWait;
			thisObj.iFrameBusy[iframeName]=true;
		}
		else
			thisObj.iFrameShowCover[iframeName]=null;

		thisObj.iFrameArgs[iframeName]=args;

		$(iframeName).src=url;

		return true;
	}

	this.showWaitProgress=function(content,args)
	{
		var m=JSWorkspace.parseJSON(content);
		if( m==null )
			return;

		if( parseInt(m.all)>0 )
		{
			var pr=parseInt(100*m.current/m.all);
			var o=coverElementArgs[args.coverElementArgsId];

			for(var i=0;i<o.elementsToRemove.length;i++)
			{
				var ar=o.elementsToRemove[i].select('[progress]');
				for(var j=0;j<ar.length;j++)
					ar[j].update(pr);
			}

			if( m.current!=m.all )
				setTimeout("jsWorkspace.requestGet(Root+'upload/progress,uploadId,"+m.uploadId+"',null,{callback:jsWorkspace.showWaitProgress,coverElementArgsId:"+args.coverElementArgsId+"})",2000);
		}
		else
			setTimeout("jsWorkspace.requestGet(Root+'upload/progress,uploadId,"+m.uploadId+"',null,{callback:jsWorkspace.showWaitProgress,coverElementArgsId:"+args.coverElementArgsId+"})",2000);
	}

	this.requestPostIframe=function(formName,showWait,args) {

		var iframeName="ajaxiframe";

		if( args!=null )
			if( args.iframe!=null )
				iframeName=args.iframe;

		if( thisObj.iFrameBusy[iframeName] )
			return false;

		if( showWait!=null ) {
			showWait['elementsToRemove']=thisObj.coverElement({where:showWait.where,what:showWait.what,hcenter:showWait.hcenter,vcenter:showWait.vcenter,height:showWait.height,width:showWait.width});
			thisObj.iFrameShowCover[iframeName]=showWait;
			thisObj.iFrameBusy[iframeName]=true;

			if( thisObj.gContainer.forms[formName].FileUploadListenerId!=null )
			{
				if( thisObj.gContainer.forms[formName].FileUploadListenerId.value=='' )
					thisObj.gContainer.forms[formName].FileUploadListenerId.value=JSWorkspace.generateID();
				coverElementArgs[showWait['elementsToRemove'].id].uploadListenerId=thisObj.gContainer.forms[formName].FileUploadListenerId.value;

				setTimeout("jsWorkspace.requestGet(Root+'upload/progress,uploadId,"+thisObj.gContainer.forms[formName].FileUploadListenerId.value+"',null,{callback:jsWorkspace.showWaitProgress,coverElementArgsId:"+showWait['elementsToRemove'].id+"})",2000);
			}
		}
		else
			thisObj.iFrameShowCover[iframeName]=null;

		thisObj.iFrameArgs[iframeName]=args;

		var action=thisObj.gContainer.forms[formName].action;

		var target=thisObj.gContainer.forms[formName].target;

		if( action.indexOf('?ajax')<0 && action.indexOf('&ajax')<0 )
		{
			if( action.indexOf('?')>=0 )
				action=action+'&ajax';
			else
				action=action+'?ajax';
			thisObj.gContainer.forms[formName].action=action;
		}

		thisObj.gContainer.forms[formName].target=iframeName;

		thisObj.gContainer.forms[formName].submit();
		thisObj.gContainer.forms[formName].target=target;

		return true;
	}

	this.requestPost=function(formName,showWait,args) {

		var newArgs=new Array();
		newArgs['client']=args;
		newArgs['showWait']=showWait;
		if( showWait!=null )
			showWait['elementsToRemove']=thisObj.coverElement({where:showWait.where,what:showWait.what,hcenter:showWait.hcenter,vcenter:showWait.vcenter,height:showWait.height,width:showWait.width});

		var form;
		if( (typeof formName)=='string' )
			form=thisObj.gContainer.forms[formName];
		else
			form=formName;

		var values=thisObj.formVarsToStringStandard(form);
		var valuesFramework=thisObj.formVarsToString(form);
		var action=form.action;

//		if( action.indexOf('?')>=0 )
//			action=action+'&ajax';
//		else
//			action=action+'?ajax';
		
		
		
		thisObj.ajax.callPage(action,thisObj,"POST",values,null,newArgs);


		if( valuesFramework.length>0 )
			return action+valuesFramework;
		return action;
	}

	this.requestGet=function(url,showWait,args) {
		var newArgs=new Array();
		newArgs['client']=args;
		newArgs['showWait']=showWait;
		if( showWait!=null )
			showWait['elementsToRemove']=thisObj.coverElement({where:showWait.where,what:showWait.what,hcenter:showWait.hcenter,vcenter:showWait.vcenter,height:showWait.height,width:showWait.width});

		
		if( url.indexOf('?')>=0 )
			url=url+'&ajax';
		else
			url=url+'?ajax';
		
		
		thisObj.ajax.callPage(url,thisObj,"GET",null,null,newArgs);
	}

	this.formVarsToStringStandard=function(form)
	{
		var i;
		var m=new Map();
		for(i=0;i<form.elements.length;i++)
		{
			var codedValue=null;
			if( form.elements[i].type=='checkbox' )
				codedValue=form.elements[i].checked?'true':'false';
			else if( form.elements[i].type=='radio' ) {
				if( !form.elements[i].checked )
					continue;
				codedValue=JSWorkspace.encodeUrl(form.elements[i].value)
			}
			else
			{
				codedValue=JSWorkspace.encodeUrl(form.elements[i].value);
			}
			m.put(form.elements[i].name,codedValue);
		}

		var url="";

		var keys=m.keys();

		for(var i=0;i<keys.length;i++) {
			if( i>0 )
				url+='&';
			url+=keys[i]+"="+m.get(keys[i]);
		}

		return url;
	}

	var savedForms=new Array();
	this.saveFormToUrl=function(key,form)
	{
		var url=form.action+this.formVarsToString(form);
		savedForms[key]=url;
	}
	this.getSavedForm=function(key)
	{
		return savedForms[key];
	}

	this.formVarsToString=function(form)
	{
		var url='';
		var i;
		var delim='';
		for(i=0;i<form.elements.length;i++)
		{
			delim=',';

			url+=delim+form.elements[i].name;
			if( form.elements[i].type=='checkbox' )
				url+=form.elements[i].checked?',true':',false';
			else
				url+=','+JSWorkspace.encodeUrl(form.elements[i].value);
		}
		return url;
	}

	var coverElementArgs=new Array();
	this.coverElement=function(args)
		{
			var elementsToRemove=new Array();

			var cT=new Element('div');
			cT.appendChild(new Element('div'));
			document.body.appendChild(cT);
			cT.absolutize();
			cT.setStyle({top:"0px",left:"0px",width:"100%",height:"100%",zIndex:90});
			cT.addClassName('coverTransparent');
			
			this.showWaitCover({what:cT,where:args.where,height:args.height,width:args.width});

			elementsToRemove.push(cT);

			if( args.what!=null )
			{
				var wI=JSWorkspace.cloneElement(args.what);
				wI.absolutize();
				wI.setStyle({zIndex:91});
				this.showWaitCover({what:wI,where:args.where,hcenter:args.hcenter,vcenter:args.vcenter,height:args.height,width:args.width});

				elementsToRemove.push(wI);
			}

			if( args.msg!=null )
			{
				var cM=JSWorkspace.cloneElement($('coverMessage'));
				cM.setStyle({zIndex:99});

				cM.down().update(args.msg);
				this.showWaitCover({what:cM,where:args.where,hcenter:args.hcenter,vcenter:args.vcenter,height:args.height,width:args.width});

				if( args.msgError!=null && args.msgError )
				{
					cM.down().removeClassName("msgOk");
					cM.down().addClassName("msgError");
				}

				else
				{
					cM.down().addClassName("msgOk");
					cM.down().removeClassName("msgError");
				}

				if( args.msgClass!=null )
					cM.down().addClassName(args.msgClass);

				elementsToRemove.push(cM);
			}

			var tmp=new Object();
			tmp.elementsToRemove=elementsToRemove;

			coverElementArgs.push(tmp);
			var id=coverElementArgs.length-1;

			if( args.actionTimeout!=null )
			{
				setTimeout('jsWorkspace.actionTimeout("'+id+'")',args.coverTimeout);
				tmp.actionExpression=args.actionExpression;
				tmp.actionCallback=args.actionCallback;
				tmp.actionCallbackArgs=args.actionCallbackArgs;
				if( args.coverTimeout==args.actionTimeout )
					tmp.closeCover=true;
				else if( args.coverTimeout!=null )
					setTimeout('jsWorkspace.coverHide("'+id+'")',args.coverTimeout);
			}
			else if( args.coverTimeout!=null )
				setTimeout('jsWorkspace.coverHide("'+id+'")',args.coverTimeout);

			return {id:id,elements:elementsToRemove};

		}

	this.actionTimeout=function(id)
	{
		if( id==null )
			return;
		var ar=coverElementArgs[id];
		if( ar==null )
			return;

		if( ar.closeCover )
			this.coverHide(id);

		if( ar.actionExpression!=null )
			eval(ar.actionExpression);

		if( ar.actionCallback!=null )
			ar.actionCallback(ar.actionCallbackArgs);

	}

	this.coverHide=function(id)
	{
		if( id==null )
			return;
		var ar=coverElementArgs[id];
		if( ar==null )
			return;
		for(var i=0;i<ar.elementsToRemove.length;i++)
		{
			ar.elementsToRemove[i].hide();
			ar.elementsToRemove[i].remove();
		}
	}
}

JSWorkspace.generateID=function()
{
	var d=new Date();
	return d.getTime()%9999999999;
}

JSWorkspace.parseJSON=function(content)
{
	content=content.stripTags();
	

	if( content==null )
		return null;
	if( content.strip().empty() )
		return null;
	if( content=="EMPTY" )
		return null;
	if( !content.isJSON() )
		return null;
	try
	{
		return JSON.parse(content);
	}
	catch(err)
	{
		return null;
	}
}

JSWorkspace.cloneElement=function(source)
{
	var n=new Element("div");
	n.hide();
	document.body.appendChild(n);
	n.hide();
	n.addClassName(source.className);
	n.update(source.innerHTML);
	return n;
}

JSWorkspace.popup=function(href,name,width,height,r)
{
        popupWindow=window.open(href, name, 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width='+width+',height='+height);
        popupWindow.opener=window;

        if( r!=null )
	        return popupWindow;
}

JSWorkspace.popupScroll=function(href,name,width,height,r)
{
        popupWindow=window.open(href, name, 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=no,width='+width+',height='+height);
        popupWindow.opener=window;

        if( r!=null )
        	return popupWindow;
}

JSWorkspace.encodeUrl=function(p)
{
	if( p==null )
		return "";
	p=p.replace(/%/g,'%25');

	p=p.replace(/,/g,'%2C');

	p=p.replace(/ą/g,'%c4%85');
	p=p.replace(/Ą/g,'%c4%84');

	p=p.replace(/ć/g,'%c4%87');
	p=p.replace(/Ć/g,'%c4%86');

	p=p.replace(/ę/g,'%c4%99');
	p=p.replace(/Ę/g,'%c4%98');

	p=p.replace(/ł/g,'%c5%82');
	p=p.replace(/Ł/g,'%c5%81');

	p=p.replace(/ń/g,'%c5%84');
	p=p.replace(/Ń/g,'%c5%83');

	p=p.replace(/ó/g,'%c3%b3');
	p=p.replace(/Ó/g,'%c3%93');

	p=p.replace(/ś/g,'%c5%9b');
	p=p.replace(/Ś/g,'%c5%9a');

	p=p.replace(/ż/g,'%c5%bc');
	p=p.replace(/Ż/g,'%c5%bb');

	p=p.replace(/ź/g,'%c5%ba');
	p=p.replace(/Ź/g,'%c5%b9');

	p=p.replace(/\?/g,'%3f');
	p=p.replace(/\,/g,'%2c');
	p=p.replace(/&/g,'%26');
	p=p.replace(/=/g,'%3d');
	p=p.replace(/\n/g,'%0a');


	return p;
}


JSWorkspace.decodeHtml=function(s)
{
	s=s.replace(/&lt;/g, "<");
	s=s.replace(/&gt;/g, ">");

	s=s.replace(/&amp;/g, "&");

	return s;

}

JSWorkspace.oldTextSelectFunc=null;
JSWorkspace.enableSelection=function() {
	if( !Prototype.Browser.IE )
	{
		document.body.onmousedown=JSWorkspace.oldTextSelectFunc;
		oldTextSelectFunc=null;
	}
	return;
}
JSWorkspace.disableSelection=function() {
	if( !Prototype.Browser.IE  )
	{
		JSWorkspace.oldTextSelectFunc=document.body.onmousedown;
		document.body.onmousedown=function(){return false}
	}
	return;
}

JSWorkspace.getViewportSize=function()
{
	if( Prototype.Browser.IE )
		return [document.documentElement.clientWidth,document.documentElement.clientHeight];
	else
		return [window.innerWidth,window.innerHeight];
}
JSWorkspace.getDocumentScrollOffset=function()
{
	var iebody=(document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body;

	var dsocleft=document.all? iebody.scrollLeft : pageXOffset;
	var dsoctop=document.all? iebody.scrollTop : pageYOffset;
	return [dsocleft,dsoctop];
}

JSWorkspace.getMiliseconds=function()
{
	var d=new Date();
	return d.getTime();
}
JSWorkspace.isInside=function(element,pointer)
{
	if( element.cumulativeOffset()[0]>pointer[0] )
		return false;
	if( element.cumulativeOffset()[1]>pointer[1] )
		return false;
	if( (element.cumulativeOffset()[0]+element.getWidth())<pointer[0] )
		return false;
	if( (element.cumulativeOffset()[1]+element.getHeight())<pointer[1] )
		return false;
	return true;
}

JSWorkspace.coverWithTransparent=function(el,prc)
{
	var div=new Element("div");
	document.body.appendChild(div);
	div.show();
	div.absolutize();
	div.setStyle({zIndex:50});


	div.setStyle({left:el.cumulativeOffset()[0]+"px",top:el.cumulativeOffset()[1]+"px"});
	div.setStyle({height:el.getHeight()+"px",width:el.getWidth()+"px"});

	div.setStyle({backgroundColor:"white"});
	div.setOpacity(prc/100);

	if( document.body==el && !Prototype.Browser.IE )
		div.setStyle({height:el.getHeight()+4+"px"});

	return div;
}

JSWorkspace.elementDown=function(el)
{
	if( el.next()!=null )
	{
		var tmp=el.next();
		el.remove();

		tmp.up().insertBefore(el,tmp.next());
	}
}
JSWorkspace.elementUp=function(el)
{
	if( el.previous()!=null )
	{
		var tmp=el.previous();
		el.remove();

		tmp.up().insertBefore(el,tmp);
	}
}


JSWorkspace.enableSelection=function()
{
}


JSWorkspace.FindAncestor=function(element,selector)
{
	var e=Element.extend(element);
	
	while(e!=null)
	{
		
		if( e.match(selector) )
			return e;
		e=e.up();
	}
	return null;
}


// JSWorkspace
//////////////////////////////////


//////////////////////////////////
// PasswordMeter

function passwordStrength(passwd,factor)
{
		var intScore   = 0
		var strVerdict = "weak"
		var strLog     = ""

		// PASSWORD LENGTH
		if (passwd.length<5)                         // length 4 or less
		{
			intScore = (intScore+3)
			strLog   = strLog + "3 points for length (" + passwd.length + ")\n"
		}
		else if (passwd.length>4 && passwd.length<8) // length between 5 and 7
		{
			intScore = (intScore+6)
			strLog   = strLog + "6 points for length (" + passwd.length + ")\n"
		}
		else if (passwd.length>7 && passwd.length<16)// length between 8 and 15
		{
			intScore = (intScore+12)
			strLog   = strLog + "12 points for length (" + passwd.length + ")\n"
		}
		else if (passwd.length>15)                    // length 16 or more
		{
			intScore = (intScore+18)
			strLog   = strLog + "18 point for length (" + passwd.length + ")\n"
		}


		// LETTERS (Not exactly implemented as dictacted above because of my limited understanding of Regex)
		if (passwd.match(/[a-z]/))                              // [verified] at least one lower case letter
		{
			intScore = (intScore+1)
			strLog   = strLog + "1 point for at least one lower case char\n"
		}

		if (passwd.match(/[A-Z]/))                              // [verified] at least one upper case letter
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one upper case char\n"
		}

		// NUMBERS
		if (passwd.match(/\d+/))                                 // [verified] at least one number
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one number\n"
		}

		if (passwd.match(/(.*[0-9].*[0-9].*[0-9])/))             // [verified] at least three numbers
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least three numbers\n"
		}


		// SPECIAL CHAR
		if (passwd.match(/.[!,@,#,$,%,^,&,*,?,_,~]/))            // [verified] at least one special character
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least one special char\n"
		}

									 // [verified] at least two special characters
		if (passwd.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/))
		{
			intScore = (intScore+5)
			strLog   = strLog + "5 points for at least two special chars\n"
		}


		// COMBOS
		if (passwd.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/))        // [verified] both upper and lower case
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for upper and lower letters\n"
		}

		if (passwd.match(/([a-zA-Z])/) && passwd.match(/([0-9])/)) // [verified] both letters and numbers
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for letters and numbers\n"
		}

									// [verified] letters, numbers, and special characters
		if (passwd.match(/([a-zA-Z0-9].*[!,@,#,$,%,^,&,*,?,_,~])|([!,@,#,$,%,^,&,*,?,_,~].*[a-zA-Z0-9])/))
		{
			intScore = (intScore+2)
			strLog   = strLog + "2 combo points for letters, numbers and special chars\n"
		}

		if( factor==null )
			factor=1;

		intScore = intScore * factor;

		if(intScore < 8)
		{
			return 0;
		}
		else if (intScore > 7 && intScore < 20)
		{
			return 1;
		}
		else if (intScore > 19 && intScore < 40)
		{
			return 2;
		}
		else if (intScore > 39 && intScore < 60)
		{
			return 3;
		}
		else
		{
			return 4;
		}
}

function PasswordStrengthMeter(divElement)
{
	var thisObj=this;

	var myDiv=Element.extend(divElement);
	myDiv.hide();

	this.register=function(obj) {
		var objExt=Element.extend(obj);
		objExt.observe('blur',this.blurAction);
		objExt.observe('keyup',this.updateAction);
		objExt.observe('focus',this.focusAction);
	}

	this.blurAction=function() {
		myDiv.hide();
	}

	this.focusAction=function(e) {
		updateScore(Event.element(e));
		showAbove(Event.element(e));
	}

	var showAbove=function(aboveWhat) {
		myDiv.setStyle({left: aboveWhat.cumulativeOffset()[0]+"px"});
		myDiv.setStyle({top: (aboveWhat.cumulativeOffset()[1] -  myDiv.getHeight() - 1 )+"px" });
		myDiv.show();
	}

	this.updateAction=function(e) {
		updateScore(Event.element(e));
	}

	var updateScore=function(input) {
		var s=passwordStrength(input.value,2);

		var ar=myDiv.descendants();
		var n=0;
		for(var i=0;i<ar.length;i++)
		{
			if( ar[i].readAttribute('meter') ) {
				if( s>n)
					ar[i].setStyle({backgroundColor: colorActive(n)});
				else
					ar[i].setStyle({backgroundColor: colorInactive()});
				n++;
			}
			if( ar[i].readAttribute('metertext') ) {
				if( s==4 ) {
					ar[i].setStyle({color: colorActive(3)});
					ar[i].update('bardzo mocne');
				}
				else if( s==3 ) {
					ar[i].setStyle({color: colorActive(2)});
					ar[i].update('mocne');
				}
				else if( s==2 ) {
					ar[i].setStyle({color: colorActive(1)});
					ar[i].update('średnie');
				}
				else if( s==1 ) {
					ar[i].setStyle({color: colorActive(0)});
					ar[i].update('słabe');
				}
				else {
					ar[i].setStyle({color: colorInactive()});
					ar[i].update('bardzo słabe');
				}
			}
		}
	}

	var colorInactive=function() {
		return 'lightgrey';
	}
	var colorActive=function(n) {

		var c;
		if( n==0 ) c='#7dbae1';
		else if( n==1 ) c='#52ed33';
		else if( n==2 ) c='#fca61c';
		else c='#f12b2b';

		return c;
	}
}
// PasswordMeter
//////////////////////////////////


//////////////////////////////////
// Set
function Set() {
	var values=new Array();

	this.remove=function(val) {
		var idx=-1;
		for(var i=0;i<values.length;i++)
			if( values[i]==key ) {
				idx=i;
				i=values.lengyh;
			}
		if( idx>=0 )
			values[idx]=null;


	}

	this.put=function(val) {
		var idx=-1;
		for(var i=0;i<values.length;i++)
			if( values[i]==val ) {
				idx=i;
				i=values.lengyh;
			}
		if( idx<0 )
			values.push(val);
	}

	this.values=function() {
		return values.compact();
	}

	this.size=function() {
		return values.compact().size();
	}

	this.each=function(fptr) {
		for(var i=0;i<values.length;i++) {
			if( values[i]!=null )
				if( fptr(values[i]) )
					values[i]=null;
		}
	}
}
// Set
//////////////////////////////////

//////////////////////////////////
// Map
function Map() {
	var keys=new Array();
	var values=new Array();

	this.remove=function(key) {
		var idx=-1;
		for(var i=0;i<keys.length;i++)
			if( keys[i]==key ) {
				idx=i;
				i=keys.lengyh;
			}
		if( idx>=0 ) {
			values[idx]=null;
			keys[idx]=null;
		}
	}

	this.put=function(key,object) {
		var idx=-1;
		for(var i=0;i<keys.length;i++)
			if( keys[i]==key ) {
				idx=i;
				i=keys.lengyh;
			}
		if( idx<0 ) {
			keys.push(key);
			idx=keys.length-1;
		}

		values[idx]=object;
	}

	this.get=function(key) {
		var idx=-1;
		for(var i=0;i<keys.length;i++)
			if( keys[i]==key ) {
				idx=i;
				i=keys.lengyh;
			}
		if( idx<0 )
			return null;
		return values[idx];
	}

	this.containsKey=function(key) {
		var o=this.get(key);
		if( o==null )
			return false;
		return true;
	}

	this.keys=function() {
		return keys.compact();
	}

	this.values=function() {
		return values.compact();
	}

	this.size=function() {
		return keys.compact().size();
	}

	this.each=function(fptr) {
		for(var i=0;i<keys.length;i++) {
			if( keys[i]!=null )
				if( fptr(keys[i],values[i]) ) {
					values[i]=null;
					keys[i]=null;
				}
		}
	}
}
// Map
//////////////////////////////////

//////////////////////////////////
// CommandQueue - To synchronize calls
function CommandQueue() {
	function Command(fnt,args) {
		this.fnt=fnt;
		this.args=args;
	}

	var queue=new Array();

	this.queueCommand=function(fnt,args) {
		var c=new Command(fnt,args);
		queue.push(c);

		if( $('debugCommandQueue')!=null )
		$('debugCommandQueue').update("Size of command queue after push: "+queue.size());

		this.execute();
	}

	this.execute=function() {
		var tmp=queue.size();
		var obj=queue.shift();
		if( obj!=null ) {
			if( $('debugCommandQueue')!=null )		$('debugCommandQueue').update("With Object - Time: "+JSWorkspace.getMiliseconds()+" Size of command queue after pop: "+queue.size()+" before pop: "+tmp);
			obj.fnt(obj.args);
		}
		else
			if( $('debugCommandQueue')!=null )		$('debugCommandQueue').update("Time: "+JSWorkspace.getMiliseconds()+" Size of command queue after pop: "+queue.size()+" before pop: "+tmp);

	}

	this.start=function() {
	}
}
var GCommandQueue=new CommandQueue();
GCommandQueue.start();
// CommandQueue
//////////////////////////////////


//////////////////////////////////
// TimeoutManager - to delay calls (like setTimeout but more powerfull)
function TimeoutManger() {
	var thisObj=this;
	function Action(functionPtr,args,removePreviousKey) {
		this.functionPtr=functionPtr;
		this.args=args;
		this.removePreviousKey=removePreviousKey;
	}

	var actions=new Array();
	this.add=function(miliseconds,functionPtr,args,removePreviousKey) {

		var act=new Action(functionPtr,args);
		GCommandQueue.queueCommand(this.addSynchronized,[functionPtr,args,miliseconds,removePreviousKey]);
	}

	this.addSynchronized=function(args) {
		var act=new Action(args[0],args[1],args[3]);

		if( args[3]!=null )
		for(var i=0;i<actions.length;i++)
			if( actions[i]!=null )
				if( actions[i].removePreviousKey!=null )
					if( actions[i].removePreviousKey==args[3] )
						actions[i]=null;

		actions.push(act);
		setTimeout("GTimeoutManager.execute("+(actions.length-1)+")",args[2]);
	}

	this.execute=function(idx) {
		var act=actions[idx];
		if( act!=null )
			act.functionPtr(act.args);
	}
}
var GTimeoutManager=new TimeoutManger();
// TimeoutManager
//////////////////////////////////


//////////////////////////////////
// MouseTrapEventManager - to trigger action  when mouse pointer goes out of box
function MouseTrapEventManager() {
	var thisObj=this;
	function Action(x1,x2,y1,y2,toHide,button,callBackIfHidden,callBackArgs,forever,effect,effectArgs) {
		this.x1=x1;
		this.x2=x2;
		this.y1=y1;
		this.y2=y2;
		this.toHide=toHide;
		this.button=button;
		this.callBackIfHidden=callBackIfHidden;
		this.callBackArgs=callBackArgs;
		this.forever=forever;
		this.effect=effect;
		this.effectArgs=effectArgs;

	}

	var events=new Array();

	this.hide=function(openButton) {
		for(var b in events) {
			var a=events[b];
			if( events[b]!=null ) {
				if( a.button==openButton ) {
					events[b]=null;
					if( a.toHide!=null )
					{
						if( a.effect!=null )
							a.effect(a.toHide,a.effectArgs);
						else
							Effect.Fade(a.toHide,{ duration: 0.1 });
					}
				}
			}
		}
	}

	this.analyze=function(event) {
		var x=Event.pointerX(event);
		var y=Event.pointerY(event);

		thisObj.x=x;
		thisObj.y=y;

		for(var i=0;i<events.length;i++)
		{
			var ac=events[i];
			if( ac==null )
				continue;

			if( x>=ac.x1 && x<=ac.x2 && y>=ac.y1 && y<=ac.y2 )
				continue;

			if( ac.forever==null )
				events[i]=null;
			else if( !ac.forever )
				events[i]=null;

			if( ac.toHide!=null )
				if( ac.effect!=null )
					ac.effect(ac.toHide,ac.effectArgs);
				else
					Effect.Fade(ac.toHide,{ duration: 0.1 });
			
			if( ac.callBackIfHidden!=null )
				ac.callBackIfHidden(ac.button,ac.callBackArgs);
		}
	}

	getLocation=function(obj,current,pad) {
		if( obj==null )
			return current;
		var o=Element.extend(obj);
		var pos=o.cumulativeOffset();


		var locNew=new Array();

		locNew['x1']=pos[0];
		locNew['y1']=pos[1];

		locNew['x2']=pos[0]+o.getWidth();
		locNew['y2']=pos[1]+o.getHeight();


		if( pad!=null ) {
			locNew['x1']-=pad[0];
			locNew['x2']+=pad[0];
			locNew['y1']-=pad[1];
			locNew['y2']+=pad[1];
		}


		if( current!=null )
		{
			if( locNew['x1']>current['x1'] )
				locNew['x1']=current['x1'];

			if( locNew['x2']<current['x2'] )
				locNew['x2']=current['x2'];

			if( locNew['y1']>current['y1'] )
				locNew['y1']=current['y1'];

			if( locNew['y2']<current['y2'] )
				locNew['y2']=current['y2'];
		}

		return locNew;
	}

	this.addReal=function(args) {
		
		var loc=getLocation(args[0],null,args[5]);

		
		for(var i=0;i<args[1].length;i++)
			loc=getLocation(args[1][i],loc,args[5]);
		
		events.push(new Action(loc['x1'],loc['x2'],loc['y1'],loc['y2'],args[0],args[2],args[3],args[4],args[6],args[7],args[8]));
		
		

		return events.length-1;
	}

	this.remove=function(id) {
		events[id]=null;
	}

	this.add=function(regionObjects,objectToHide,button,callBackH,callBackArgs,padding,forever,effect,effectArgs) {
		if( objectToHide!=null )
			if( !objectToHide.visible() )
				Effect.Appear(objectToHide,{ duration: 0.1 });
		//GTimeoutManager.add(200,thisObj.addReal,[objectToHide,regionObjects,button,callBackH,callBackArgs,padding,forever])
		return thisObj.addReal([objectToHide,regionObjects,button,callBackH,callBackArgs,padding,forever,effect,effectArgs]);
	}


	Event.observe(document.body,"mousemove",this.analyze);
}
var GMouseTrapEventManager=null;
// MouseTrapEventManager
//////////////////////////////////


//////////////////////////////////
// TextBoxSearchable
function TextBoxSearchable(source,searchUrl,searchDelay,searchListKey,inputElement,dropDownElement,size,callBackSelect,noSearch,overflowMin,noScroll)
{
	var thisObj=this;
	if( overflowMin==null )
		overflowMin=0;

	var hasFocus=true;
	this.onBlur=function(e)
	{
		hasFocus=false;
	}
	this.onFocus=function(e)
	{
		hasFocus=true;
	}


	var handleCallback=function(row) {
		if( callBackSelect==null )
			return;
		callBackSelect(row.readAttribute("lp"),row.readAttribute("value"));
	}

	this.onClick=function(e) {
		var el=Event.element(e);
		thisObj.selectedRow=el;

		thisObj.divElement.hide();
		var row=thisObj.selectedRow;
		if( row!=null ) {
			handleCallback(row);
			var v=row.readAttribute('value');
			inputElement.value=JSWorkspace.decodeHtml(v.replace(/&quot;/g,'"'));
		}
	}

	var createCaption=function(text,search) {
		var i=text.toLowerCase().indexOf(search.toLowerCase());


		if( i>=0 )
			text=text.substr(0,i) + '<b>' + text.substr(i,search.length) + '</b>' + text.substr(i+search.length);

		return text;
	}

	var selectCurrent=function() {
		var tmp=thisObj.selectedRow;

		if( tmp!=null )
			tmp.setStyle({backgroundColor: "#f0f0f0"});
	}

	var unselectCurrent=function() {
		var tmp=thisObj.selectedRow;
		if( tmp!=null )
			tmp.setStyle({backgroundColor: "white"});
	}

	this.searchFromServer=function(args)
	{
		jsWorkspace.requestGet(searchUrl+JSWorkspace.encodeUrl(args.searchText),null,{callback:thisObj.searchFromServerResult});
	}
	this.searchFromServerResult=function(content)
	{
		var m=JSWorkspace.parseJSON(content);
		if( m==null )
			return;
		noSearch=true;
		thisObj.search("",m[searchListKey]);
	}

	this.search=function(text,otherSource) {

		var e=thisObj.divElement;

		e.update('');

		thisObj.selectedRow=null;

		var shown=0;
		var toShow=false;

		if( otherSource!=null )
			source=otherSource;

		for(var i=0;i<source.length;i++) {
			if( source[i].toLowerCase().indexOf(text.toLowerCase())>=0 || noSearch ) {

				toShow=true;
				shown++;

				var cap=createCaption(source[i],text);
				cap=cap.replace(/ /g,"&nbsp;");

				var p=Element.extend(document.createElement("p"));
				p.writeAttribute("value",source[i]);
				p.writeAttribute("lp",i);

				p.setStyle({padding: 1, margin: 1});

				p.observe("click",thisObj.onClick);
				p.setStyle({cursor: "default"});

				if( thisObj.selectedRow==null ) {
					thisObj.selectedRow=p;
					selectCurrent();
				}

				p.update(cap);

				e.appendChild(p);
			}
		}


		if( toShow && hasFocus ) {

			if( shown>=overflowMin && noScroll==null  )
				e.setStyle({height: size, overflowY: "auto"});
			else
				e.setStyle({height: "", overflowY: "visible"});

			position();
			e.show();
			inputElement.noAdd=true;
		}
		else {
			e.hide();
			inputElement.noAdd=false;
		}
		e.scrollTop=0;
	}

	this.dropDownOrHide=function(e) {
		if( thisObj.divElement.visible() ) {
			thisObj.divElement.hide();
			inputElement.noAdd=false;
		}
		else {
			thisObj.search(inputElement.value);
			if( e!=null )
				Event.stop(e);
		}
	}
	this.hide=function() {
		thisObj.divElement.hide();
		inputElement.noAdd=false;
	}

	this.onUpdate=function(e) {
		if( e.keyCode>=65 && e.keyCode<=90 || e.keyCode>=48 && e.keyCode<=57 || thisObj.divElement.visible() )
			if( e.keyCode!=40 && e.keyCode!=38 && e.keyCode!=27 && e.keyCode!=13 && e.keyCode!=18 && e.keyCode!=9 && e.keyCode!=33 && e.keyCode!=34 )
			{
				if( searchUrl==null )
					thisObj.search(inputElement.value);
				else
					GTimeoutManager.add(searchDelay,thisObj.searchFromServer,{searchText:inputElement.value},thisObj);
			}
	}

	this.keyPressed=function(e) {
		if( e.keyCode==9 ) {
			thisObj.divElement.hide();
			inputElement.noAdd=false;
			thisObj.handledEvent=e;
		}
		if( e.keyCode==27 ) {
			thisObj.divElement.hide();
			inputElement.noAdd=false;
			Event.stop(e);
			thisObj.handledEvent=e;
		}
		else if( e.keyCode==13 && thisObj.divElement.visible()) {
			thisObj.divElement.hide();
			var row=thisObj.selectedRow;
			if( row!=null ) {
				handleCallback(row);
				var v=row.readAttribute('value');
				inputElement.value=JSWorkspace.decodeHtml(v.replace(/&quot;/g,'"'));
			}
			Event.stop(e);
		}
		else if( e.keyCode==13 && !thisObj.divElement.visible()) {
			if( thisObj.oldKeyPressFunc!=null )
				thisObj.oldKeyPressFunc(e);
		}
		else if( e.keyCode==40 && !thisObj.divElement.visible() )
			thisObj.search(inputElement.value);
		else if( e.keyCode==40 || e.keyCode==34 ) {
			var current=thisObj.selectedRow;
			if( current!=null ) {
				var n=current.next();



				if( n!=null && typeof(n)!='undefined') {

					if( e.keyCode==34 )
						for(var i=0;i<10 && n.next()!=null && typeof(n.next())!='undefined';i++)
							n=n.next();


					unselectCurrent();
					thisObj.selectedRow=n;
					selectCurrent();

					var h=n.cumulativeOffset()[1] - thisObj.divElement.cumulativeOffset()[1] + n.getHeight();

					while( h > (thisObj.divElement.getHeight() + thisObj.divElement.scrollTop) ) {
						thisObj.divElement.scrollTop+=1;
					}

				}
			}
		}
		else if( e.keyCode==38 || e.keyCode==33 ) {
			var current=thisObj.selectedRow;
			if( current!=null ) {
				var n=current.previous();



				if( n!=null && typeof(n)!='undefined' ) {

					if( e.keyCode==33 )
						for(var i=0;i<10 && n.previous()!=null && typeof(n.previous())!='undefined';i++)
							n=n.previous();

					unselectCurrent();
					thisObj.selectedRow=n;
					selectCurrent();

					var h=n.cumulativeOffset()[1] - thisObj.divElement.cumulativeOffset()[1];

					while( h < thisObj.divElement.scrollTop ) {
						thisObj.divElement.scrollTop-=1;
					}

				}
			}
		}

	}

	this.divElement=Element.extend(document.createElement('div'));
	this.divElement.addClassName('dropDownBox');


	Element.extend(inputElement).observe('keydown',this.keyPressed);
	Element.extend(inputElement).observe('keyup',this.onUpdate);
	Element.extend(inputElement).observe('blur',this.onBlur);
	Element.extend(inputElement).observe('focus',this.onFocus);

	if( dropDownElement!=null )
		Element.extend(dropDownElement).observe('click',this.dropDownOrHide);

	var ie=Element.extend(inputElement);

	if( size==null )
		size=50;

	this.divElement.hide();
	inputElement.noAdd=false;

	document.body.appendChild(this.divElement);

	var position=function() {
		thisObj.divElement.setStyle({left: ie.cumulativeOffset()[0]+"px", top: (ie.cumulativeOffset()[1] + ie.getHeight() +2)+"px"});
	}

	this.divElement.absolutize();

	this.divElement.setStyle({textAlign:'left',width: ie.getWidth()+"px", height: size+"px", overflowY: "auto", overflowX: "hidden"});

	position();

	inputElement.dropDownBox=this;

	this.oldKeyPressFunc=inputElement.onKeyPressFunc;

	if( this.oldKeyPressFunc!=null )
		ie.stopObserving("keypress",this.oldKeyPressFunc);

	Element.extend(document.body).observe("click",this.hide);
}
// TextBoxSearchable
//////////////////////////////////

//////////////////////////////////
// ImagePreviewer
function ImagePreviewer(containerId,imgSrc,smallWidth,smallHeight,maxBigWidth,maxBigHeight)
{
	var thisObj=this;

	var img=new Image();
	var zoom=100;

	var containerOuter=$(containerId);
	var container=$(containerId+'ImageDiv');

	var fullBg=null;



	this.imageLoaded=function() {
		var imgTag=new Element("img");
		imgTag.src=img.src;

		container.appendChild(imgTag);
	}

	img.onLoad=this.imgLoaded;
	img.src=imgSrc;

	var imgTag=new Element("img");
	container.appendChild(imgTag);

	imgTag.src=img.src;

	this.close=function() {
		containerOuter.hide();
		if( fullBg!=null )
		fullBg.hide();
		if( bodyOverflow!=null )
		Element.extend(document.body).setStyle({overflow:bodyOverflow});

	}


	this.show=function() {
		containerOuter.show();
		thisObj.gotoSmall();
	}

	this.setZoom=function(z) {
		zoom=z;
		if(zoom<0) zoom=0;
		if(zoom>100) zoom=100;

		zoomImage();
	}
	this.increaseZoom=function(n) {
		if( n==null )
			n=10;

		zoom=zoom-n;
		if(zoom<0) zoom=0;
		zoomImage();
	}
	this.decreaseZoom=function(n) {
		if( n==null )
			n=10;
		zoom=zoom+n;
		if(zoom>100) zoom=100;
		zoomImage();
	}

	var zoomImage=function() {
		if( container.getWidth()>img.width )
			return;

		var n=img.width-container.getWidth();
		n=n*(100-zoom)/100;

		n=img.width-n;

		container.down().setStyle({width:n+"px"});

		container.scrollTop=0;
		container.scrollLeft=0;
	}

	var dragging=false;
	var lastDragX=0;
	var lastDragY=0;
	this.mouseUp=function() {
		dragging=false;
		JSWorkspace.enableSelection();
		container.setStyle({cursor:"auto"});
		container.down().setStyle({cursor:"auto"});


	}

	this.mouseClick=function(e) {
		if( dragging )
		{
				dragging=false;
			container.setStyle({cursor:"auto"});
			container.down().setStyle({cursor:"auto"});
		}
		else
		{
			dragging=true;
			container.setStyle({cursor:"move"});
			container.down().setStyle({cursor:"move"});

			lastDragX=Event.pointerX(e);
			lastDragY=Event.pointerY(e);

		}
	}

	this.mouseDown=function(e) {
		dragging=true;



		JSWorkspace.disableSelection();
		container.setStyle({cursor:"move"});
		container.down().setStyle({cursor:"move"});

		lastDragX=Event.pointerX(e);
		lastDragY=Event.pointerY(e);

	}
	this.mouseMove=function(e) {
		if( !dragging )
			return;

		var x=Event.pointerX(e);
		var y=Event.pointerY(e);

		container.scrollTop=container.scrollTop-(y-lastDragY);
		container.scrollLeft=container.scrollLeft-(x-lastDragX);

		lastDragX=x;
		lastDragY=y;
	}

	var fullSmall=null;

	this.gotoFull=function() {
		containerOuter.down().setStyle({margin: "auto"});
		container.setStyle({width: 400+"px", height: 300+"px"});
		fullSmall="full";
		zoomImage();

		var b=Element.extend(document.body);

		containerOuter.setStyle({position:"absolute", top: b.cumulativeScrollOffset()[1]+"px", zIndex:99});

		var w=JSWorkspace.getViewportSize()[0];
		var h=JSWorkspace.getViewportSize()[0];
		if( w>maxBigWidth )
			w=maxBigWidth;
		if( h>maxBigHeight )
			h=maxBigHeight;
		if( w>img.width )
			w=img.width;
		if( h>img.height )
			h=img.height;

		container.setStyle({width: w+"px", height: h+"px"});
		if( fullBg!=null )
			fullBg.remove();
		fullBg=new Element("div");
		document.body.appendChild(fullBg);
		fullBg.appendChild(new Element("p"));

		fullBg.absolutize();
		fullBg.setStyle({top:b.cumulativeScrollOffset()[1]+"px",left:0,margin:0,padding:0,backgroundColor:"black",height:"100%",width:"100%"});
		fullBg.down().setStyle({margin:0,padding:0,width:"100%",height:"100%",backgroundColor:"black"});
		fullBg.setOpacity(0.5);
		fullBg.setStyle({zIndex:98});
		fullBg.show();

		bodyOverflow=Element.extend(document.body).getStyle("overflow");
		Element.extend(document.body).setStyle({overflow:"hidden"});



	}
	var bodyOverflow=null;
	this.gotoSmall=function() {
		containerOuter.down().setStyle({margin: "0px"});
		container.setStyle({width: smallWidth+"px", height: smallHeight+"px"});
		fullSmall="small";
		zoomImage();
		containerOuter.setStyle({position:"relative", top: 0});
		if( fullBg!=null )
		fullBg.hide();
		if( bodyOverflow!=null )

		Element.extend(document.body).setStyle({overflow:bodyOverflow});
	}



	this.fullSmall=function() {
		if( fullSmall=="full" )
			thisObj.gotoSmall();
		else
			thisObj.gotoFull();
	}



	container.observe('mouseout',thisObj.mouseUp);
	container.observe('mousemove',thisObj.mouseMove);

	if( Prototype.Browser.IE )
	{
		container.observe('click',thisObj.mouseClick);
	}
	else

	{
		container.observe('mousedown',thisObj.mouseDown);
		container.observe('mouseup',thisObj.mouseUp);
	}

	$(containerId+"ZoomOut").observe("click",function() { thisObj.increaseZoom(10);});
		$(containerId+"ZoomIn").observe("click",function() { thisObj.decreaseZoom(10);});

	if( $(containerId+"Close")!=null )
		$(containerId+"Close").observe("click",thisObj.close);
	$(containerId+"Maximize").observe("click",thisObj.gotoFull);
	$(containerId+"Minimize").observe("click",thisObj.gotoSmall);
}
ImagePreviewer.registered=new Map();
ImagePreviewer.findAndSmall=function(parent)
{

	var ar=parent.select("[imagePreview=true]");
	for(var i=0;i<ar.length;i++) {
		var container=ar[i];
		if( !ImagePreviewer.registered.containsKey(container) )
			ImagePreviewer.registered.put(container, new ImagePreviewer(container.readAttribute('id'), container.readAttribute('imageHref'), container.readAttribute('imageWidthSmall'), container.readAttribute('imageHeightSmall'), container.readAttribute('imageWidthBig'), container.readAttribute('imageHeightBig') ) );
		ImagePreviewer.registered.get(container).setZoom(50);
		ImagePreviewer.registered.get(container).gotoSmall();
	}
}
// ImagePreviewer
//////////////////////////////////


//////////////////////////////////
// Menu
function Menu(dataModel,args)
{
	if( args==null )
		args=new Object();


	var thisObj=this;

	var currentMenus=new Array();

	var dataModelFlat=new Array();

	this.name=args.name;

	this.mouseClick=function(e) {
		var element=Event.element(e).dataModelElement;
		if( element!=null )
		{
			if( element.callBack!=null )
				element.callBack(element.callBackArgs);
			else if( element.expression!=null )
				setTimeout(element.expression,1);
			else
			{
				if( args.openOnClick!=null )
					if( args.openOnClick ) {
						if( element.children!=null )
							openMenu(element);
						return;
					}
			}

			currentMenus.clear();
			showHideMenus();
		}
	}

	this.mouseOut=function(e) {
		var element=Event.element(e).dataModelElement;
		if( args.openOnClick!=null )
			if( args.openOnClick ) {
				element.forcedOver=false;
				showHideMenus();

				if( element.parent==null ) {
					if( args.rootButtonCallback!=null )
						args.rootButtonCallback(currentMenus<1,{rootButton:element.button,menu:thisObj});
				}

				return;
			}

		if( element.parent==null ) {
			if( args.rootButtonCallback!=null )
				args.rootButtonCallback(false,{rootButton:element.button,menu:thisObj});
		}
	}

	var openMenu=function(element) {
		if( !currentMenus.inArray(element) ) {
			currentMenus.clear();
			var e=element;

			while(e!=null) {
				currentMenus.splice(0,0,e);
				e=e.parent;
			}
			showHideMenus();
		}
		else {
			if( args.openOnClick!=null )
				if( args.openOnClick ) {
					var e=currentMenus.pop();
					while(e!=null && e!=element)
						e=currentMenus.pop();

					showHideMenus();
				}

		}
	}

	this.mouseOver=function(e) {
		var element=Event.element(e).dataModelElement;


		if( args.openOnClick!=null )
			if( args.openOnClick ) {
				element.forcedOver=true;
				showHideMenus();

				if( element.parent==null ) {
					if( args.rootButtonCallback!=null )
						args.rootButtonCallback(false,{rootButton:element.button,menu:thisObj});
				}

				return;
			}
		if( element!=null )
			openMenu(element);

	}
	////////////////////
	var fillDataModel=function(element,parent)
	{
		if( element==null )
			return;
		dataModelFlat.push(element);

		if( parent!=null )
			element.parent=parent;
		if( element.button!=null ) {
			element.button.dataModelElement=element;

			element.button.observe('mouseover',thisObj.mouseOver);
			element.button.observe('mouseout',thisObj.mouseOut);
			element.button.observe('click',thisObj.mouseClick);

		}
		if( element.children!=null )
		for(var i=0;i<element.children.length;i++)
			fillDataModel(element.children[i],element);
	}

	for(var i=0;i<dataModel.length;i++)
		fillDataModel(dataModel[i]);
	/////////////////////

	var build=function(element) {

		if( element.children==null )
			return;
		element.div=new Element('div');
		if( args.className==null )
			element.div.addClassName('menu');
		else
			element.div.addClassName(args.className);
		document.body.appendChild(element.div);
		element.div.hide();


		var table=new Element('table');
		element.div.appendChild(table);
		if( args.cellSpacingIE!=null && Prototype.Browser.IE  )
			element.div.down().writeAttribute('cellSpacing',args.cellSpacingIE);
		element.div.down().appendChild(new Element('tbody'));

		if( element.parent==null )
			element.div.writeAttribute('first','true');



		for(var i=0;i<element.children.length;i++)
		{
			var td=new Element('td');
			td.update(element.children[i].text);
			td.dataModelElement=element.children[i];
			td.observe('mouseover',thisObj.mouseOver);
			element.children[i].button=td;
			var tr=new Element('tr');

			td.observe('click',thisObj.mouseClick);
			td.observe('mouseout',thisObj.mouseOut);

			element.div.down().down().appendChild(tr);
			tr.appendChild(td);

			if( element.children[i].children!=null )
				if( element.children[i].children.length>0 )
					td.addClassName("withchildren");

		}

		var tmp1=0;
		if( args.cellSpacingIE!=null )
			tmp1=parseInt(args.cellSpacingIE);

		if( element.parent==null )
			element.div.setStyle({left:element.button.cumulativeOffset()[0]+"px",top:(element.button.cumulativeOffset()[1]+element.button.getHeight())+"px"});
		else
			element.div.setStyle({left:(element.button.cumulativeOffset()[0]+element.button.getWidth())+"px",top:(element.button.cumulativeOffset()[1]-tmp1)+"px"});
		element.div.setStyle({zIndex:80});
		element.div.setStyle({width: element.div.getWidth()+"px", height: element.div.getHeight()+"px"});
	}


	this.close=function() {
		currentMenus.clear();
		for(var i=0;i<dataModelFlat.length;i++)
			dataModelFlat[i].forcedOver=false;

		showHideMenus();
	}

	var showHideMenus=function() {
		for(var i=0;i<dataModelFlat.length;i++) {
			if( currentMenus.inArray(dataModelFlat[i]) )
			{
				showElement(dataModelFlat[i]);
				if( dataModelFlat[i].button!=null )
				{
					if( dataModelFlat[i].children!=null )
						dataModelFlat[i].button.addClassName('overchildren');
					else
						dataModelFlat[i].button.addClassName('over');
				}
			}
			else if( dataModelFlat[i].div!=null )
			{
				dataModelFlat[i].div.hide();

				if( dataModelFlat[i].button!=null )
				{
					dataModelFlat[i].button.removeClassName('over');
					dataModelFlat[i].button.removeClassName('overchildren');
				}
			}
			else
			{
				if( dataModelFlat[i].button!=null ) {
						dataModelFlat[i].button.removeClassName('overchildren');
						dataModelFlat[i].button.removeClassName('over');
				}
			}

			if( dataModelFlat[i].forcedOver )
				if( dataModelFlat[i].children!=null )
					dataModelFlat[i].button.addClassName('overchildren');
				else
					dataModelFlat[i].button.addClassName('over');
		}

		if( args.rootButtonCallback!=null )
			args.rootButtonCallback(currentMenus.length<1,{rootButton:(dataModelFlat.length>0?dataModelFlat[0].button:null),menu:thisObj});
	}

	var showElement=function(element) {

		if( element.div==null ) {
			build(element);
			if( element.div!=null ) {
				var mtemId=GMouseTrapEventManager.add([element.div.down(),element.button],null,null,thisObj.hideElement,{obj:element},[10,10],true);
				element.mtemId=mtemId;
			}
		}
		else {
			if( element.div!=null ) {
				GMouseTrapEventManager.remove(element.mtemId);
				var mtemId=GMouseTrapEventManager.add([element.div.down(),element.button],null,null,thisObj.hideElement,{obj:element},[10,10],true);
				element.mtemId=mtemId;
			}
		}
		if( element.div!=null ) {
			if( !element.div.visible() ) {
				element.div.absolutize();
				if( element.parent==null )
					element.div.setStyle({left:element.button.cumulativeOffset()[0]+"px",top:(element.button.cumulativeOffset()[1]+element.button.getHeight())+"px"});
				else
					element.div.setStyle({left:(element.button.cumulativeOffset()[0]+element.button.getWidth())+"px",top:(element.button.cumulativeOffset()[1]-1)+"px"});

				if( args.appearDuration!=null )
					Effect.Appear(element.div,{ duration: args.appearDuration, from: 0.01, to: 1.0 });
				else
					Effect.Appear(element.div,{ duration: 0.3, from: 0.01, to: 1.0 });
			}

		}
	}

	this.hideOver=function(e) {
		var element=Event.element(e).dataModelElement;

		if( element!=null )
		{
			if( !currentMenus.inArray(args.obj) )
				args.obj.div.hide();
		}
	}

	this.hideElement=function(button, argsInternal) {
		if( args.openOnClick!=null )
			if( args.openOnClick )
				return;

		if( argsInternal.obj!=null )
		{
			if( !currentMenus.inArray(argsInternal.obj) )
				argsInternal.obj.div.hide();

			var l=currentMenus.last();
			if( l==null )
				return;
			if( l.children==null )
				l=l.parent;
			if( l==null )
				return;

			if( argsInternal.obj==l )  {
				currentMenus.pop();

				showHideMenus();
			}
		}
	}
}
// Menu
//////////////////////////////////


//////////////////////////////////
// ToolTip
function ToolTip()
{
	var registered=new Array();
	var current=null;
	var shown=null;

	var thisObj=this;

	this.checkRoutine=function()
	{
		var t=JSWorkspace.getMiliseconds();
		if( current!=null ) {
				show(current.register);
		}
	}

	var show=function(r)
	{
		if( shown!=null )
			return;
		if( GMouseTrapEventManager==null )
			return;

		var div;

		var firstTime=true;
		if( r.div!=null ) {
			div=r.div;
			firstTime=false;
		}
		else {
			div=new Element('div');
			document.body.appendChild(div);
			div.setStyle({zIndex:69});
			div.absolutize();

			div.appendChild(new Element('div'));

			if( r.text!=null )
				div.down().update(r.text);
			else if( r.url!=null ) {
				div.down().update("&nbsp;");
				div.down().setStyle({width:$('coverWaitIcon').getWidth()+16+"px"});
			}
			r.div=div;

			if( r.containerClass!=null )
				div.addClassName(r.containerClass);
			else
				div.addClassName("tooltip");


		}

		div.show();
		div.absolutize();
		div.setStyle({top:GMouseTrapEventManager.y+"px",left:GMouseTrapEventManager.x+"px"});

		div.setStyle({width:div.down().getWidth()+"px"});

		if( firstTime && r.url!=null ) {
			jsWorkspace.requestGet(r.url,{where:div.down(),what:$('coverWaitIcon'),vcenter:true,hcenter:true,height:34},{dest:div.down(),callback:thisObj.afterUrl});
			div.hide();
		}
		else {
			GMouseTrapEventManager.add([div,div.down()],null,null,thisObj.hide,null,[20,20],false);
			current=null;
		}


		shown=new Object();
		shown.register=r;
		shown.div=div;

	}

	this.afterUrl=function()
	{
		if( shown!=null )
		{
			current=null;

				shown.div.show();
				shown.div.down().setStyle({width:shown.div.down().down().getWidth()+16+"px"});
			GMouseTrapEventManager.add([shown.div,shown.div.down()],null,null,thisObj.hide,null,[20,20],false);
		}
	}

	this.hide=function() {
		GCommandQueue.queueCommand(thisObj.hideDo);
	}
	this.hideDo=function() {
		if( shown!=null ) {
			shown.div.hide();
			shown=null;
		}
	}

	this.registerDo=function(args)
	{
		if( current!=null )
			return;

		for(var i=0;i<registered.length;i++)
			if( registered[i].domObj==args.domObj ) {
				if( shown!=null )
					if( shown.register==registered[i] )
						return;
				current={register:registered[i],time:JSWorkspace.getMiliseconds()};
				GTimeoutManager.add(current.register.delay,thisObj.checkRoutine);
				return;
			}

		registered.push(args);

		if( shown!=null )
			if( shown.register==registered.last() )
				return;
		current={register:registered.last(),time:JSWorkspace.getMiliseconds()};
		GTimeoutManager.add(current.register.delay,thisObj.checkRoutine);
	}

	this.unregisterDo=function(args)
	{
		if( current==null )
			return;

		for(var i=0;i<registered.length;i++)
			if( registered[i].domObj==args.domObj )
				if( current.register==registered[i] ) {
					current=null;
					return;
				}

	}

	this.register=function(domObj,args)
	{
		args.domObj=domObj;
		thisObj.registerDo(args);
	}

	this.unregister=function(domObj)
	{
		thisObj.unregisterDo({domObj:domObj});
	}

	this.start=function() {
		GTimeoutManager.add(100,thisObj.checkRoutine);
	}
}
GToolTip=new ToolTip();
// ToolTip
//////////////////////////////////


//////////////////////////////////
// Calendar
function Calendar(args)
{
	var thisObj=this;
	var year=null;
	var month=null;
	var selectedDate=null;
	var rows=null;
	var inputElement=null;

	if( args.link==null )
		return;
	if( args.link.calendar!=null )
	{
		args.link.calendar.show();
		return;
	}
	
	

	args.link=Element.extend(args.link);
	args.link.calendar=this;
	var div=JSWorkspace.cloneElement($('calendar'));
	div.setStyle({width:"180px"});

	var setCalendarSelectDate=function(currentDate)
	{
		var year=currentDate.getFullYear();
		var month=currentDate.getMonth();
		var dayOfMonth=currentDate.getDate();
	}

	if( args.input!=null )
		inputElement=Element.extend(args.input);

	var setupCalendar=function() {
		if( inputElement!=null ) {
			var sd=Conversion.stringToDate(inputElement.value);

			if( sd!=null )
				selectedDate=sd;
			else
				sd=new Date();

			year=sd.getFullYear();
			month=sd.getMonth();
		}
		else {
			var d=new Date();
			year=d.getFullYear();
			month=d.getMonth();
			selectedDate=null;
		}
	}

	setupCalendar();

	this.selectDate=function(e)
	{
		var el=Event.element(e);
		if( inputElement!=null )
			inputElement.value=year+"-"+((month+1)+"").pad(2,'0','l')+ "-"+el.innerHTML.pad(2,'0','l');

		
		if( args.onSelecting )
			args.onSelecting(parseInt(year),parseInt(month),parseInt(el.innerHTML));
		
		div.hide();
		
		if( args.onSelect )
			args.onSelect(parseInt(year),parseInt(month),parseInt(el.innerHTML));
		
	}


	this.reset=function()
	{
		if( inputElement!=null )
			inputElement.value='';
		div.hide();
	}

	this.close=function()
	{
		div.hide();
	}


	this.monthNext=function()
	{
		if( month<11 )
			month++;
		else {
			year++;
			month=0;
		}

		generateRows();
		draw();
	}
	this.monthPrev=function()
	{
		if( month>0 )
			month--;
		else {
			year--;
			month=11;
		}

		generateRows();
		draw();
	}
	this.yearNext=function()
	{
		year++;
		generateRows();
		draw();
	}
	this.yearPrev=function()
	{
		year--;
		generateRows();
		draw();
	}

	div.select('[monthNext]')[0].observe('click',thisObj.monthNext);
	div.select('[monthPrev]')[0].observe('click',thisObj.monthPrev);
	div.select('[yearPrev]')[0].observe('click',thisObj.yearPrev);
	div.select('[yearNext]')[0].observe('click',thisObj.yearNext);

	div.select('[close]')[0].observe('click',thisObj.close);
	div.select('[reset]')[0].observe('click',thisObj.reset);


	var generateRows=function()
	{
		var days=findNumDaysInMonth(year,month);

		var d=new Date();
		d.setMinutes(0);
		d.setSeconds(0);
		d.setHours(0);
		d.setMonth(month);
		d.setYear(year);
		d.setDate(1);

		var n=1;
		var shift=d.getDay();
		shift=shift-1;
		if( shift==-1 ) shift=6;
		n=n-shift;

		rows=new Array();
		for(var i=0;n<=days;i++)
		{
			if( rows.length==0 )
				rows.push(new Array());
			else if( rows.last().length==7 )
				rows.push(new Array());

			if( n>0 )
				rows.last().push(n);
			else
				rows.last().push(0);
			n++;
		}


	}

	var IsLeapYear=function(year)
	{
	   if (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0))
	      return (true);
	   else
	      return (false);
	}
	var findNumDaysInMonth=function(Year, Month)
	{
		if(Month == 1){
		if(IsLeapYear(Year)) return 29;
		else return 28;
		}else{
		if(Month >6) Month++;
		if(Month/2 == Math.round(Month/2)) return 31;
		}
		return 30;
	}

	var isSameDay=function(d1,d2)
	{
		if( d1==null || d2==null )
			return false;
		if( d1.getFullYear()==d2.getFullYear() && d1.getMonth()==d2.getMonth() && d1.getDate()==d2.getDate() )
			return true;
		return false;
	}
	
	this.yearChange=function() {
		year=parseInt(div.select('[year]')[0].down().value);
		generateRows();
		draw();
	}
	this.monthChange=function() {
		month=parseInt(div.select('[month]')[0].down().value);
		generateRows();
		draw();
	}
	
	
	var handleSelect=function(parent, from, to, value, callback, captions, asc) {
		if( Prototype.Browser.IE )
		{
			if( parent.down()!=null && parent.select('[value='+value+']').length==0 ) {
				parent.update('');
				if( from>value )
					from=value;
				if( to<value )
					to=value;

			}
		}

		
		if( parent.down()==null ) {
			parent.appendChild(new Element('select'));
			parent.down().observe('change',callback);
			
			
			var i=to;
			if( asc )
				i=from;
			
			while( i>=from && i<=to ) {
				var o=new Element('option');
				o.writeAttribute('value',""+i);
				if( captions!=null )
					o.update(captions[i]);
				else
					o.update(""+i);
				parent.down().appendChild(o);

				
				
				if( asc )
					i++;
				else
					i--;
			}
			
			
		}
		
		if( parent.select('[value='+value+']').length==0 )
		{
			
			
			var selectElement=parent.down();
			var firstOption=selectElement.down();
			
			
			var newOption=new Element('option');
			newOption.writeAttribute('value',value);
			newOption.value=value;
			if( captions!=null )
				newOption.update(captions[i]);
			else
				newOption.update(""+value);
			
			var tail=parseInt(firstOption.readAttribute('value'))<value;
			
			if( asc ) tail=!tail;
			
			if( tail )
				selectElement.insertBefore(newOption,firstOption);
			else
				selectElement.appendChild(newOption);
		}
		parent.down().value=value;
	}

	var draw=function()
	{
		if( args.yearSelect ) {
			var yearFrom=1950;
			if( args.yearSelectFrom!=null && parseInt(args.yearSelectFrom)>0 )
				yearFrom=parseInt(args.yearSelectFrom);
			
			var yearTo=2020;
			if( args.yearSelectTo!=null && parseInt(args.yearSelectTo)>0 )
				yearTo=parseInt(args.yearSelectTo);
			
			var parent=div.select('[year]')[0];
			
			
			handleSelect(parent,yearFrom,yearTo,year,thisObj.yearChange)
			
			
		}
		else
			div.select('[year]')[0].update(year);
		
		if( args.monthSelect ) {
			var monthFrom=0;
			var monthTo=11;
			
			var parent=div.select('[month]')[0];
			
			
			
			handleSelect(parent,monthFrom,monthTo,month,thisObj.monthChange,["1","2","3","4","5","6","7","8","9","10","11","12"],true)
		}
		else
			div.select('[month]')[0].update(month+1);
		
		
		div.select('[rows]')[0].update("");
		for(var i=0;i<rows.length;i++)
		{
			var row=rows[i];
			var tr=new Element('tr');
			for(var j=0;j<row.length;j++)
			{
				var td=new Element('td');
				if( j==6 )
					td.addClassName('sunday');

				if( j==5 )
					td.addClassName('saturday');

				tr.appendChild(td);


				if( row[j]==0 || row[j]==-1 ) {
					td.addClassName('blank');
					td.update('&nbsp;');
				}



				var d=new Date();
				var dc=new Date();

				dc.setMinutes(0);
				dc.setSeconds(0);
				dc.setHours(0);
				dc.setMonth(month);
				dc.setYear(year);
				if( row[j]>0 )
					dc.setDate(row[j]);
				else
					dc.setDate(1);

				if( row[j]>0 ) {
					if( isSameDay(dc,d) && row[j]>0 )
						td.addClassName('today');
					else if( dc.getTime()>d.getTime() )
						td.addClassName('future');
					else
						td.addClassName('past');
				}

				if( isSameDay(dc,selectedDate) && row[j]>0 )
					td.addClassName('selected');


				if( row[j]>0 ) {
					var a=new Element('a');
					a.href='javascript:;';
					a.observe('click',thisObj.selectDate);
					a.update(row[j]);
					td.appendChild(a);

				}
				else
					td.update('&nbsp;');
			}

			div.select('[rows]')[0].appendChild(tr);

		}

	}

	this.show=function()
	{
		if( div==null )
			return;
		setupCalendar();
		generateRows();
		draw();
		div.show();
		
		
	}

	generateRows();
	div.show();
	div.absolutize();
	div.setStyle({zIndex: 99, top: (args.link.cumulativeOffset()[1]+args.link.getHeight())+"px", left: (args.link.cumulativeOffset()[0]+args.link.getWidth())+"px"});
	draw();

}
// Calendar
//////////////////////////////////


//////////////////////////////////
// Conversion
var Conversion=new Object();
Conversion.stringToDate=function(s) {
	if( s==null )
		return null;
	if( s.empty() )
		return null;
	var ar=null;

	var d=new Date();
	d.setMinutes(0);
	d.setSeconds(0);
	d.setHours(0);

	ar=s.split('/');
	if( ar.length==3 ) {
		d.setYear(parseInt(ar[0]));
		d.setMonth(parseInt(ar[1].trimNumber())-1);
		d.setDate(parseInt(ar[2].trimNumber()));
		return d;
	}
	ar=s.split('-');
	if( ar.length==3 ) {
		d.setDate(parseInt(ar[2].trimNumber()));
		d.setMonth(parseInt(ar[1].trimNumber())-1);
		d.setYear(parseInt(ar[0]));
		return d;
	}
	ar=s.split('.');
	if( ar.length==3 ) {
		d.setYear(parseInt(ar[0]));
		d.setMonth(parseInt(ar[1].trimNumber())-1);
		d.setDate(parseInt(ar[2].trimNumber()));
		return d;
	}
	return null;
}
// Conversion
//////////////////////////////////


//////////////////////////////////
// TrColorChanger
function TrColorChanger()
{
	var trMap=new Array();

	this.onMouseOver2=function(obj,oldColorClass,colorClass)
	{
		if( obj==null )
			return;
		var el=Element.extend(obj);

		var m=new Object();
		trMap[el]=m;

		m.oldColorClass=oldColorClass;
		m.colorClass=colorClass;

		el.removeClassName(oldColorClass);

		el.addClassName(colorClass);
	}

	this.onMouseOut2=function(obj,e)
	{


		var el=Element.extend(obj);

		if( e!=null )
			if( JSWorkspace.isInside(el,[Event.pointerX(e),Event.pointerY(e)]) )
				return;


		var m=trMap[el];
		if( m==null )
			return;

		el.removeClassName(m.colorClass);
		if(m.oldColorClass!=null)
			el.addClassName(m.oldColorClass);
	}


	this.onMouseOver=function(obj,colorClass)
	{
		if( obj==null )
			return;
		var el=Element.extend(obj);

		var m=new Object();
		trMap[el]=m;

		m.removedClasses=new Array();
		m.colorClass=colorClass;
		m.childElements=new Array();

		removeClass(el,m.removedClasses);

		var ar=el.childElements();
		for(var i=0;i<ar.length;i++) {
			var o=new Object();
			o.td=ar[i];
			o.removedClasses=new Array();
			removeClass(o.td,o.removedClasses);

			if( o.removedClasses.length>0 )
				m.childElements.push(o);
		}

		el.addClassName(colorClass);
	}

	var removeClass=function(el,rc) {
		var classes=el.readAttribute('class');
		if( classes==null )
			return;
		var ar=classes.split(' ');
		for(var i=0;i<ar.length;i++)
			if( ar[i].startsWith('color') ) {
				el.removeClassName(ar[i])
				rc.push(ar[i]);
			}
		}

	this.onMouseOut=function(obj,e)
	{


		var el=Element.extend(obj);

		if( e!=null )
			if( JSWorkspace.isInside(el,[Event.pointerX(e),Event.pointerY(e)]) )
				return;


		var m=trMap[el];
		if( m==null )
			return;
		el.removeClassName(m.colorClass);

		for(var i=0;i<m.removedClasses.length;i++)
			el.addClassName(m.removedClasses[i]);

		var ar=m.childElements;
		for(var i=0;i<ar.length;i++) {
			var o=m.childElements[i];
			for(var j=0;j<o.removedClasses.length;j++) {
				o.td.addClassName(o.removedClasses[j]);
			}
		}
	}
}
var GTrColorChanger=new TrColorChanger();
// TrColorChanger
//////////////////////////////////


//////
// Tabbed
function Tabs(container, elements, contents, className)
{
	if( elements.length<2 )
		return;

	this.change=function(n)
	{
		
		n=parseInt(n);
		
		for(var i=0;i<elements.length;i++)
		{
			var tabId=elements[i].readAttribute('tabId');
			var lastTabId=elements[i].readAttribute('lastTabId');

			
			if( tabId==null )
			{
				elements[i].classNames().each( function(name) {elements[i].removeClassName(name);} );
				if( n==lastTabId )
					elements[i].addClassName(className+'LastChecked')
				else
					elements[i].addClassName(className+'Last')
				
			}
		}		
		
		for(var i=0;i<elements.length;i++)
		{
			var tabId=elements[i].readAttribute('tabId');
			var lastTabId=elements[i].readAttribute('lastTabId');
			
			if( tabId!=null )
			{
				elements[i].classNames().each( function(name) {elements[i].removeClassName(name);} );
				
				
				
				if( tabId==n )
				{
					elements[i].addClassName(className+'Checked');
				}
				else if( tabId==(n+1) )
				{
					elements[i].addClassName(className+'PrevChecked');
				}
				else
				{
					elements[i].addClassName(className+'Normal');
				}
			}
		}




		for(var i=0;i<contents.length;i++)
			if( n==i )
				contents[i].show();
			else
				contents[i].hide();
	}
	var thisObj=this;
	this.select=function(e)
	{
		var element=Event.element(e);
		
		while(element!=null )
		{
			if( element.readAttribute('tabId')!=null )
			{
				thisObj.change(element.readAttribute('tabId'));
				return;
			}
			element=element.up();
		}
	}
	container.select('[type=TabLink]').each( function(o) {o.observe('click',thisObj.select)});

	this.change(0);

}
Tabs.scan=function()
{
	var root=Element.extend(document.body);
	
	var l=root.select('[type=TabContainer]');
	
	var elements=new Array();
	for(var i=0;i<l.length;i++)
	{
		var cont=l[i];
		
		var elements=cont.select('[type=TabElement]');
		var contents=cont.select('[type=TabContent]');
		var className=cont.readAttribute('classPrefix');
		
		var o=new Tabs(cont,elements,contents,className);
	}
}




Effect.Scroll = Class.create();
Object.extend(Object.extend(Effect.Scroll.prototype, Effect.Base.prototype), {
  initialize: function(element) {
    this.element = $(element);
    if(!this.element) throw(Effect._elementDoesNotExistError);
    this.start(Object.extend({x: 0, y: 0}, arguments[1] || {}));
  },
  setup: function() {
    var scrollOffsets = (this.element == window) 
                ? document.viewport.getScrollOffsets() 
                : Element._returnOffset(this.element.scrollLeft, this.element.scrollTop) ;
    this.originalScrollLeft = scrollOffsets.left;
    this.originalScrollTop  = scrollOffsets.top;
  },
  update: function(pos) {
    this.element.scrollLeft=Math.round(this.options.x * pos + this.originalScrollLeft);
    this.element.scrollTop=Math.round(this.options.y * pos + this.originalScrollTop);
  }
});



