var aMonths=['January','February','March','April','May','June','July','August','September','October','November','December'];  
var aWeekdays=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; 

var b64s='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var b64 = [];
var f64 =[];
for (var i=0; i<b64s.length ;i++) {
	b64[i] = b64s.charAt(i);
	f64[b64s.charAt(i)] = i;
}

function atobJS(sInput){
	var sOutput=[]; var i=0;
	sInput=sInput.replace(/\n|\r/g,""); sInput=sInput.replace(/=/g,"");
	while (i<sInput.length){
		sOutput += String.fromCharCode((f64[sInput.charAt(i)]<<2) | (f64[sInput.charAt(i+1)]>>4));
		sOutput += String.fromCharCode((((f64[sInput.charAt(i+1)]&15)<<4) | (f64[sInput.charAt(i+2)]>>2)));
		sOutput += String.fromCharCode((((f64[sInput.charAt(i+2)]&3)<<6) | (f64[sInput.charAt(i+3)])));
		i+=4;
	}
	if (sInput.length%4 == 2)
		sOutput = sOutput.substr(0, sOutput.length-2);
	if (sInput.length%4 == 3)
		sOutput = sOutput.substr(0, sOutput.length-1);
	return sOutput;
	
}

function debugAlert(sAlert){

	if (oDiv=document.getElementById('JSDebugDiv')){
		oDiv.style.backgroundColor='#ffffff';
		oDiv.innerHTML=oDiv.innerHTML+'<br/>'+sAlert;
	}
}

function print_r(xSubject,iIndent,xLabel){
	sRet='';
	if (!iIndent)
		var iIndent=0;
	var i=iIndent;
	while (i>0){
		sRet+='&nbsp;&nbsp;';
		i--;
	}
	if (xLabel)
		sRet+=xLabel+': ';
	sRet+=xSubject+' ('+typeof(xSubject)+')<br/>';

	if ((typeof(xSubject) == 'object'))
		for (var x in xSubject)
			sRet+=print_r(xSubject[x],iIndent+1,x);
	
	return sRet;
}

function compareOptionAsc(oOption1, oOption2) {
	if (oOption1.sText.toLowerCase() > oOption2.sText.toLowerCase())
		return (1);
	else if (oOption1.sText.toLowerCase() < oOption2.sText.toLowerCase())
		return (-1);
	else
		return (0);
}

function sortSelect(oSelect) {

	aOptions = [];
	for (i=0; i < oSelect.options.length; i++) {
		aOptions[i] = { 
			sText:oSelect.options[i].text, 
			sValue:oSelect.options[i].value 
		};
	}

	aOptions.sort(compareOptionAsc);

	for (i=0; i < oSelect.options.length; i++) {
		oSelect.options[i].text = aOptions[i].sText;
		oSelect.options[i].value = aOptions[i].sValue;
	}
}

function ensureNumeric(oInput){
	oInput.value=oInput.value.replace(",",".");
	oInput.value=(isNaN(oInput.value) ? 0 : oInput.value);
	oInput.value=(oInput.value*1).toFixed(2);
}

function ensurePositiveNumeric(oInput){
	oInput.value=oInput.value.replace(",",".");
	oInput.value=(isNaN(oInput.value) ? 0 : oInput.value);
	if (oInput.value <0)
		oInput.value=0;
	oInput.value=(oInput.value*1).toFixed(2);
}

function ensureInteger(oInput){
	oInput.value=oInput.value.replace(",",".");
	oInput.value=(isNaN(oInput.value) ? 0 : parseInt(oInput.value));
}

function ensurePositiveInteger(oInput){
	oInput.value=oInput.value.replace(",",".");
	oInput.value=(isNaN(oInput.value) ? 0 : parseInt(oInput.value));
	if (oInput.value <0)
		oInput.value=0;
}

function ensureDate(oInput){
}

function ensureEmail(oInput){
	if (!(/^\w+([\.-]?\w+)*(\.\w{2,5})+$/.test(oInput.value)))
		oInput.value='invalid.email@nonexistent.domain';
}

function varByName(sName){
	return eval('(window.'+sName+')?'+sName+':null');
}

function getDaysInMonth(iYear,iMonth) {
	switch (iMonth){
		case 0:
		case 2:
		case 4:
		case 6:
		case 7:
		case 9:
		case 11:
			return 31;
			break;
		case 3:
		case 5:
		case 8:
		case 10:
			return 30;
			break;
		case 1:
			if (iYear%4==0){
				if (((iYear%100)==0)&&((iYear%400)!=0)){
					return 28;
				}else{
					return 29;
				}
			}else{
				return 28;
			}
			break;
		default:
			return 0;
	}
}

function renderCalendar(iTS,sCaller,sHideDiv,bInit){
	
	if (bInit){
		if (oCaller=document.getElementById(sCaller)){
			if ("value" in oCaller){
				var iTSTemp=(isNaN(oCaller.value) ? 0 : parseInt(oCaller.value));
				if (iTSTemp!=0)
					iTS=iTSTemp;
			}
		}
	}

	var oDate=new Date();
	oDate.setTime(iTS*1000);
	iMonth=oDate.getMonth();
	iYear=oDate.getFullYear();


	if(iMonth <0){
		iMonth=0;
	}else if(iMonth >11){
		iMonth=11;
	}

	if(iYear<1902){
		iYear=1902;
		iMonth=0;
	}else if(iYear>2037){
		iYear=2037;
		iMonth=11;
	}

	oDate=new Date();
	var iDayNow = oDate.getDate();  
	var iMonthNow = oDate.getMonth();
	var iYearNow = oDate.getFullYear();

	var iDaysInMonth = getDaysInMonth(iYear,iMonth);
	oDate.setFullYear(iYear); 
	oDate.setMonth(iMonth); 
	oDate.setDate(1); 
	var iFirstWeekday = oDate.getDay();

	var iNextYear=iYear;
	var iPrevYear=iYear;
	var iFutureYear = iYear +1; 
	var iPastYear = iYear -1; 

	var iPrevMonth = iMonth-1;  
	if (iPrevMonth <0) {
		iPrevMonth = 11; 
		iPrevYear--;
	} 
	var iNextMonth = iMonth+1; 
	if (iNextMonth > 11){
		iNextMonth =0; 
		iNextYear++;
	}

	var sReturn = '<table class="bsxCalTable" style="text-align:left;"><tr>'
		+'<td colspan="7" class="bsxCalYears">'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear-15,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear-15)+'&nbsp;</span>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear-10,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear-10)+'&nbsp;</span>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear-5,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear-5)+'&nbsp;</span>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear+5,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear+5)+'&nbsp;</span>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear+10,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear+10)+'&nbsp;</span>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iYear+15,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">'+(iYear+15)+'&nbsp;</span>'
		+'</td></tr><tr>'
		+'<td style="cursor:pointer;" class="bsxCalNav">'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iPastYear,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">&lt;&lt;</span><br/>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iPrevYear,iPrevMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">&lt;</span>'
		+'</td><td colspan=5 class="bsxCalHead" style="text-align:center;">'
		+aMonths[iMonth]
		+' '
		+iYear
		+'<br/><span class="bsxCalHeadNormal" style="cursor:pointer;" onclick="setCaller(\''+sCaller+'\',0,\''+sHideDiv+'\');">remove date</span>'
		+'</td><td class="bsxCalNav" style="text-align:right;">'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iFutureYear,iMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">&gt;&gt;</span><br/>'
		+'<span style="cursor:pointer;" onclick="document.getElementById(\'bsxCalendarDiv\').innerHTML = renderCalendar('+(43200+Date.UTC(iNextYear,iNextMonth,1)/1000)+',\''+sCaller+'\',\''+sHideDiv+'\');return false;">&gt;</span>'
		+'</td></tr><tr>';

	for(var i=0;i <7;i++){
		if(i==6||i==0) 
			sReturn += '<td class="bsxCalHeadHighlight">' + aWeekdays[i] + '</td>'; 
		else 
			sReturn += '<td class="bsxCalHeadNormal">' + aWeekdays[i] + '</td>';
	}

	sReturn += '</tr><tr>'; 
	
	for(var i=0;i<iFirstWeekday;i++) 
		sReturn += '<td class="bsxCalGrayed"></td>';

	for(var i=1;i<=iDaysInMonth;i++){
		if(iFirstWeekday==7){
			sReturn += '</tr><tr>'; 
			iFirstWeekday=0;
		} 
		if((iDayNow==i)&&(iYearNow==iYear)&&(iMonthNow==iMonth)) 
			sReturn += '<td class="bsxCalHighlight"><span style="cursor:pointer;" onclick="setCaller(\''+sCaller+'\','+(43200+Date.UTC(iYear,iMonth,i)/1000)+',\''+sHideDiv+'\');">'+i+'&nbsp;</span></td>'; 
		else 
			sReturn += '<td class="bsxCalNormal"><span style="cursor:pointer;" onclick="setCaller(\''+sCaller+'\','+(43200+Date.UTC(iYear,iMonth,i)/1000)+',\''+sHideDiv+'\');">'+i+'&nbsp;</span></td>'; 
		iFirstWeekday ++;
	} 

	for(var i=iFirstWeekday;i<7;i++) 
		sReturn += '<td class="bsxCalGrayed"></td>'; 

	sReturn += '</tr></table>';
	return sReturn;
}

function setCaller(sCaller,iValue,sHideDiv){
	var oCaller=null;
	if (oCaller=document.getElementById(sCaller)){
		if ("value" in oCaller)
			oCaller.value=iValue;
	}
	var oCallerVisible=null;
	if (oCallerVisible=document.getElementById(sCaller+'-DateVisible')){
		if ("value" in oCallerVisible){
			if(iValue==0){
				oCallerVisible.value='';
			}else{
				var oDate=new Date();
				oDate.setTime(iValue*1000);
				sDisplayMonth=""+(oDate.getMonth()+1);
				if (sDisplayMonth<10)
					sDisplayMonth="0"+sDisplayMonth;
				sDisplayDay=""+oDate.getDate();
				if (sDisplayDay<10)
					sDisplayDay="0"+sDisplayDay;
				oCallerVisible.value=sDisplayDay+"."+sDisplayMonth+"."+oDate.getFullYear();
			}
		}
	}
	if (sHideDiv){
		hideLayer(sHideDiv);
	}
}

function copyCaller(sCaller){
	var oCaller=null;
	if (oCaller=document.getElementById(sCaller)){
		if ("value" in oCaller){
			var iValue=oCaller.value;
			setCaller(sCaller,iValue);
		}
	}	
}

function doCalendar(iTS,sCaller,sHideDiv){
	document.getElementById('bsxCalendarDiv').innerHTML =renderCalendar(iTS,sCaller,sHideDiv, true);
}

function parseDate(sDate,sCaller){
	
	var oDate=new Date();
	oDate.setTime(0);

	var iMonth=0;
	var iYear=1970;
	var iDay=1;

	oDate.setFullYear(iYear); 
	oDate.setMonth(iMonth); 
	oDate.setDate(1); 

	aParse = sDate.match(/\d+/g);
	if (aParse && aParse.length==3){
		//debugAlert('match');
		if ((parseInt(aParse[1])>0)&&(parseInt(aParse[1])<13)&&(parseInt(aParse[0])>0)&&(parseInt(aParse[2])>0)){
			//debugAlert('pass');
			if (parseInt(aParse[0])>31){
				iMonth=parseInt(aParse[1])-1;
				iYear=parseInt(aParse[0]);
				iDay=parseInt(aParse[2]);
				oDate.setTime(43200);
			}else{
				iMonth=parseInt(aParse[1])-1;
				iYear=parseInt(aParse[2]);
				iDay=parseInt(aParse[0]);
				oDate.setTime(43200);
			}
		}
	}
	//debugAlert(iDay);
	//debugAlert(iMonth);
	//debugAlert(iYear);

	if(iYear<100){
		iYear+=1900;
	}

	if(iYear<1902){
		iYear=1902;
		iMonth=0;
	}else if(iYear>2037){
		iYear=2037;
		iMonth=11;
	}

	//debugAlert(iDay);
	//debugAlert(iMonth);
	//debugAlert(iYear);

	if(iDay>getDaysInMonth(iYear,iMonth)){
		iDay=getDaysInMonth(iYear,iMonth);
	}

	oDate.setFullYear(iYear); 
	oDate.setMonth(iMonth); 
	oDate.setDate(iDay); 

	if (sCaller){
		if((oDate.getTime()!=0)||(sDate.length==0)){
			setCaller(sCaller,oDate.getTime()/1000);
			//debugAlert('set'+oDate.getTime());
		}else{
			copyCaller(sCaller);
			//debugAlert('copy');
		}
	}

	return oDate.getTime()/1000;
}