function mouseCoords(ev){
  ev = ev || window.event;
	if(ev.pageX || ev.pageY){
		return {x:ev.pageX, y:ev.pageY};
	}
  var spos = getScrollXY();
	return {
		x:ev.clientX + spos.x - document.body.clientLeft,
		y:ev.clientY + spos.y - document.body.clientTop
	};
};

function mouseDelta(pos2,pos1)
{
	return {x:pos2.x-pos1.x, y:pos2.y-pos1.y};
};

function getMouseOffset(target, ev){
	ev = ev || window.event;

	var docPos    = getPosition(target);
	var mousePos  = mouseCoords(ev);

	return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
};

function getPosition(e,absolute){
	var left = 0;
	var top  = 0;

	while (e.offsetParent && e.className!='popform') {
		left += e.offsetLeft;
		top  += e.offsetTop;
		e     = e.offsetParent;
	}

	if( e.className!='popform' ) {
		left += e.offsetLeft;
		top  += e.offsetTop;
	}

	return {x:left, y:top};
};

function getDocHeight()
{
	var docHeight;
/*	if (typeof document.height != 'undefined') {
		Debug.add('document.height: '+document.height);
	return document.height;
	}
	else */ if (document.documentElement) {
//		Debug.add('document.documentElement.scrollHeight: '+document.documentElement.scrollHeight);
	return document.documentElement.scrollHeight;
	}
	else if (document.body && typeof document.body.scrollHeight != 'undefined') {
	return document.body.scrollHeight;
	}
	return getSize().cy;
}

function getSize()
{
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  return {cx:myWidth, cy:myHeight};
};

function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return { x:scrOfX, y:scrOfY };
};

function trim(val)
{
	str = new String(val);
	while (str.substr(0,1) == ' ')
		str = str.substr(1, str.length);
	while (str.substr(str.length-1, str.length) == ' ')
		str = str.substr(0,str.length-1);
	return str;
};

var Messages =
{
	mbOkCancel: function(html,icon,onOk,onCancel)
	{
		if( document.documentElement.scrollTop>0 )
			Messages.oldScrTop = document.documentElement.scrollTop;
		document.documentElement.scrollTop = 0;

		if( onOk==undefined || onOk==true ) onOk = Messages.hideOkCancel;
		if( onCancel==undefined || onCancel==true ) onCancel = Messages.hideOkCancel;

		var bOk = onOk;
		var bCancel = onCancel;

		if( !onOk ) onOk=Messages.nothing;
		if( !onCancel ) onCancel=Messages.nothing;


		var d1 = document.createElement('div');
		d1.className = 'okcancel';

		var d2 = document.createElement('div');
		d1.appendChild(d2);

		var ul = document.createElement('ul');
		ul.className = 'clear buttons';

		var li = document.createElement('li');

		var a, iBtns=0;

		if( bOk ) {
			a = document.createElement('a');
			a.className='ok'; a.setAttribute('origClass',a.className);
			a.appendChild(document.createTextNode('ok'));
			a.onclick=onOk;
			li.appendChild(a);
			ul.appendChild(li);
			iBtns++;
		}

		if( bCancel ) {
			li = document.createElement('li');
			a = document.createElement('a');
			a.className='cancel'; a.setAttribute('origClass',a.className);
			a.appendChild(document.createTextNode('cancel'));
			a.onclick=onCancel;
			li.appendChild(a);
			ul.appendChild(li);
			iBtns++;
		}

		d1.appendChild(ul);

		switch( icon )
		{
			case 'error':
				d1.style.backgroundImage = 'url('+Session.vdir+'/img/fwk/error.png)';
				break;
			case 'warn':
				d1.style.backgroundImage = 'url('+Session.vdir+'/img/fwk/warn.png)';
				break;
			case 'info':
				d1.style.backgroundImage = 'url('+Session.vdir+'/img/fwk/info.png)';
				break;
			default:
				d1.style.backgroundImage = 'none';
		}

		if( iBtns ) {
			ul.style.width = (iBtns * 60 + (iBtns-1)*20)+'px';
		}

		d2.innerHTML = html;
		d1.style.display='block';

		document.body.appendChild( d1 );

		Messages.opaque(true,'okcancel');
	},

	mbOk: function( html, icon )
	{

		Messages.mbOkCancel( html, icon, true, false );
	},

	hideOkCancel: function(ev)
	{
		ev         = ev || window.event;
		var target = ev.target || ev.srcElement;

		var e = Node.descendsFromClass(target,'okcancel');
		e.style.display='none';
		document.body.removeChild(e);

		Messages.opaque(false,'okcancel');

		Messages.hide();
	},

	notice: function(html, spin)
	{
		if( document.documentElement.scrollTop>0 )
			Messages.oldScrTop = document.documentElement.scrollTop;
		document.documentElement.scrollTop = 0;

		var notice = document.getElementById('notice');
		notice.innerHTML=(spin?'<img src="'+Session.vdir+'/img/fwk/wait.gif">':'')+'<p>'+html+'</p>';
		notice.style.display='block';
		Messages.opaque(true,'notice');
	},

	opaque: function(show,owner)
	{
		var o = document.getElementById('opaque');

		if( !show && o.getAttribute('owner')==owner)
		{
			o.style.display='none';
		}
		else if( show && o.style.display!='block' )
		{
			o.style.position='absolute';
			o.style.display='block';
			o.style.height=getDocHeight()+'px';
			o.setAttribute('owner',owner);
		}
		else
		{
		}

		return o.style.display!='none';
	},

	hide: function(delay)
	{
		if( delay ) {
			setTimeout('Messages.hide()',delay);
			return;
		}
		else {
			var e = document.getElementById('notice');
			e.style.display='none';
			var b = Messages.opaque(false,'notice');

			if( Messages.oldScrTop )
				document.documentElement.scrollTop = Messages.oldScrTop;
		}

	},

	nothing: function(ev)
	{
	}
};




function message(html)
{
	var msg = document.getElementById('msg');
	msg.innerHTML=html;
};


function error(text)
{
	var err = document.getElementById('error');
	if( err )
	{
		err.innerHTML=text;
		if( text!='' )
			err.style.display='block';
		else
			err.style.display='none';
	}
};

var Msg = {
	clear: function()
	{
		var msg = document.getElementById('msg');
		if( msg ) while( msg.childNodes[0] )
			msg.removeChild( msg.childNodes[0] );
	},

	add: function(t)
	{
		var msg = document.getElementById('msg');
		if( msg ) msg.innerHTML+="<p>"+t+"</p>";
	}
};

var Debug = {
	clear: function()
	{
		var dbo = document.getElementById('debug');
		if( dbo ) while( dbo.childNodes[0] )
			dbo.removeChild( dbo.childNodes[0] );
	},

	show: function(t)
	{
		var dbo = document.getElementById('debug');
		if( dbo ) dbo.innerHTML=t;
	},

	add: function(t)
	{
		var dbo = document.getElementById('debug');
		if( dbo ) dbo.innerHTML+="<p>"+t+"</p>";
	},

	params: function(t)
	{
		var dbo = document.getElementById('debug');
		if( dbo ) {
			str = '';
			for( v in t )
			{
				str +=  v + '=';
				str += t[v] +', ';
			}
			Debug.add( str );
		}
	},

	xmp: function(t)
	{
		var dbo = document.getElementById('debug');
		if( dbo ) dbo.innerHTML+="<xmp>"+t+"</xmp>";
	},

	time: function(msg)
	{
		if( !msg )
			Debug._time = new Date();
		else
		{	var diff = new Date().getTime() - Debug._time.getTime();
			Debug.add(msg+': '+diff+' ms');
		}
	},

	expand: function(t)
	{
		try
		{
			str = '';
			for( v in t )
			{
				str +=  v + '=';
				str += t[v] +', ';
			}
			Debug.add( str );
		}
		catch(e)
		{
			Debug.show(elt);
		}
	},

	_time: null
};


var Format = {
	cost: function(v,showZero) {
		v = parseFloat(v);
		if( isNaN(v) ) return '';
		v = ''+Math.round(v*100)/100;
		if( v=='0' && !showZero ) return '';
		var i= v.indexOf('.');
		if( i==-1 ) v+='.00';
		else if( i==v.length-2 ) v+='0';
		return v;
	},

	percent: function(v,showZero) {
		v = parseFloat(v);
		if( isNaN(v) ) return '';
		v = ''+parseInt(Math.round(v*100));
		if( v=='0' && !showZero ) return '';
		return v+'%';
	},

	pound: function(v,showZero) {
		v = parseFloat(v);
		if( isNaN(v) ) return Format._nbsp;
		v = ''+Math.round(v*100)/100;
		if( v=='0' && !showZero ) return Format._nbsp;
		var i= v.indexOf('.');
		if( i==-1 ) v+='.00';
		else if( i==v.length-2 ) v+='0';
		return Format._pound+v;
	},

	round: function(v) {
		v = parseFloat(v);
		if( isNaN(v) ) return Format._nbsp;
		v = ''+Math.round(v*100)/100;
		return v;
	},

	ucfirst: function(str) {
		var f = str.substr(0,1).toUpperCase();
		var l = str.substr(1).toLowerCase();
		return f+l;
	},

	ucwords: function(str) {
		var list = str.split(' ');
		var f, s='';
		for( var i=0; i<list.length; i++ )
		{
			if( i>0 ) s+=' ';
			s += list[i].substr(0,1).toUpperCase();
			s += list[i].substr(1).toLowerCase();
		}
		return s;
	},

	label: function(str) {
		var re = /_id/gi;
		var s = str.replace(re,'');
		re = /_/gi;
		s = s.replace(re,' ');
		var ss = s.split(' ');
		s='';
		for( var i=0; i<ss.length; i++ )
		{
			if( i>0 ) s+=' ';
			s += ss[i].substr(0,1).toUpperCase();
			s += ss[i].substr(1).toLowerCase();
		}
		re=/ id/;
		return s.replace(re,'');
	},

	inits: function(w) {
		var s = w.split(' ');
		var r = '';
		for( var i=0; i<s.length; i++ )
		{
			r+=s[i].substr(0,1);
		}

		return r.toUpperCase();
	},

	nl2br: function(w) {
		if( !w ) return '';
		var s = w.split("\n");
		var r = '';
		for( var i=0; i<s.length; i++ )
		{
			if( i>0 ) r+='<br />';
			r+=s[i];
		}

		return r;
	},

	frac: function(v) {
		if( v==0.5 ) return Format._half;
		if( v==0.25 ) return Format._quart;
		if( v==0.75 ) return Format._threeq;
		if( v==0.2 ) return "2h";
		return v;
	},

	nbsp: function(s)
	{
		if( s=='' ) return Format._nbsp;
		else return s;
	},

	convert: function( s, t )
	{
		var d2;
		switch( t )
		{
			case 'date':
				if( !s.getStr ) { d2 = new Date(); d2.fromString( s ); }
				else d2 = s;
				return d2.getStr();
			case 'datetime':
				if( !s.getStr ) { d2 = new Date(); d2.fromString( s ); }
				else d2 = s;
				return d2.getStr(true);
			case 'time':
				if( !s.getStr ) { d2 = new Date(); d2.fromString( s ); }
				else d2 = s;
				return d2.getTimeStr();
			default:
				return s;
		}
	},

	_nbsp: "\u00a0",
	_pound: "\u00A3",
	_quart: "\u00BC",
	_half: "\u00BD",
	_threeq: "\u00BE"
};
