//Set up listeners to display animations on the new (master3.css) navigation
var MakeNavItemSwitch = false;
var CountNavSwitches = 0;
$(function(){
	$('.NavItem').bind('mouseover', function(){
		var Name = $(this).attr('NavName');
		SelectNavItem(Name);
	});
	
	$('.NavItem').bind('mouseout', function(){
		MakeNavItemSwitch = true;
		SetNavSwitch();
	});
	
	$('#SubHeaderCenter').bind('mouseover', function(){
		MakeNavItemSwitch = false;
	});
	
	$('#SubHeaderCenter').bind('mouseout', function(){
		MakeNavItemSwitch = true;
		SetNavSwitch();
		setTimeout("SwitchNavItem()", 500);
	});
	
	$('[type=button], [type=submit]').addClass('FormButton');
	$('[type=button], [type=submit]').bind('mouseover', function(){
		$(this).addClass('FormButtonHover');
	});
	$('[type=button], [type=submit]').bind('mouseout', function(){
		$(this).removeClass('FormButtonHover');
	});
	
	AddTextAreaDefault('#SidebarSearch', 'Enter Contact Name');
	
	$('.Warning').hide();
	$('.Warning').each(function(){
		if($(this).hasClass('Verify'))
			$(this).prepend("<img src='/images/icons/tick.png' style=position:relative;top:3px;' /> ");
		else
			$(this).prepend("<img src='/images/icons/information.png' style=position:relative;top:3px;' /> ");
		
	});
	$('.Warning').fadeIn('slow');
});

function SelectNavItem(Name){
	MakeNavItemSwitch = false;
	
	//make sure no other nav items are highlighted
	$('.NavTabLeftHighlighted').removeClass('NavTabLeftHighlighted');
	$('.NavTabCenterHighlighted').removeClass('NavTabCenterHighlighted');
	$('.NavTabRightHighlighted').removeClass('NavTabRightHighlighted');
	
	var jqName = Name.replace(' ', '\\ ');
	
	//if this navigation item wasn't already selected, highlight it
	if(SelectedNav != Name){
		$('#Nav_'+jqName+'_Left').addClass('NavTabLeftHighlighted');
		$('#Nav_'+jqName+'_Center').addClass('NavTabCenterHighlighted');
		$('#Nav_'+jqName+'_Right').addClass('NavTabRightHighlighted');
	}
	
	$('.SubNavItems').hide();
	$('#SubNavItems_'+jqName).show();
}

function SetNavSwitch(){
	CountNavSwitches++;
	setTimeout("SwitchNavItem("+CountNavSwitches+")", 500);
}

function SwitchNavItem(CurrentCount){
	if(CurrentCount != CountNavSwitches)
		return;
	if(MakeNavItemSwitch){
		SelectNavItem(SelectedNav);
	}
}

//Sniff Browser Types
// This script is a simplified adaptation from the
// JavaScript Browser Sniffer
// Eric Krok, Andy King, Michel Plungjan
// see http://www.webreference.com/ for more information

var agt=navigator.userAgent.toLowerCase();
var appVer = navigator.appVersion.toLowerCase();
var is_minor = parseFloat(appVer);
var is_major = parseInt(is_minor);
var iePos = appVer.indexOf('msie');
if (iePos !=-1) {
is_minor = parseFloat(appVer.substring(iePos+5,appVer.indexOf(';',iePos)))
is_major = parseInt(is_minor);
}
var is_getElementById = (document.getElementById) ? "true" : "false";
var is_getElementsByTagName = (document.getElementsByTagName) ? "true" : "false";
var is_documentElement = (document.documentElement) ? "true" : "false";
var is_ie = ((iePos!=-1));
var is_ie3 = (is_ie && (is_major < 4));
var is_ie4 = (is_ie && is_major == 4);
var is_ie4up = (is_ie && is_minor >= 4);
var is_ie5 = (is_ie && is_major == 5);
var is_ie5up = (is_ie && is_minor >= 5);
var is_ie5_5 = (is_ie && (agt.indexOf("msie 5.5") !=-1));
var is_ie5_5up =(is_ie && is_minor >= 5.5);
var is_ie6 = (is_ie && is_major == 6);
var is_ie6up = (is_ie && is_minor >= 6);

var is_safari = navigator.appVersion.search('Safari') != -1 && navigator.appVersion.search('Chrome') == -1;
var is_chrome = navigator.appVersion.search('Chrome') != -1;

function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }   
    }
    return (arrReturnElements)
}

function leftTrim(sString)
{
	while (sString.substring(0,1) == ' ')
		sString = sString.substring(1, sString.length);
	return sString;
}
//Cookies
function GetCookie(find) {
	var cookies = document.cookie.split(";");
	for(var i = 0; i < cookies.length; i++) {
		var crumbs = cookies[i].split("=");
		var name = leftTrim(crumbs[0]);
		var value = crumbs[1];
		if(name == find)
			return value;
	}
	return null;
}

/*
Adds a function to be called during an event on an object.
Works in all major browsers and allows multiple event handlers.  
Examples:
	addEvent(window, 'load', InitFunction);
	addEvent(document.getElementById('thebutton'), 'click', 'ButtonClick');
*/
function addEvent(obj, type, fn) {
	if (obj.addEventListener)
		obj.addEventListener( type, fn, false );
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}

/*
Set a maximum length on textareas.
*/
function setMaxLength() {
	var x = document.getElementsByTagName('textarea');
	var counter = document.createElement('div');
	counter.className = 'counter';
	for (var i=0;i<x.length;i++) {
		if (x[i].getAttribute('maxlength')) {
			var counterClone = counter.cloneNode(true);
			counterClone.relatedElement = x[i];
			counterClone.innerHTML = '<label>&nbsp;</label><span>0</span>/'+x[i].getAttribute('maxlength')+' characters';
			x[i].parentNode.insertBefore(counterClone,x[i].nextSibling);
			x[i].relatedElement = counterClone.getElementsByTagName('span')[0];

			x[i].onkeyup = x[i].onchange = checkMaxLength;
			x[i].onkeyup();
		}
	}
}

function checkMaxLength() {
	var maxLength = this.getAttribute('maxlength');
	var currentLength = this.value.length;
	if (currentLength > maxLength)
		this.value = this.value.substring(0,maxLength);
	else
		this.relatedElement.className = '';
	this.relatedElement.firstChild.nodeValue = currentLength;
	// not innerHTML
	
	if(TextAreaEvent)
		TextAreaEvent();
}

addEvent(window, 'load', setMaxLength);


/*
Opens a window of the correct size named 'demo' going to the address
provided.
*/
function PopupDemo(Link) {
	window.open(Link, 'demo', 'height=850, width=1220, toolbar=yes, location=yes,directories=yes,status=yes,	menubar=yes,scrollbars=yes,resizable=yes');
	return false;
}

/*
Adds a . .. ... . .. ... animation to submit buttons.
*/
var CDCount = 0;
var CDOriginalValue;
var CDOriginalId;

function CreepingDots(Id, FormId) {
	isFormChanged = false;
	CDOriginalValue = document.getElementById(Id).value;
	CDOriginalId = Id;
	document.getElementById(Id).disabled = "disabled";
	setTimeout(AnimateDots, 400);
	document.getElementById(FormId).submit();
}
function AnimateDots() {
	if (CDCount < 3)
		CDCount++;
	else
		CDCount = 0;
	NewValue = CDOriginalValue;
	for (i = 0; i < CDCount; i++) 
		NewValue = " " + NewValue + ".";
	document.getElementById(CDOriginalId).value = NewValue;
	setTimeout(AnimateDots, 400);
}



/*
Find the position, in pixels, of any document element inside the
document body (used to place things absolutely in the right place).
*/
function FindPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

/*
Globals MouseX and MouseY are in document pixel coordinates.
*/
function InitMousePos() {
	if (window.Event && document.captureEvents)
		document.captureEvents(Event.MOUSEMOVE);
	document.onmousemove = GetCursorPos;
}
addEvent(window, 'load', InitMousePos);
var MouseX, MouseY;
function GetCursorPos(e) {
	if (is_ie6)
		return;
    e = e || window.event;
    if (e.pageX || e.pageY) {
        MouseX = e.pageX;
        MouseY = e.pageY;
    } 
    else {
        var de = document.documentElement;
        var b = document.body;
        MouseX = e.clientX + 
            (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
        MouseY = e.clientY + 
            (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
}

/*
Get the visible window size (may or may not contain scrollbars)
*/
function GetFrameSize() {
	if (self.innerWidth) {
		frameWidth = self.innerWidth;
		frameHeight = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientWidth) {
		frameWidth = document.documentElement.clientWidth;
		frameHeight = document.documentElement.clientHeight;
	}
	else if (document.body) {
		frameWidth = document.body.clientWidth;
		frameHeight = document.body.clientHeight;
	}
	return [frameWidth,frameHeight];
}

function GetScrollTop() {
	var ScrollTop = document.body.scrollTop;
	if (ScrollTop == 0) {
	    if (window.pageYOffset)
	        ScrollTop = window.pageYOffset;
	    else
	        ScrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;
	}
	return ScrollTop;
}
function GetScrollLeft() {
	var ScrollLeft = document.body.scrollLeft;
	if (ScrollLeft == 0) {
	    if (window.pageXOffset)
	        ScrollLeft = window.pageXOffset;
	    else
	        ScrollLeft = (document.body.parentElement) ? document.body.parentElement.scrollLeft : 0;
	}
	return ScrollLeft;
}

//Shrink the leftbar and reduce the left margin on the body.
function ShrinkLeftbar() {
	/*
	var body = document.getElementById('body');
	var leftbar = $('#leftbar').get(0);
	
	if(leftbar == null)
		return false;
	
	var showbtn = document.getElementById('showleftbar');
	
	var divArray = document.getElementsByTagName('div');
	var divArrayLen = divArray.length;

	for (var i=0; i<divArrayLen; i++) {
		if (divArray[i].className.substring(0,9) == 'container') {
			var container = divArray[i];
			break;
		}
	}
	
	if(leftbar.style.width == '0px') {
		leftbar.style.width='230px';
		container.style.borderLeftWidth = '240px';
		container.style.paddingLeft = '15px';
		if(showbtn != null)
			body.removeChild(showbtn);
		
		document.cookie = "hideleftbar=0; path=/";
	}
	else {		
		leftbar.style.width='0px';
		container.style.borderLeftWidth = '0';
		container.style.paddingLeft = '32px';
		
		var showbtn = document.createElement('div');
		showbtn.type = 'button';
		showbtn.className = 'button';
		showbtn.onclick = ShrinkLeftbar;
		showbtn.id = 'showleftbar';
		showbtn.style.backgroundColor = '#E5DBCC';
		showbtn.style.cursor = 'pointer';
		showbtn.style.backgroundImage = 'url(https://'+ document.domain +'/images/showtoolbar2.png)';
		showbtn.style.backgroundRepeat = 'no-repeat';
		
		showbtn.style.height = body.offsetHeight+'px';
		showbtn.style.width = '24px';
		showbtn.style.position = 'absolute';
		showbtn.style.left = '0';
		body.insertBefore(showbtn, body.firstChild);
		
		document.cookie = "hideleftbar=1; path=/";
	}	
	*/
}
sfHover = function() {
	if (!document.getElementById("nav"))
		return;
	var sfEls = document.getElementById("nav").getElementsByTagName("LI");
	for (var i=0; i<sfEls.length; i++) {
		sfEls[i].onmouseover=function() {
			this.className+=" sfhover";
		}
		sfEls[i].onmouseout=function() {
			this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
		}
	}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);

function WindowResize() {
	var body = document.getElementById('body');
	var showbtn = document.getElementById('showleftbar');
	if(showbtn != null) 
		showbtn.style.height = body.offsetHeight+'px';
}
addEvent(window, 'resize', WindowResize);

var hide = GetCookie('hideleftbar');
if(hide == 1) {
	$(function() {
		ShrinkLeftbar();
	});
}
/****************************************************************
**                                                             **
**                        AJAX                                 **
**                                                             **
****************************************************************/

//Creates a XMLHttpRequest object in any browser that supports it.
//Returns null on failure.
function CreateRequester() {
	var ret;
	try { ret = new XMLHttpRequest(); }
	catch(error) {
		try { ret = new ActiveXObject("Msxml2.XMLHTTP.5.0"); }
		catch(error) {
			try { ret = new ActiveXObject("Msxml2.XMLHTTP.4.0"); }
			catch(error) {
				ret = null;
			}
		}
	}
	return ret;
}

/*
Usage:

function MyCallIsDone(response, call) {
	jqAlert(response);
}

new AjaxCall("http://whatever", MyCallIsDone);

Optionally, you can set additional attributes on your AjaxCall object, which is passed
into your Done function as the second parameter:

function MyCallIsDone(response, call) {
	jqAlert(call.CustomCal);
}

var c = new AjaxCall("Http://whatever", MyCallIsDone);
c.CustomVal = 123;
*/
function AjaxCall(url, done, post) {
	this._url = url;
	this._done = done;
	this._post = post;
	
	this._request = CreateRequester();
	if(this._request == null) {
		this.Failed = true;
		return;
	}
	
	if(this._post == null)
		this._request.open("GET", url);
	else {
		this._request.open("POST", url, true);
		this._request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this._request.setRequestHeader("Content-length", this._post.length);
		this._request.setRequestHeader("Connection", "close");
	}
	
	this._request.onreadystatechange = function(foo) {
		return function() {
			foo._requestDone();
		}
	}(this);

	this._request.send(this._post);
}
AjaxCall.prototype.Failed = false;
AjaxCall.prototype._url;
AjaxCall.prototype._done;
AjaxCall.prototype._request;
AjaxCall.prototype._post;
AjaxCall.prototype._requestDone = function(e) {
	if(this._request.readyState == 4) {
		if(this._request.status == 200 || this._request.status == 304) {
			this._done(this._request.responseText, this);
		}
		else {
			//Failure.
		}
	}
}

function SetupButtonHovers() {
	$("input.button, button")
		.bind('mouseover', function() {
			$(this).addClass('hover');
		})
		.bind('mouseout', function() {
			$(this).removeClass('hover');
		});
}
addEvent(window, 'load', SetupButtonHovers);


function SetSpanText(c, t) {
	$('span.'+c).each(function(i) {
		if(this.innerHTML.substring(0,1) >= 'a' && this.innerHTML.substring(0,1) <= 'z')
			this.innerHTML = t.toLowerCase();
		else
			this.innerHTML = t;
	});
}

function SelectTab(TabBox, BoxId, TabId){
	for(i=0; i<TabBox.length; i++){
		if(TabBox[i] == TabId){
			
			document.getElementById('tab_'+BoxId+'_'+TabBox[i]).style.display = '';
			document.getElementById('leftTab_'+BoxId+'_'+TabBox[i]).className='leftSelected';
			document.getElementById('mainTab_'+BoxId+'_'+TabBox[i]).className='mainSelected';
			document.getElementById('rightTab_'+BoxId+'_'+TabBox[i]).className='rightSelected';
			document.getElementById('tabText_'+BoxId+'_'+TabBox[i]).className='tabTextSelected';
		}
		else{
			document.getElementById('tab_'+BoxId+'_'+TabBox[i]).style.display = 'none';
			document.getElementById('leftTab_'+BoxId+'_'+TabBox[i]).className='leftTab';
			document.getElementById('mainTab_'+BoxId+'_'+TabBox[i]).className='mainTab';
			document.getElementById('rightTab_'+BoxId+'_'+TabBox[i]).className='rightTab';
			document.getElementById('tabText_'+BoxId+'_'+TabBox[i]).className='tabTextTab';
		}
	}
}

function SelectTabNew(Element){
	//alert($(Element).attr('BoxId'));
	$('.TabContent_'+$(Element).attr('BoxId')).hide();
	$('#tab_'+$(Element).attr('BoxId')+'_'+$(Element).attr('TabId')).show();
	$('.mainSelected').addClass('mainTab');
	$('.mainSelected').removeClass('mainSelected');
	$(Element).addClass('mainSelected');
	$(Element).removeClass('mainTab');
	CurrentTab = $(Element).attr('TabId');
}


function GetFormQueryString(FormFilter) {
	var qs = '';
	$(FormFilter).find(":enabled:input[name][type!=submit][type!=checkbox][type!=radio],input[type=hidden]").each(function() {
		qs += (qs=='' ? '' : '&');
		qs += encodeURIComponent(this.name) + '=' + encodeURIComponent(this.value);
	});
	$(FormFilter).find(":enabled:checked[name]").each(function() {
		qs += (qs=='' ? '' : '&');
		qs += encodeURIComponent(this.name) + '=' + encodeURIComponent(this.value);
	});
	return qs;
}

/*************************************************************
***    Showing/hiding blocks of content
***
***    Call these functions on page load.
**************************************************************/

/*
BlockFilter is a selector that identifies the items to be shown and hidden depending
on whether the check/radio box is checked (e.g. #coinsurancediv).

CheckboxFilter is a selector that identifies the checkbox/radio box that determines
whether the div shows (e.g. #ShowInsuranceCheckbox).

Callback is an optional function that gets called when the checkbox is clicked, which
takes a boolean parameter of whether the div is showing.

ExtraEventFilter is a selector that optionally identifies additional elements whose
click events should trigger a reevaluation of the div's display state, usually identifying
the other radio boxes in the radio group (or unused for checkboxes).
*/
function SetupCheckboxHideableBlock(BlockFilter, CheckboxFilter, Callback, ExtraEventFilter) {
	$(BlockFilter).css({display:($(CheckboxFilter).attr('checked') ? 'block' : 'none')});
	
	$(CheckboxFilter + (ExtraEventFilter!=null ? ','+ExtraEventFilter : '')).bind('click', function() {
		var cb = $(CheckboxFilter).get(0);
		if(Callback == null || Callback(this.checked) != false) {
			if(cb.checked)
				$(BlockFilter).slideDown('slow');
			else
				$(BlockFilter).slideUp('slow');
		}
		else
			cb.checked = !cb.checked;
	});
}


function SetupMultipleCheckboxHideableBlock(BlockFilter, CheckboxFilter, Callback, ExtraEventFilter) {
	$(BlockFilter).css({display:($(CheckboxFilter).attr('checked') ? 'block' : 'none')});

	$(CheckboxFilter + (ExtraEventFilter!=null ? ','+ExtraEventFilter : '')).bind('click', function() {
		//var cb = $(CheckboxFilter).get(0);
		var cb = $(CheckboxFilter).get();
                var isChecked;
                //if (cb.length == 1) cb = cb[0];
                $.each(cb, function() {
                    if(Callback == null || Callback(this.checked) != false) {
                            if(this.checked) {
                                    isChecked = true;
                                    //$(BlockFilter).slideDown('slow');
                                    return false
                            } else {
                                    isChecked = false;
                                    //$(BlockFilter).slideUp('slow');
                            }
                    }
                    else
                            //cb.checked = !cb.checked;
                            isChecked = !this.checked;
                });

                if (isChecked) {
                    $(BlockFilter).slideDown('slow');
                } else {
                    $(BlockFilter).slideUp('slow');
                }

	});
}

function SetupRadioHideableBlockSet(BlockFilters, RadioFilters) {
	for(var i = 0; i < BlockFilters.length; i++) {
		$(BlockFilters[i]).css({display:($(RadioFilters[i]).attr('checked') ? 'block' : 'none')});
		
		$(RadioFilters[i]).bind('click', function(i) { return function() {
			if(this.checked)
				$(BlockFilters[i]).slideDown('slow');
			else
				$(BlockFilters[i]).slideUp('slow');
				
			for(var j = 0; j < BlockFilters.length; j++) {
				if(j == i) 
					continue;
					
				if(!this.checked)
					$(BlockFilters[j]).slideDown('slow');
				else
					$(BlockFilters[j]).slideUp('slow');
			}
		}}(i));
	}
}

function SetupDropdownHideableBlockSet(BlockFilters, DropdownFilter, Values) {
	for(var i = 0; i < BlockFilters.length; i++)
		$(BlockFilters[i]).css({display:($(DropdownFilter).val()==Values[i] ? 'block' : 'none')});
	
	$(DropdownFilter).bind('change', function() {
		for(var i = 0; i < BlockFilters.length; i++) {
			if(this.value == Values[i])
				$(BlockFilters[i]).slideDown('slow');
			else
				$(BlockFilters[i]).slideUp('slow');
		}
	});
}

function SetupDialogEditableBox(DataDivFilter, DialogFilter, TextBoxFilter, EditButtonFilter, FieldName, ScriptURL) {
	$(DialogFilter).dialog({
		autoOpen: false,
		modal: true,
		buttons: {
			Cancel: function() { $(this).dialog('close'); },
			Save: function() {
				new AjaxCall(ScriptURL+FieldName+'='+escape($(TextBoxFilter).val()), function(response, call) {
					$(DataDivFilter).html(response);
					$(DialogFilter).dialog('close');
				});
			}
		},
		width:380,
		height:210
	});	
	$(EditButtonFilter).bind('click', function() {$(DialogFilter).dialog('open')});
}

function jqAlert(msg, title, buttons, width, closeafter) {
	var id = 'jqalertbox_'+Math.floor(Math.random()*100000000);
	if(title == null)
		title = 'ZaneHRA';
	
	if(buttons == null) {
		buttons = {
			Ok: function() { }
		};
	}
	
	//Add $('#'+id).dialog('close');  to the BEGINNING of every button function.
	for(var b in buttons) {
		buttons[b] = function(old) {
			return function() {
				if(closeafter) {
					old();
					$('#'+id).dialog('close');
				}
				else {
					$('#'+id).dialog('close');
					old();
				}
			}
		}(buttons[b]);
	}
	
	if(width == null)
		width = 300;
	
	if(msg.indexOf('<') == -1)
		msg = '<p>'+msg+'</p>';
	
	$('body').append('<div class="dialog" style="left=-10000px; top=-10000px; width:'+width+'px;" id="'+id+'" title="'+title+'">'+msg+'<!--[if lte IE 6.5]><iframe src="/ajax/blank.php"></iframe><![endif]--></div>');
	var h = $("#"+id).get(0).offsetHeight;
	
	$('#'+id).dialog({
		buttons:buttons,
		modal:true,
		width:width+50,
		height:h+100
	}).bind('dialogclose', function() {
		$('#'+id).dialog('destroy');
		$('#'+id).remove();
	});
	
	return $('#'+id);
}

function jqPrompt(msg,val,fn,title,width){var dlg=jqAlert(msg+'<br/><input type="text" id="jqPromptInput"/>',title,{Cancel:function(){},OK:function(){fn(val);}},width);$('#jqPromptInput').val(val).bind('keydown keyup change',function(){val=$('#jqPromptInput').val();}).bind('keydown',function(e){if(e.which==13||e.keyCode==13)
dlg.parent().parent().find('button').eq(1).triggerHandler('click');}).focus().select();}

function SetupConfirmClick(ButtonFilter, msg, OkLabel, okf) {
	$(ButtonFilter).each(function() {
		var TheButton = $(this);
		
		//We have to make a copy of the OkFunction if ButtonFilter has more
		//than one match; otherwise OkFunction gets repeatedly overwritten
		//and every ButtonFilter match will use whatever the last one is.
		var OkFunction = okf;
				
		if(OkLabel == null)
			OkLabel = 'Ok';
		if(OkFunction == null) {
			OkFunction = function() {
				if(TheButton.attr('href') == null)
					TheButton.click();
				else
					window.location = TheButton.attr('href'); //For some reason, click() doesn't work for links here (?!)
			}
		}
		
		TheButton.bind('click', function() {
			if(TheButton.attr('IsConfirmed') == '1')
				return true;
	
			buttons = {};
			buttons['Cancel'] = function() { };
			buttons[OkLabel] = function() { 
				TheButton.attr('IsConfirmed', '1');
				OkFunction();
				TheButton.attr('IsConfirmed', '0');
			};
	
			jqAlert(msg, null, buttons);
			return false;
		});
	});
}

function CreateDialogBox(ButtonId, DialogId, CancelText, ApproveText, ApproveFunction, AutoOpen) {
	if(ButtonId != ''){
		$('#'+ButtonId).bind('click', function(){
			$('#'+DialogId).dialog('open');
		});
	}
	buttons = {};
	buttons[CancelText] = function() { $(this).dialog('close'); };
	buttons[ApproveText] = ApproveFunction;
	
	$('#'+DialogId).dialog({
		autoOpen:AutoOpen,
		buttons:buttons,
		modal:true,
		width:400
	});
}

function ReplaceReportDiv(DivFilter, Content) {
	var pos = FindPos($(DivFilter+'_old').get(0));
	var w = $(DivFilter+'_old').get(0).offsetWidth;
	var h = $(DivFilter+'_old').get(0).offsetHeight;

	$(DivFilter+'_old').css({position:'absolute', left:pos[0], top:pos[1]-13, width:w, height:h});
	
	$(DivFilter+'_old').before(Content);
	$(DivFilter+' a.reportnav').click(function() {
		GrayReportDiv(DivFilter);
	});
	$(DivFilter+' select.reportnav').change(function() {
		GrayReportDiv(DivFilter);
	});
	SetBubbleEvents(DivFilter);
	
	$(DivFilter+'_old').fadeOut(400, function() {
		$(DivFilter+'_old').remove();
	});
}

var GrayReportDivHooks = [];

function GrayReportDiv(DivFilter) {
	var pos = FindPos($(DivFilter).get(0));
	var w = $(DivFilter).get(0).offsetWidth;
	var h = $(DivFilter).get(0).offsetHeight;
	$(DivFilter+" table").fadeTo(200, .5);

	for(var i = 0; i < GrayReportDivHooks.length; i++)
		GrayReportDivHooks[i](DivFilter);
	
	$(DivFilter).get(0).id = $(DivFilter).get(0).id+'_old';
}

/****************************************************
**
**	Replacement for setTimeout that actually 
**	uses _functions_ instead of strings.
**
****************************************************/ 
function setTimerFunction(milliseconds, callback) {
	var id;
	for (id=0; id<timeoutData.length; id++)	{
		if (timeoutData[id] == null)
			break;
	}
	var td = timeoutData[id] = {args:[]};
	td.callback = callback;

	for (var i=2; i<arguments.length; i++)
		td.args[i-2] = arguments[i];
	td.handle = setTimeout("callbackForSetTimeout(" + id + ")", milliseconds);
	return id;
}

function setTimerFunctionThisObject(id, thisObject) {
	var td = timeoutData[id];
	if (td)	
		td.thisObject = thisObject;
	return id;
}

function cancelTimerFunction(id) {
	var a = timeoutData, td = a[id];
	if (td)	{
		clearTimeout (td.handle);
		if (id == a.length-1)
			a.pop();
		else
			delete a[id];
	}
}

function callbackForSetTimeout(id) {
	var  a = timeoutData, td = a[id];
	td.callback.apply (td.thisObject, td.args);
	if (id == a.length-1)
		a.pop();
	else
		delete a[id];
}

var timeoutData = [];

/****************************************************
**
**	Used to do expensive (e.g. Ajax) things after 
**  one of a number of form elements has changed.
**
**  Create a ConsolidatedFunctionCall object with
**  the millisecond timeout and function to be
**  called, then set the .Queue() as the onchange,
**  onkeyup, whatever events of every related form
**  element.
**
****************************************************/ 

function ConsolidatedFunctionCall(timeout, foo) {
	this._foo = foo;
	this._timeout = timeout;
	this._count = 0;
}
ConsolidatedFunctionCall.prototype._foo;
ConsolidatedFunctionCall.prototype._timeout;
ConsolidatedFunctionCall.prototype._count;
ConsolidatedFunctionCall.prototype.Queue = function(timeout) {
	if(timeout == null)
		timeout = this._timeout;
	
	this._count++;
	var id = setTimerFunction(timeout, function() {
		this._count--;
		if(this._count > 0)
			return;
		this._foo();
	});
	setTimerFunctionThisObject(id, this);
}




$(function() {
	$('.fadeinimage')
		.each(function() {
			$(this).wrap('<div style="width:'+this.offsetWidth+'px;height:'+this.offsetHeight+'px;"></div>');
		})
		.css({
			display:'none'
		})
		.load(function() {
			$(this).fadeIn('slow');
		})
	;
});


function HelpOnClickToggle(divId,relatedCheckBoxId) {
	var keepopen = false;
	
	if ( $('#'+relatedCheckBoxId).is(':checked')) {
		keepopen = true;
	}
	
	if ( $('#'+divId).children('input[type=checkbox]').is(':checked') ) {
		keepopen = true;
	}
	if ( $('#'+divId).children('input[type=radio]').is(':checked') ) {
		keepopen = true;
	}
	$('#'+divId).children('input[type=text]').each(function (i) {
		if (this.value != '') {
			keepopen = true;
		}
	});

	if (keepopen == false) {
		$("#"+divId).slideToggle("slow");
	}
}

/***************************************
****************************************
		Autocomplete text areas
***************************************
***************************************/
var SelectedAutoComplete = 0;
var CurrentAutoCompleteValue = '';
var CurrentAutoComplete = '';
var FocusedAutoCompleteElement = '';

function AutoComplete(Selector, Type){
	var PendingSearch = null;
	var SearchIsRunning = false;
	function DoSearch(Text) {
		PendingSearch = Text;
		
		if(SearchIsRunning)
			return;
		
		SearchIsRunning = true;
		
		Text = PendingSearch;
		PendingSearch = null;
		$.post('/ajax/autocomplete/'+Type, {Text:Text}, function(data) {
			DisplayAutoComplete(data);
			SearchIsRunning = false;
			
			if(PendingSearch != null)
				DoSearch(PendingSearch);
		});
	}
	
	$(Selector).bind('focus', function(){
		EndAutoComplete();
		CurrentAutoCompleteValue = '';
		CurrentAutoComplete = Selector;
		$(Selector).after("<div class='AutoComplete'><div align='center'><img src='/images/dashboard/throbber.gif' /></div></div>");
		$('.AutoComplete').css('left', $(Selector).position().left);
		$('.AutoComplete').css('top', $(Selector).position().top+22);
		$('.AutoComplete').width($(Selector).width());
		DoSearch($(Selector).val());
		
		SelectedAutoComplete = 0;
		
		$(document).bind('keydown', 'down', function(){
			if(FocusedAutoCompleteElement == Selector){
				NewSelected = $('#AutoCompleteOption_'+(SelectedAutoComplete+1));
				if(NewSelected.length > 0){
					SelectedAutoComplete++;
					HighlightAutoComplete(SelectedAutoComplete);
				}
				return false;
			}
		});
		$(document).bind('keydown', 'up', function(){
			if(FocusedAutoCompleteElement == Selector){
				if(SelectedAutoComplete > 0)
					SelectedAutoComplete--;
				HighlightAutoComplete(SelectedAutoComplete);
				
				return false;
			}
		});
		$(document).bind('keydown', 'tab', function(){
			if(FocusedAutoCompleteElement == Selector){
				SelectedElement = $('.HighlightedAutoComplete');
				
				if(SelectedElement.length > 0){
					$(Selector).val(SelectedElement.children('.AutoCompleteNewText').html());
					$('.AutoComplete').hide();
					$(Selector).change();
					return false;
				}
				else{
					EndAutoComplete();
				}
			}
		});
		$(document).bind('keydown', 'return', function(){
			if(FocusedAutoCompleteElement == Selector){
				SelectedElement = $('.HighlightedAutoComplete');
				
				if(SelectedElement.length > 0){
					$(Selector).val(SelectedElement.children('.AutoCompleteNewText').html());
					$('.AutoComplete').hide();
					$(Selector).change();
					return false;
				}
				else{
					EndAutoComplete();
				}
			}
		});
		
		$(Selector).bind('keyup', function(event){		
			NewText = $(Selector).val();
			if(NewText != CurrentAutoCompleteValue){
				CurrentAutoCompleteValue = NewText;
				SelectedAutoComplete = 0;
				DoSearch(NewText);
			}
		});
	});
	
	$(Selector).bind('focus', function(){
		FocusedAutoCompleteElement = Selector;
	});
	
	$(Selector).bind('blur', function(){
		setTimeout('EndAutoComplete()', 400);
		FocusedAutoCompleteElement = '';
	});
}

function DisplayAutoComplete(Text){
	$('.AutoComplete').html(Text);
	SelectedAutoComplete = 0;
	if(Text == '')
		$('.AutoComplete').hide();
	else
		$('.AutoComplete').show();
	
	$('.AutoCompleteOption').bind('click', function(){
		$(CurrentAutoComplete).val($(this).children('.AutoCompleteNewText').html());
		$('.AutoComplete').hide();
		$(CurrentAutoComplete).change();
		EndAutoComplete();
	});
}

function HighlightAutoComplete(Number){
	$('.HighlightedAutoComplete').removeClass('HighlightedAutoComplete');
	$('#AutoCompleteOption_'+Number).addClass('HighlightedAutoComplete');
}

function EndAutoComplete(){
	$('.AutoComplete').remove();
}

/*
Call this function on a form field to add text that will appear until they first
click on the field
*/
function AddTextAreaDefault(Selector, DefaultText){
	$(Selector).each(function(){
		if($(this).val() == '' || $(this).val() == DefaultText){
			$(this).css('color', '#999999');
			$(this).val(DefaultText);
			$(this).css('color', '#999999');
			$(this).bind('focus', function(){
				if($(this).css('color') == '#999999' || DefaultText == $(this).val()){
					$(this).val('');
					$(this).css('color', '#333333');
				}
			});
			$(this).bind('blur', function(){
				if($(this).val() == ''){
					$(this).val(DefaultText);
					$(this).css('color', '#999999');
				}
			});
		}
	});
}




function CallAPI(Function, Params, Callback) {
	var data = 'Function='+encodeURIComponent(Function);
	for(var i = 0; i < Params.length; i++) {
		if(typeof(Params[i]) == 'object') {
			data += '&Params[]='+encodeURIComponent(JSON.stringify(Params[i]));
			data += '&ObjectParams[]='+i;
		}
		else
			data += '&Params[]='+encodeURIComponent(Params[i]);
	}
	
	$.ajax({
		type:'POST',
		url:'/ajax/api.php',
		data:data,
		success:function(msg) {
			if(Callback != null)
				Callback(JSON.parse(msg));
		}
	});
}


function setTimeoutFunction(f, t) {
	var i = setInterval(function() {
		clearInterval(i);
		f();
	}, t);
}

function unserialize(data){
    // http://kevin.vanzonneveld.net
    // +     original by: Arpad Ray (mailto:arpad@php.net)
    // +     improved by: Pedro Tainha (http://www.pedrotainha.com)
    // +     bugfixed by: dptr1988
    // +      revised by: d3x
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // %            note: We feel the main purpose of this function should be to ease the transport of data between php & js
    // %            note: Aiming for PHP-compatibility, we have to translate objects to arrays 
    // *       example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    // *       returns 1: ['Kevin', 'van', 'Zonneveld']
    // *       example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
    // *       returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
    
    var error = function (type, msg, filename, line){throw new window[type](msg, filename, line);};
    var read_until = function (data, offset, stopchr){
        var buf = [];
        var chr = data.slice(offset, offset + 1);
        var i = 2;
        while (chr != stopchr) {
            if ((i+offset) > data.length) {
                error('Error', 'Invalid');
            }
            buf.push(chr);
            chr = data.slice(offset + (i - 1),offset + i);
            i += 1;
        }
        return [buf.length, buf.join('')];
    };
    var read_chrs = function (data, offset, length){
        var buf;
        
        buf = [];
        for(var i = 0;i < length;i++){
            var chr = data.slice(offset + (i - 1),offset + i);
            buf.push(chr);
        }
        return [buf.length, buf.join('')];
    };
    var _unserialize = function (data, offset){
        var readdata;
        var readData;
        var chrs = 0;
        var ccount;
        var stringlength;
        var keyandchrs;
        var keys;
 
        if(!offset) offset = 0;
        var dtype = (data.slice(offset, offset + 1)).toLowerCase();
        
        var dataoffset = offset + 2;
        var typeconvert = new Function('x', 'return x');
        
        switch(dtype){
            case "i":
                typeconvert = new Function('x', 'return parseInt(x)');
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case "b":
                typeconvert = new Function('x', 'return (parseInt(x) == 1)');
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case "d":
                typeconvert = new Function('x', 'return parseFloat(x)');
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
            break;
            case "n":
                readdata = null;
            break;
            case "s":
                ccount = read_until(data, dataoffset, ':');
                chrs = ccount[0];
                stringlength = ccount[1];
                dataoffset += chrs + 2;
                
                readData = read_chrs(data, dataoffset+1, parseInt(stringlength));
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 2;
                if(chrs != parseInt(stringlength) && chrs != readdata.length){
                    error('SyntaxError', 'String length mismatch');
                }
            break;
            case "a":
                readdata = {};
                
                keyandchrs = read_until(data, dataoffset, ':');
                chrs = keyandchrs[0];
                keys = keyandchrs[1];
                dataoffset += chrs + 2;
                
                for(var i = 0;i < parseInt(keys);i++){
                    var kprops = _unserialize(data, dataoffset);
                    var kchrs = kprops[1];
                    var key = kprops[2];
                    dataoffset += kchrs;
                    
                    var vprops = _unserialize(data, dataoffset);
                    var vchrs = vprops[1];
                    var value = vprops[2];
                    dataoffset += vchrs;
                    
                    readdata[key] = value;
                }
                
                dataoffset += 1;
            break;
            default:
                error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
            break;
        }
        return [dtype, dataoffset - offset, typeconvert(readdata)];
    };
    return _unserialize(data, 0)[2];
}



function strtotime (str, now) {
    // Convert string representation of date and time to a timestamp  
    // 
    // version: 908.406
    // discuss at: http://phpjs.org/functions/strtotime
    // +   original by: Caio Ariede (http://caioariede.com)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: David
    // +   improved by: Caio Ariede (http://caioariede.com)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Wagner B. Soares
    // %        note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
    // *     example 1: strtotime('+1 day', 1129633200);
    // *     returns 1: 1129719600
    // *     example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
    // *     returns 2: 1130425202
    // *     example 3: strtotime('last month', 1129633200);
    // *     returns 3: 1127041200
    // *     example 4: strtotime('2009-05-04 08:30:00');
    // *     returns 4: 1241418600
    var i, match, s, strTmp = '', parse = '';

    strTmp = str;
    strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
    strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars

    if (strTmp == 'now') {
        return (new Date()).getTime()/1000; // Return seconds, not milli-seconds
    } else if (!isNaN(parse = Date.parse(strTmp))) {
        return (parse/1000);
    } else if (now) {
        now = new Date(now*1000); // Accept PHP-style seconds
    } else {
        now = new Date();
    }

    strTmp = strTmp.toLowerCase();

    var __is =
    {
        day:
        {
            'sun': 0,
            'mon': 1,
            'tue': 2,
            'wed': 3,
            'thu': 4,
            'fri': 5,
            'sat': 6
        },
        mon:
        {
            'jan': 0,
            'feb': 1,
            'mar': 2,
            'apr': 3,
            'may': 4,
            'jun': 5,
            'jul': 6,
            'aug': 7,
            'sep': 8,
            'oct': 9,
            'nov': 10,
            'dec': 11
        }
    };

    var process = function (m) {
        var ago = (m[2] && m[2] == 'ago');
        var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);

        switch (m[0]) {
            case 'last':
            case 'next':
                switch (m[1].substring(0, 3)) {
                    case 'yea':
                        now.setFullYear(now.getFullYear() + num);
                        break;
                    case 'mon':
                        now.setMonth(now.getMonth() + num);
                        break;
                    case 'wee':
                        now.setDate(now.getDate() + (num * 7));
                        break;
                    case 'day':
                        now.setDate(now.getDate() + num);
                        break;
                    case 'hou':
                        now.setHours(now.getHours() + num);
                        break;
                    case 'min':
                        now.setMinutes(now.getMinutes() + num);
                        break;
                    case 'sec':
                        now.setSeconds(now.getSeconds() + num);
                        break;
                    default:
                        var day;
                        if (typeof (day = __is.day[m[1].substring(0, 3)]) != 'undefined') {
                            var diff = day - now.getDay();
                            if (diff == 0) {
                                diff = 7 * num;
                            } else if (diff > 0) {
                                if (m[0] == 'last') {diff -= 7;}
                            } else {
                                if (m[0] == 'next') {diff += 7;}
                            }
                            now.setDate(now.getDate() + diff);
                        }
                }
                break;

            default:
                if (/\d+/.test(m[0])) {
                    num *= parseInt(m[0], 10);

                    switch (m[1].substring(0, 3)) {
                        case 'yea':
                            now.setFullYear(now.getFullYear() + num);
                            break;
                        case 'mon':
                            now.setMonth(now.getMonth() + num);
                            break;
                        case 'wee':
                            now.setDate(now.getDate() + (num * 7));
                            break;
                        case 'day':
                            now.setDate(now.getDate() + num);
                            break;
                        case 'hou':
                            now.setHours(now.getHours() + num);
                            break;
                        case 'min':
                            now.setMinutes(now.getMinutes() + num);
                            break;
                        case 'sec':
                            now.setSeconds(now.getSeconds() + num);
                            break;
                    }
                } else {
                    return false;
                }
                break;
        }
        return true;
    };

    match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
    if (match != null) {
        if (!match[2]) {
            match[2] = '00:00:00';
        } else if (!match[3]) {
            match[2] += ':00';
        }

        s = match[1].split(/-/g);

        for (i in __is.mon) {
            if (__is.mon[i] == s[1] - 1) {
                s[1] = i;
            }
        }
        s[0] = parseInt(s[0], 10);

        s[0] = (s[0] >= 0 && s[0] <= 69) ? '20'+(s[0] < 10 ? '0'+s[0] : s[0]+'') : (s[0] >= 70 && s[0] <= 99) ? '19'+s[0] : s[0]+'';
        return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2])+(match[4] ? match[4]/1000 : ''), 10);
    }

    var regex = '([+-]?\\d+\\s'+
        '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?'+
        '|sun\.?|sunday|mon\.?|monday|tue\.?|tuesday|wed\.?|wednesday'+
        '|thu\.?|thursday|fri\.?|friday|sat\.?|saturday)'+
        '|(last|next)\\s'+
        '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?'+
        '|sun\.?|sunday|mon\.?|monday|tue\.?|tuesday|wed\.?|wednesday'+
        '|thu\.?|thursday|fri\.?|friday|sat\.?|saturday))'+
        '(\\sago)?';

    match = strTmp.match(new RegExp(regex, 'g'));
    if (match == null) {
        return false;
    }

    for (i in match) {
        if (!process(match[i].split(' '))) {
            return false;
        }
    }

    return (now.getTime()/1000);
}


function date ( format, timestamp ) {
    // Format a local date/time  
    // 
    // version: 908.406
    // discuss at: http://phpjs.org/functions/date
    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: MeEtc (http://yass.meetcweb.com)
    // +   improved by: Brad Touesnard
    // +   improved by: Tim Wiel
    // +   improved by: Bryan Elliott
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: David Randall
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   derived from: gettimeofday
    // %        note 1: Uses global: php_js to store the default timezone
    // *     example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    // *     returns 1: '09:09:40 m is month'
    // *     example 2: date('F j, Y, g:i a', 1062462400);
    // *     returns 2: 'September 2, 2003, 2:26 am'
    // *     example 3: date('Y W o', 1062462400);
    // *     returns 3: '2003 36 2003'
    // *     example 4: x = date('Y m d', (new Date()).getTime()/1000); // 2009 01 09
    // *     example 4: (x+'').length == 10
    // *     returns 4: true
    var that = this;
    var jsdate=(
        (typeof(timestamp) == 'undefined') ? new Date() : // Not provided
        (typeof(timestamp) == 'number') ? new Date(timestamp*1000) : // UNIX timestamp
        new Date(timestamp) // Javascript Date()
    ); // , tal=[]
    var pad = function (n, c){
        if ( (n = n + "").length < c ) {
            return new Array(++c - n.length).join("0") + n;
        } else {
            return n;
        }
    };
    var _dst = function (t) {
        // Calculate Daylight Saving Time (derived from gettimeofday() code)
        var dst=0;
        var jan1 = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0);  // jan 1st
        var june1 = new Date(t.getFullYear(), 6, 1, 0, 0, 0, 0); // june 1st
        var temp = jan1.toUTCString();
        var jan2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));
        temp = june1.toUTCString();
        var june2 = new Date(temp.slice(0, temp.lastIndexOf(' ')-1));
        var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60);
        var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60);

        if (std_time_offset === daylight_time_offset) {
            dst = 0; // daylight savings time is NOT observed
        }
        else {
            // positive is southern, negative is northern hemisphere
            var hemisphere = std_time_offset - daylight_time_offset;
            if (hemisphere >= 0) {
                std_time_offset = daylight_time_offset;
            }
            dst = 1; // daylight savings time is observed
        }
        return dst;
    };
    var ret = '';
    var txt_weekdays = ["Sunday","Monday","Tuesday","Wednesday",
        "Thursday","Friday","Saturday"];
    var txt_ordin = {1:"st",2:"nd",3:"rd",21:"st",22:"nd",23:"rd",31:"st"};
    var txt_months =  ["", "January", "February", "March", "April",
        "May", "June", "July", "August", "September", "October", "November",
        "December"];

    var f = {
        // Day
            d: function (){
                return pad(f.j(), 2);
            },
            D: function (){
                var t = f.l();
                return t.substr(0,3);
            },
            j: function (){
                return jsdate.getDate();
            },
            l: function (){
                return txt_weekdays[f.w()];
            },
            N: function (){
                return f.w() + 1;
            },
            S: function (){
                return txt_ordin[f.j()] ? txt_ordin[f.j()] : 'th';
            },
            w: function (){
                return jsdate.getDay();
            },
            z: function (){
                return (jsdate - new Date(jsdate.getFullYear() + "/1/1")) / 864e5 >> 0;
            },

        // Week
            W: function (){
                var a = f.z(), b = 364 + f.L() - a;
                var nd2, nd = (new Date(jsdate.getFullYear() + "/1/1").getDay() || 7) - 1;

                if (b <= 2 && ((jsdate.getDay() || 7) - 1) <= 2 - b){
                    return 1;
                } 
                if (a <= 2 && nd >= 4 && a >= (6 - nd)){
                    nd2 = new Date(jsdate.getFullYear() - 1 + "/12/31");
                    return that.date("W", Math.round(nd2.getTime()/1000));
                }
                return (1 + (nd <= 3 ? ((a + nd) / 7) : (a - (7 - nd)) / 7) >> 0);
            },

        // Month
            F: function (){
                return txt_months[f.n()];
            },
            m: function (){
                return pad(f.n(), 2);
            },
            M: function (){
                var t = f.F();
                return t.substr(0,3);
            },
            n: function (){
                return jsdate.getMonth() + 1;
            },
            t: function (){
                var n;
                if ( (n = jsdate.getMonth() + 1) == 2 ){
                    return 28 + f.L();
                }
                if ( n & 1 && n < 8 || !(n & 1) && n > 7 ){
                    return 31;
                }
                return 30;
            },

        // Year
            L: function (){
                var y = f.Y();
                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
            },
            o: function (){
                if (f.n() === 12 && f.W() === 1) {
                    return jsdate.getFullYear()+1;
                }
                if (f.n() === 1 && f.W() >= 52) {
                    return jsdate.getFullYear()-1;
                }
                return jsdate.getFullYear();
            },
            Y: function (){
                return jsdate.getFullYear();
            },
            y: function (){
                return (jsdate.getFullYear() + "").slice(2);
            },

        // Time
            a: function (){
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function (){
                return f.a().toUpperCase();
            },
            B: function (){
                // peter paul koch:
                var off = (jsdate.getTimezoneOffset() + 60)*60;
                var theSeconds = (jsdate.getHours() * 3600) +
                                 (jsdate.getMinutes() * 60) +
                                  jsdate.getSeconds() + off;
                var beat = Math.floor(theSeconds/86.4);
                if (beat > 1000) {
                    beat -= 1000;
                }
                if (beat < 0) {
                    beat += 1000;
                }
                if ((String(beat)).length == 1) {
                    beat = "00"+beat;
                }
                if ((String(beat)).length == 2) {
                    beat = "0"+beat;
                }
                return beat;
            },
            g: function (){
                return jsdate.getHours() % 12 || 12;
            },
            G: function (){
                return jsdate.getHours();
            },
            h: function (){
                return pad(f.g(), 2);
            },
            H: function (){
                return pad(jsdate.getHours(), 2);
            },
            i: function (){
                return pad(jsdate.getMinutes(), 2);
            },
            s: function (){
                return pad(jsdate.getSeconds(), 2);
            },
            u: function (){
                return pad(jsdate.getMilliseconds()*1000, 6);
            },

        // Timezone
            e: function () {
/*                var abbr='', i=0;
                if (this.php_js && this.php_js.default_timezone) {
                    return this.php_js.default_timezone;
                }
                if (!tal.length) {
                    tal = this.timezone_abbreviations_list();
                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {
                            return tal[abbr][i].timezone_id;
                        }
                    }
                }
*/
                return 'UTC';
            },
            I: function (){
                return _dst(jsdate);
            },
            O: function (){
               var t = pad(Math.abs(jsdate.getTimezoneOffset()/60*100), 4);
               t = (jsdate.getTimezoneOffset() > 0) ? "-"+t : "+"+t;
               return t;
            },
            P: function (){
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },
            T: function () {
/*                var abbr='', i=0;
                if (!tal.length) {
                    tal = that.timezone_abbreviations_list();
                }
                if (this.php_js && this.php_js.default_timezone) {
                    for (abbr in tal) {
                        for (i=0; i < tal[abbr].length; i++) {
                            if (tal[abbr][i].timezone_id === this.php_js.default_timezone) {
                                return abbr.toUpperCase();
                            }
                        }
                    }
                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {
                            return abbr.toUpperCase();
                        }
                    }
                }
*/
                return 'UTC';
            },
            Z: function (){
               return -jsdate.getTimezoneOffset()*60;
            },

        // Full Date/Time
            c: function (){
                return f.Y() + "-" + f.m() + "-" + f.d() + "T" + f.h() + ":" + f.i() + ":" + f.s() + f.P();
            },
            r: function (){
                return f.D()+', '+f.d()+' '+f.M()+' '+f.Y()+' '+f.H()+':'+f.i()+':'+f.s()+' '+f.O();
            },
            U: function (){
                return Math.round(jsdate.getTime()/1000);
            }
    };

    return format.replace(/[\\]?([a-zA-Z])/g, function (t, s){
        if ( t!=s ){
            // escaped
            ret = s;
        } else if (f[s]){
            // a date function exists
            ret = f[s]();
        } else {
            // nothing special
            ret = s;
        }
        return ret;
    });
}

function ValidateEmail(String){
	if(String.search(/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/)==-1){
		return false;
	}
	return true;
}

function ValidatePhone(String){
	if(String.search(/^(1?.?[0-9][0-9][0-9].?)? ?[0-9][0-9][0-9].?[0-9][0-9][0-9][0-9]( ?(x|ext) ?[0-9]*)?$/)==-1){
		return false;
	}
	return true;
}

function ValidatePassword(String){
	if(String.search(/^(?=^.{6,}$)((?=.*[A-Za-z])(?=.*[0-9]))^.*$/)==-1){
		return false;
	}
	return true;
}
