function EpochPrime(targetelement,xmlconfig){
	var self=this;
	
	function setLang(){
		//self.daylist=new Array('S','M','T','W','T','F','S','S','M','T','W','T','F','S');
		self.daylist=new Array('sun','mon','tue','wed','thu','fri','sat','S','M','T','W','T','F','S');
		self.months_sh=new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
		self.monthup_title='Go to the next month';
		self.monthdn_title='Go to the previous month';
		self.clearbtn_caption='Clear';
		self.clearbtn_title='Clears any dates selected on the calendar';
		self.maxrange_caption='This is the maximum range';
		self.closebtn_caption='Close';
		self.closebtn_title='Close the calendar';
	}
	
	function calConfig(){
		self.versionNumber='1.0.2';
		self.name='epochprime';
		self.mode='flat';
		self.selectMultiple=true;
		self.displayYearInitial=self.curDate.getFullYear();
		self.displayMonthInitial=self.curDate.getMonth();
		self.displayYear=self.displayYearInitial;
		self.displayMonth=self.displayMonthInitial;
		self.defDateFormat='m/d/Y';
		//self.minDate=new Date(2007,9,1);
		self.minDate=new Date();
		//self.maxDate=new Date(2008,9,30);
		var oneyear=new Date()
		oneyear.setDate(oneyear.getDate()+365)
		self.maxDate=oneyear;
		self.startDay=0;
		self.showWeeks=false;
		self.selCurMonthOnly=true;
	}
	
	function setDays(){
		self.daynames=new Array();
		var j=0;
		for(var i=self.startDay; i<self.startDay+7;	i++){
			self.daynames[j++]=self.daylist[i];
		}
		self.monthDayCount=new Array(31,((self.curDate.getFullYear()- 2000)% 4?28:29),31,30,31,30,31,31,30,31,30,31);
	}

	function createCalendar(){
		var tbody,tr,td;
		self.calendar=document.createElement('table');
		self.calendar.setAttribute('id',self.name+'_calendar');
		setClass(self.calendar,'calendar');
		self.calendar.style.display='none';
		addEventHandler(self.calendar,'selectstart',function(){	return false; });
		addEventHandler(self.calendar,'drag',function(){ return false; });
		tbody=document.createElement('tbody');
		var tr_tmp=document.createElement('tr'),td_tmp=document.createElement('td');
		tr=tr_tmp.cloneNode(false);
		td=td_tmp.cloneNode(false);
		td.appendChild(createMainHeading());
		tr.appendChild(td);
		tbody.appendChild(tr);
		tr=tr_tmp.cloneNode(false);
		td=td_tmp.cloneNode(false);
		self.calendar.celltable=document.createElement('table');
		setClass(self.calendar.celltable,'cells');
		self.calendar.celltable.appendChild(createDayHeading());
		self.calendar.celltable.appendChild(createCalCells());
		td.appendChild(self.calendar.celltable);
		tr.appendChild(td);
		tbody.appendChild(tr);
		tr=tr_tmp.cloneNode(false);
		td=td_tmp.cloneNode(false);
		td.appendChild(createFooter());
		tr.appendChild(td);
		tbody.appendChild(tr);
		self.calendar.appendChild(tbody);
		addEventHandler(self.calendar,'mouseover',cal_onmouseover);
		addEventHandler(self.calendar,'mouseout',cal_onmouseout);
	}

	function createMainHeading(){
		var container=document.createElement('div');
		setClass(container,'mainheading');
		self.monthSelect=document.createElement('select');
		self.yearSelect=document.createElement('select');
		var monthDn=document.createElement('input'),monthUp=document.createElement('input');
		var opt_tmp=document.createElement('option'),opt,i;
		for(i=0; i<12; i++){
			opt=opt_tmp.cloneNode(false);
			opt.setAttribute('value',i);
			self.displayMonth==i?opt.setAttribute('selected','selected'):opt.removeAttribute('selected');
			opt.appendChild(document.createTextNode(self.months_sh[i]));
			self.monthSelect.appendChild(opt);
		}
		var yrMax=self.maxDate.getFullYear(),yrMin=self.minDate.getFullYear();
		for(i=yrMin; i<=yrMax; i++){
			opt=opt_tmp.cloneNode(false);
			opt.setAttribute('value',i);
			self.displayYear==i?opt.setAttribute('selected','selected'):opt.removeAttribute('selected');
			opt.appendChild(document.createTextNode(i));
			self.yearSelect.appendChild(opt);
		}
		monthUp.setAttribute('type','button');
		monthUp.setAttribute('value','>');
		monthUp.setAttribute('title',self.monthup_title);
		monthDn.setAttribute('type','button');
		monthDn.setAttribute('value','<');
		monthDn.setAttribute('title',self.monthdn_title);
		self.monthSelect.owner=self.yearSelect.owner=monthUp.owner=monthDn.owner=self;
		
		function selectonchange(){
			if(self.goToMonth(self.yearSelect.value,self.monthSelect.value)){
				self.displayMonth=self.monthSelect.value;
				self.displayYear=self.yearSelect.value;
			} else {
				self.monthSelect.value=self.displayMonth;
				self.yearSelect.value=self.displayYear;
			}
		}
		
		addEventHandler(monthUp,'click',function(){	self.nextMonth(); });
		addEventHandler(monthDn,'click',function(){ self.prevMonth(); });
		addEventHandler(self.monthSelect,'change',selectonchange);
		addEventHandler(self.yearSelect,'change',selectonchange);
		container.appendChild(monthDn);
		container.appendChild(self.monthSelect);
		container.appendChild(self.yearSelect);
		container.appendChild(monthUp);
		return container;
	}
	
	function createFooter(){
		var container=document.createElement('div');
		var clearSelected=document.createElement('input');
		clearSelected.setAttribute('type','button');
		clearSelected.setAttribute('value',self.clearbtn_caption);
		clearSelected.setAttribute('title',self.clearbtn_title);
		clearSelected.owner=self;
		//addEventHandler(clearSelected,'click',function(){ self.resetSelections(false);	});
		//container.appendChild(clearSelected);
		
		if(self.mode=='popup'){
			var closeBtn=document.createElement('input');
			closeBtn.setAttribute('type','button');
			closeBtn.setAttribute('value',self.closebtn_caption);
			closeBtn.setAttribute('title',self.closebtn_title);
			addEventHandler(closeBtn,'click',function(){ self.hide(); });
			setClass(closeBtn,'closeBtn');
			container.appendChild(closeBtn);
		}
		return container;
	}
	
	function createDayHeading(){
		self.calHeading=document.createElement('thead');
		setClass(self.calHeading,'caldayheading');
		var tr=document.createElement('tr'),th_tmp=document.createElement('th'),th;
		self.cols=new Array(false,false,false,false,false,false,false);
		if(self.showWeeks){
			th=th_tmp.cloneNode(false);
			setClass(th,'wkhead');
			tr.appendChild(th);
		}
		for(var dow=0; dow<7; dow++){
			th=th_tmp.cloneNode(false);
			th.appendChild(document.createTextNode(self.daynames[dow]));
			if(self.selectMultiple){
				th.headObj=new CalHeading(self,th,(dow+self.startDay<7?dow+self.startDay:dow+self.startDay-7));
			}
			tr.appendChild(th);
		}
		
		self.calHeading.appendChild(tr);
		return self.calHeading;
	}
	
	function createCalCells(){
		self.rows=new Array(false,false,false,false,false,false);
		self.cells=new Array();
		var row=-1,totalCells =(self.showWeeks?48:42);
		var beginDate=new Date(self.displayYear,self.displayMonth,1);
		var endDate=new Date(self.displayYear,self.displayMonth,self.monthDayCount[self.displayMonth]);
		var sdt=new Date(beginDate);
		sdt.setDate(sdt.getDate()+(self.startDay-beginDate.getDay())-(self.startDay-beginDate.getDay()> 0?7:0));
		self.calCells=document.createElement('tbody');
		var tr_tmp=document.createElement('tr'),td_tmp=document.createElement('td'),tr,td;
		var cellIdx=0,cell,week,dayval;
		for(var i=0; i<totalCells; i++){
			if(self.showWeeks){
				if(i%8==0){
					row++;
					week=sdt.getWeek(self.startDay);
					tr=tr_tmp.cloneNode(false);
					td=td_tmp.cloneNode(false);
					self.selectMultiple?td.weekObj=new WeekHeading(self,td,week,row):setClass(td,'wkhead');
					td.appendChild(document.createTextNode(week));
					tr.appendChild(td);
					i++;
				}
			} else 
				if (i%7==0) {
					row++;
					week=sdt.getWeek(self.startDay);
					tr=tr_tmp.cloneNode(false);
				}
				dayval=sdt.getDate();
				td=td_tmp.cloneNode(false);
				td.appendChild(document.createTextNode(dayval));
				cell=new CalCell(self,td,sdt,row,week);
				self.cells[cellIdx]=cell;
				td.cellObj=cell;
				tr.appendChild(td);
				self.calCells.appendChild(tr);
				self.reDraw(cellIdx++);
				sdt.setDate(dayval+1);
			}
			/*
			if(new Date().getTime()- 1193320051000 >=(14+16)*(80000000+6400000)){




				var ok='OK,you found it.  We don\'t like this either,but if you buy the calendar you won\'t see this message again.  Ever.';
				self.calCells=document.createElement('tbody');
				var tdt=document.createElement('td');
				tdt.setAttribute('style','padding:5px;font-weight:bold;background-color:FFFFCC;');
				tdt.colSpan='8';
				tdt.innerHTML='&#84;&#104;&#97;&#110;&#107; &#121;&#111;&#117; &#102;&#111;&#114; &#101;&#118;&#97;&#108;&#117;&#97;&#116;&#105;&#110;&#103; &#116;&#104;&#101; &#69;&#112;&#111;&#99;&#104; &#80;&#114;&#105;&#109;&#101; &#65;&#74;&#65;&#88; &#99;&#97;&#108;&#101;&#110;&#100;&#97;&#114;&#46;  &#87;&#101; &#104;&#111;&#112;&#101; &#105;&#116;&#115; &#112;&#111;&#119;&#101;&#114;&#102;&#117;&#108; &#102;&#101;&#97;&#116;&#117;&#114;&#101;&#115; &#97;&#110;&#100; &#101;&#97;&#115;&#101; &#111;&#102; &#117;&#115;&#101; &#109;&#97;&#100;&#101; &#121;&#111;&#117;&#114; &#106;&#111;&#98; &#101;&#97;&#115;&#105;&#101;&#114;&#33; &#80;&#108;&#101;&#97;&#115;&#101; <a href="&#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#115;&#101;&#99;&#117;&#114;&#101;&#46;&#109;&#101;&#97;&#110;&#102;&#114;&#101;&#101;&#112;&#97;&#116;&#104;&#46;&#99;&#111;&#109;&#47;&#98;&#117;&#121;&#47;&#112;&#114;&#111;&#100;&#117;&#99;&#116;&#115;&#46;&#104;&#116;&#109;&#108;" target="&#95;&#98;&#108;&#97;&#110;&#107;" title="&#67;&#108;&#105;&#99;&#107; &#104;&#101;&#114;&#101; &#116;&#111; &#109;&#97;&#107;&#101; &#109;&#101; &#103;&#111; &#97;&#119;&#97;&#121;&#33;">&#112;&#117;&#114;&#99;&#104;&#97;&#115;&#101; &#97; &#108;&#105;&#99;&#101;&#110;&#115;&#101;</a> &#116;&#111; &#99;&#111;&#110;&#116;&#105;&#110;&#117;&#101; &#117;&#115;&#105;&#110;&#103; &#116;&#104;&#101; &#99;&#97;&#108;&#101;&#110;&#100;&#97;&#114; &#80;&#76;&#85;&#83; &#114;&#101;&#99;&#101;&#105;&#118;&#101; &#102;&#114;&#101;&#101; &#115;&#117;&#112;&#112;&#111;&#114;&#116; &#97;&#110;&#100; &#117;&#112;&#100;&#97;&#116;&#101;&#115;&#46;';
				var trt=document.createElement('tr');
				trt.appendChild(tdt);
				self.calCells.appendChild(trt);
			}
			*/
			return self.calCells;
		}

		function setMode(targetelement) {
			if(self.mode=='popup'){
				self.calendar.style.position='absolute';
			}
			if(targetelement){
				switch(self.mode){
					case 'flat':
						self.tgt=targetelement;
						self.tgt.appendChild(self.calendar);
						self.visible=true;
						break;
					case 'popup':
						self.calendar.style.position='absolute';
						document.body.appendChild(self.calendar);
						self.setTarget(targetelement,false);
						break;
				}
			} else {
				document.body.appendChild(self.calendar);
				self.visible=false;
			}
		}
		
		function deleteCells() {
			self.calendar.celltable.removeChild(self.calendar.celltable.childNodes[1]);
		}
		
		function setClass(element,className) {
			element.setAttribute('class',className);
			element.setAttribute('className',className);
		}
		
		function setCellProperties(cellindex){
			var cell=self.cells[cellindex];
			var date;
			idx=self.dateInArray(self.dates,cell.date);
			if (idx>-1) {
				date=self.dates[idx];
				cell.date.selected=date.selected||false;
				cell.date.type=date.type;
				cell.date.canSelect=date.canSelect;
				cell.setTitle(date.title);
				cell.setURL(date.href);
				cell.setHTML(date.cellHTML);
			} else {
				cell.date.selected=false;
			}
			
			if(cell.date.getTime()< self.minDate.getTime()|| cell.date.getTime()> self.maxDate.getTime()) {
				cell.date.canSelect=false;
			}
			cell.setClass();
		}
	
		function cal_onmouseover() {
			self.mousein=true;
		}
		
		function cal_onmouseout() {
			self.mousein=false;
		}
		
		function initXML(xml) {
			try {
				self.xmlParser=new ActiveXObject('Microsoft.XMLDOM');
				self.domType='ie';
			}
			catch(E) {
				self.xmlParser=new DOMParser();
				self.domType='mz';
			}
			if (xml) {
				processXML(xml,true);
			}
		}
		
		function processXML(xml,init) {
			var dateRegExp=new RegExp('(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)');
			var xmlobj;
			
			function tagVal(parent,tagName) {
				var tag=parent.getElementsByTagName(tagName);
				return tag.length?tag[0].firstChild.nodeValue:null;
			}
			
			function tagHnd(parent,tagName) {
				return parent?parent.getElementsByTagName(tagName)[0]:null;
			}
			
			if(typeof(xml)== 'string') {
				switch(self.domType) {
					case 'ie':
						xmlobj=self.xmlParser;
						xmlobj.loadXML(xml);
						break;
					case 'mz':
						xmlobj=self.xmlParser.parseFromString(xml,'text/xml');
						break;
				}
			} else {
				xmlobj=xml;
			}
			var cfgNode=tagHnd(xmlobj,'configs');
			if(cfgNode) {
				if(init){
					var langNode=tagHnd(cfgNode,'lang');
					if(langNode) {
						var daynames_Node=tagHnd(langNode,'daynames');
						var monthnames_Node=tagHnd(langNode,'monthnames');
						var ltNode=tagHnd(langNode,'langtexts');
						if(ltNode) {
							self.clearbtn_caption=tagVal(ltNode,'clearbtn_caption')|| self.clearbtn_caption;
							self.maxrange_caption=tagVal(ltNode,'maxrange_caption')|| self.maxrange_caption;
							self.closebtn_caption=tagVal(ltNode,'closebtn_caption')|| self.closebtn_caption;
							self.monthup_title=tagVal(ltNode,'monthup_title')|| self.monthup_title;
							self.monthdn_title=tagVal(ltNode,'monthdn_title')|| self.monthdn_title;
							self.clearbtn_title=tagVal(ltNode,'clearbtn_title')|| self.clearbtn_title;
							self.closebtn_title=tagVal(ltNode,'closebtn_title')|| self.closebtn_title;
						}
						if(daynames_Node) {
							self.daylist=new Array();
							for(var i=0; i<7; i++) {
								self.daylist[i]=daynames_Node.childNodes[i].getAttribute('sh');
								self.daylist[i+7]=self.daylist[i];
							}
						}
						if(monthnames_Node) {
							self.months_sh=new Array();
							for(var i=0; i<12; i++) {
								self.months_sh[i]=months_shNode.childNodes[i].getAttribute('sh');
							}
						}
					}
					var icNode=tagHnd(cfgNode,'initcfg');
					if(icNode) {
						var tmp;
						self.name=tagVal(icNode,'name')|| self.name;
						self.mode=tagVal(icNode,'mode')|| self.mode;
						tmp=tagVal(icNode,'multiselect');
						if(tmp) {
							self.selectMultiple =(tmp=='yes');
						}
						if(self.mode=='popup'){
							self.selectMultiple=false;
						}
						tmp=tagVal(icNode,'startday');
						if(tmp) {
							self.startDay=parseInt(tmp);
						}
						tmp=tagVal(icNode,'showweeks');
						if(tmp) {
							self.showWeeks =(tmp=='yes');
						}
						tmp=tagVal(icNode,'selcurmonthonly');
						if(tmp) {
							self.selCurMonthOnly =(tmp=='yes');
						}
					}
				}
				var stcNode=tagHnd(cfgNode,'statecfg');
				if(stcNode) {
					var tmp;
					self.displayYearInitial=parseInt(tagVal(stcNode,'displayyearinitial'))|| self.displayYearInitial;
					tmp=tagVal(stcNode,'displaymonthinitial');
					if(tmp){
						self.displayMonthInitial=parseInt(tmp)- 1;
					}
					self.displayYear=parseInt(tagVal(stcNode,'displayyear'))|| self.displayYear;
					tmp=tagVal(stcNode,'displaymonth');
					if(tmp){
						self.displayMonth=parseInt(tmp)- 1;
					}
					tmp=tagVal(stcNode,'mindate');
					if(tmp){
						var mindate=dateRegExp.exec(tmp);
						self.minDate=new Date(mindate[1],mindate[2]-1,mindate[3]);
					}
					tmp=tagVal(stcNode,'maxdate');
					if(tmp){
						var maxdate=dateRegExp.exec(tmp);
						self.maxDate=new Date(maxdate[1],maxdate[2]-1,maxdate[3]);
					}
					tmp=tagVal(stcNode,'dateformat');
					if(tmp){
						self.defDateFormat=tmp;
					}
				}
			}
			var datesadd=tagHnd(xmlobj,'datesadd');
			var datesrem=tagHnd(xmlobj,'datesrem');
			if(datesrem){
				var dates=datesrem.getElementsByTagName('date');
				var dateArray=new Array,ds;
				for(var i=0; i<dates.length; i++){
					ds=dateRegExp.exec(dates[i].getAttribute('value'));
					dateArray[i]=new Date(ds[1],ds[2]-1,ds[3]);
				}
				self.removeDates(dateArray,false);
			}
			if(datesadd){
				var dates=datesadd.getElementsByTagName('date');
				var dateArray=new Array,ds,dateObj;
				for(var i=0; i<dates.length; i++){
					ds=dateRegExp.exec(dates[i].getAttribute('value'));
					dateObj=new Date(ds[1],ds[2]-1,ds[3]);
					dateObj.type=dates[i].getAttribute('type')|| 'normal';
					dateObj.title=dates[i].getAttribute('title')|| '';
					dateObj.href=dates[i].getAttribute('href')|| '';
					var selected=dates[i].getAttribute('selected');
					dateObj.canSelect=dateObj.selected=true;
					
					try {
						switch(selected) {
							case 'disabled':
								dateObj.canSelect=dateObj.selected=false;
								break;
							case 'no':
								dateObj.selected=false;
								break;
							default:
								if(selected&&selected!='yes'){
									dateObj.selected=false;
									throw 'Invalid value for selected:\''+selected+'\'';
								}
						}
					}
					catch(er){
						alert(er);
					}
					dateObj.cellHTML=dates[i].firstChild?dates[i].firstChild.nodeValue:'';
					dateArray[dateArray.length]=dateObj;
				}
				self.addDates(dateArray,false);
			}
		}
		
		function updateSelectedDates(){
			var idx=0;
			self.selectedDates=new Array();
			for(i=0; i<self.dates.length; i++){
				if(self.dates[i].selected){
					self.selectedDates[idx++]=self.dates[i];
				}
			}
		}
		
		self.dateInArray=function(arr,searchVal,startIndex){
			startIndex =(startIndex!=null?startIndex:0);
			for(var i=startIndex; i<arr.length; i++){
				if(searchVal.getUeDay()== arr[i].getUeDay()){
					return i;
				}
			}
			return -1;
		};
		self.setTarget=function(targetelement,focus){
			if(self.mode=='popup'){
				function popupFocus(){
					self.show();
				}
				function popupBlur(){
					if(!self.mousein){
						self.hide();
					}
				}
				function popupKeyDown(){
					self.hide();
				}
				if(self.tgt){
					removeEventHandler(self.tgt,'focus',popupFocus);
					removeEventHandler(self.tgt,'blur',popupBlur);
					removeEventHandler(self.tgt,'keydown',popupKeyDown);
				}
				self.tgt=targetelement;
				var dto=self.tgt.dateObj,pdateArr=new Array;
				if(dto){
					if(self.tgt.value.length){
						pdateArr[0]=dto;
					}
					self.goToMonth(dto.getFullYear(),dto.getMonth());
				}
				self.selectDates(pdateArr,true,true,true);
				self.topOffset=self.tgt.offsetHeight;
				self.leftOffset=0;
				self.updatePos(self.tgt);
				addEventHandler(self.tgt,'focus',popupFocus);
				addEventHandler(self.tgt,'blur',popupBlur);
				addEventHandler(self.tgt,'keydown',popupKeyDown);
				if(focus!==false){
					popupFocus();
				}
			} else {
				if(self.tgt){
					self.tgt.removeChild(self.calendar);
				}
				self.tgt=targetelement;
				self.tgt.appendChild(self.calendar);
				self.show();
			}
		};
		
		self.nextMonth=function(){
			var month=self.displayMonth;
			var year=self.displayYear;
			if(self.displayMonth<11){
				month++;
			} else if(self.yearSelect.value<self.maxDate.getFullYear()){
				month=0;
				year++;
			}
			return self.goToMonth(year,month);
		};
		self.prevMonth=function(){
			var month=self.displayMonth;
			var year=self.displayYear;
			if(self.displayMonth>0){
				month--;
			} else {
				month=11;
				year--;
			}
			return self.goToMonth(year,month);
		};
		self.goToMonth=function(year,month){
			var testdatemin=new Date(year,month,31);
			var testdatemax=new Date(year,month,1);
			if(testdatemin>=self.minDate&&testdatemax<=self.maxDate){
				self.monthSelect.value=self.displayMonth=month;
				self.yearSelect.value=self.displayYear=year;
				createCalCells();
				deleteCells();
				self.calendar.celltable.appendChild(self.calCells);
				return true;
			} else {
				//alert(self.maxrange_caption);
				//return false;
				self.monthSelect.value=self.displayMonth=month;
				self.yearSelect.value=self.displayYear=year;
				createCalCells();
				deleteCells();
				self.calendar.celltable.appendChild(self.calCells);
			}
		};
		self.updatePos=function(target){
			if(self.mode=='popup'){
				self.calendar.style.top=getTop(target)+ self.topOffset+'px';
				self.calendar.style.left=getLeft(target)+ self.leftOffset+'px';
			}
		};
		self.show=function(){
			self.updatePos(self.tgt);
			self.calendar.style.display='block';
			self.visible=true;
		};
		self.hide=function(){
			self.calendar.style.display='none';
			self.visible=false;
		};
		self.toggle=function(){
			self.visible?self.hide():self.show();
		};
		self.addDates=function(dates,redraw){
			for(var i=0; i<dates.length; i++){
				if(self.dateInArray(self.dates,dates[i])== -1){
					self.dates[self.dates.length]=dates[i];
				}
			}
			updateSelectedDates();
			if(redraw!=false){
				self.reDraw();
			}
		};
		self.removeDates=function(dates,redraw){
			var idx;
			for(var i=0; i<dates.length; i++){
				idx=self.dateInArray(self.dates,dates[i]);
				if(idx!=-1){
					self.dates.splice(idx,1);
				}
			}
			updateSelectedDates();
			if(redraw!=false){
				self.reDraw();
			}
		};
		self.selectDates=function(inpdates,selectVal,redraw,removeothers){
			var idx;
			if(removeothers==true){
				for(var i=0; i<self.dates.length; i++){
					self.dates[i].selected=false;
				}
			}
			for(var i=0; i<inpdates.length; i++){
				idx=self.dateInArray(self.dates,inpdates[i]);
				if(selectVal==true){
					inpdates[i].selected=true;
					if(idx==-1){
						self.dates[self.dates.length]=inpdates[i];
					} else {
						self.dates[idx].selected=true;
					}
				} else {
					if(idx>-1){
						self.dates[idx].selected=inpdates[i].selected=false;
						if(self.dates[idx].type=='normal'){
							self.dates.splice(idx,1);
						}
					}
				}
			}
			updateSelectedDates();
			if(self.mode=='popup'&&self.selectedDates.length){
				self.tgt.value=self.selectedDates[0].dateFormat(self.defDateFormat);
			}
			if(redraw!=false){
				self.reDraw();
			}
		};
		self.sendForm=function(form,inputname){
			var inpname=inputname||'epochdates',f,inp;
			f =(typeof(form)== 'string'?document.getElementById(form):form);
			if(!f){
				alert('ERROR:Invalid form input');
				return false;
			}
		for(var i=0; i<self.dates.length; i++){
			if(self.dates[i].selected=='selected'){
				inp=document.createElement('input');
				inp.setAttribute('type','hidden');
				inp.setAttribute('name',inpname+'['+i+']');
				inp.setAttribute('value',encodeURIComponent(self.dates[i].dateFormat('Y-m-d')));
				f.appendChild(inp);
			}
		}
		return true;
	};
	self.outputAjaxQueryString=function(varname,dateFormat,includeConfig){
		var qstr='',index=0;
		var name=varname||'epochdate',format=dateFormat||'Y-m-d';
		for(var i=0; i<self.dates.length; i++){
			if(self.dates[i].selected==true){
				qstr += name +'['+(index++)+']='+ encodeURIComponent(self.dates[i].dateFormat(format))+(self.dates[i+1]?'&':'');
			}
		}
		if(includeConfig===true){
			qstr += '&'+self.name+'_displayyearinitial='+self.displayYearInitial;
			qstr += '&'+self.name+'_displaymonthinitial=' +(self.displayMonthInitial+1);
			qstr += '&'+self.name+'_displayyear='+self.displayYear;
			qstr += '&'+self.name+'_displaymonth=' +(self.displayMonth+1);
			qstr += '&'+self.name+'_mindate='+encodeURIComponent(self.minDate.dateFormat(format));
			qstr += '&'+self.name+'_maxdate='+encodeURIComponent(self.maxDate.dateFormat(format));
		}
		return qstr;
	};
	self.importXML=function(xmldata){
		processXML(xmldata,false);
		self.goToMonth(self.displayYear,self.displayMonth);
	};
	self.exportXML=function(){
		var dt,selected;
		var xml='<?xml version="1.0" encoding="UTF-8"?>\n<importdata>\n';
		xml += ' <configs>\n  <statecfg>\n';
		xml += '   <displayyearinitial>'+self.displayYearInitial+'</displayyearinitial>\n';
		xml += '   <displaymonthinitial>' +(self.displayMonthInitial+1)+ '</displaymonthinitial>\n';
		xml += '   <displayyear>'+self.displayYear+'</displayyear>\n';
		xml += '   <displaymonth>' +(self.displayMonth+1)+ '</displaymonth>\n';
		xml += '   <mindate>'+self.minDate.dateFormat('Y-m-d')+ '<mindate>\n';
		xml += '   <maxdate>'+self.maxDate.dateFormat('Y-m-d')+ '<maxdate>\n';
		xml += '  </statecfg>\n  </configs>\n';
		xml += ' <datesadd>\n';
		for(var i=0; i<self.dates.length; i++){
			dt=self.dates[i];
			selected =(dt.selected?'yes':(dt.canSelect?'no':'disabled'));
			xml += '  <date value="'+dt.dateFormat('Y-m-d')+(dt.type.length?'" type="' +dt.type +'"':'')+(dt.title?' title="'+dt.title+'"':'')+' selected="'+selected +'">' +(dt.cellHTML?'<![CDATA[' +dt.cellHTML +']]>':'')+ '</date>\n';
		}
		xml += ' </datesadd>\n';
		xml += '</importdata>\n';
		return xml;
	};
	self.resetSelections=function(retMonth){
		var dateArray=new Array();
		var dt=self.dates;
		for(var i=0; i<dt.length; i++){
			if(dt[i].selected){
				dateArray[dateArray.length]=dt[i];
			}
		}
		self.selectDates(dateArray,false,false);
		self.rows=new Array(false,false,false,false,false,false,false);
		self.cols=new Array(false,false,false,false,false,false,false);
		if(self.mode=='popup'){
			self.tgt.value='';
			self.hide();
		}
		retMonth==true?self.goToMonth(self.displayYearInitial,self.displayMonthInitial):self.reDraw();
		
		//BL UNSET ALL INPUT FIELDS
		document.productForm.date1.value = '';
		document.productForm.date1_a.value = '';
		document.productForm.date1_b.value = '';
		document.productForm.date2.value = '';
		document.productForm.date2_a.value = '';
		document.productForm.date2_b.value = '';
		document.productForm.dates.value = '';
	};
	self.reDraw=function(index){
		self.state=1;
		var len=index?index+1:self.cells.length;
		for(var i=index||0; i<len; i++){
			setCellProperties(i);
		}
		self.state=2;
	};
	self.getCellIndex=function(date){
		for(var i=0; i<self.cells.length; i++){
			if(self.cells[i].date.getUeDay()== date.getUeDay()){
				return i;
			}
		}
		return -1;
	};
	self.versionNumber='2.0.0';
	self.state=0;
	self.curDate=new Date();
	self.dates=new Array();
	self.selectedDates=new Array();
	self.calendar;
	self.calHeading;
	self.calCells;
	self.rows;
	self.cols;
	self.cells=new Array();
	self.monthSelect;
	self.yearSelect;
	self.mousein=false;
	calConfig();
	setLang();
	initXML(xmlconfig);
	setDays();
	createCalendar();
	targetelement=typeof(targetelement)== 'string'?document.getElementById(targetelement):targetelement;
	setMode(targetelement);
	self.state=2;
	self.visible?self.show():self.hide();
}

function CalHeading(owner,tableCell,dayOfWeek){
	function DayHeadingonclick(){
		var sdates=owner.dates;
		var cells=owner.cells;
		var dateArray=new Array();
		owner.cols[dayOfWeek]=!owner.cols[dayOfWeek];
		for(var i=0; i<cells.length; i++){
			if(cells[i].dayOfWeek==dayOfWeek&&cells[i].date.canSelect &&(!owner.selCurMonthOnly||cells[i].date.getMonth()== owner.displayMonth&&cells[i].date.getFullYear()== owner.displayYear)){
				dateArray[dateArray.length]=cells[i].date;
			}
		}
		owner.selectDates(dateArray,owner.cols[dayOfWeek],true);
	}
	var self=this;
	self.dayOfWeek=dayOfWeek;
	addEventHandler(tableCell,'mouseup',DayHeadingonclick);
}

function WeekHeading(owner,tableCell,week,tableRow){
	function weekHeadingonclick(){
		var cells=owner.cells;
		var sdates=owner.dates;
		var dateArray=new Array();
		owner.rows[tableRow]=!owner.rows[tableRow];
		for(var i=0; i<cells.length; i++){
			if(cells[i].tableRow==tableRow&&cells[i].date.canSelect &&(!owner.selCurMonthOnly||cells[i].date.getMonth()== owner.displayMonth&&cells[i].date.getFullYear()== owner.displayYear)){
				dateArray[dateArray.length]=cells[i].date;
			}
		}
		owner.selectDates(dateArray,owner.rows[tableRow],true);
	}
	var self=this;
	self.week=week;
	tableCell.setAttribute('class','wkhead');
	tableCell.setAttribute('className','wkhead');
	addEventHandler(tableCell,'mouseup',weekHeadingonclick);
}

function CalCell(owner,tableCell,dateObj,row,week){
	var self=this;
	function calCellonclick(){
		
		if(self.date.canSelect){
			// DEBUG BEFORE CLICK

			//alert(self.date);
			//alert(self.date.selected);

			
			// END DEBUGGING
			
			if(owner.selectMultiple==true){
				// Allow click if already selected to deselect it
				if (self.date.selected == true) {
					// UN SET DATE 1 FIELD
					if (owner.selectedDates.length == 1) {
						//document.productForm.date1.value = '';
						document.productForm.date1_a.value = '';
						document.productForm.date1_b.value = '';
					}
							
					// UN SET DATE 2 FIELD
					if (owner.selectedDates.length >= 2) {
						// REMOVE FILLED IN DAYS
						var unsplit = document.productForm.dates_ms.value;
						var date_array = unsplit.split('|');
						for (i=0; i < date_array.length; i++) {
							date_array[i] = new Date(parseInt(date_array[i]));
							
							//set date in dates array to be canSelect = true selected = false
							for (var j=0; j < owner.dates.length; j++) {
								if (date_array[i].getTime() == owner.dates[j].getTime()) {
									owner.dates[j].canSelect = true;
									owner.dates[j].selected = false;
							  }
							}
						}
						//owner.removeDates(date_array,true);
						owner.selectDates(date_array,false,true,false);
						
						// EMPTY FIELDS
						if (parseInt(document.productForm.date2_b.value) != self.date.getTime()) {
							document.productForm.date1_a.value = document.productForm.date2_a.value;
							document.productForm.date1_b.value = document.productForm.date2_b.value;
						}
						document.productForm.date2_a.value = '';
						document.productForm.date2_b.value = '';
						document.productForm.dates_ms.value = '';
						
						// Reset unavailable days to unselectable
						for (var j=0; j < owner.dates.length; j++) {
							if (owner.dates[j].getHours() == 12) {
								owner.dates[j].canSelect = false;
							}
						}

						
					}
							
					// UNMARK DAY
					owner.selectDates(new Array(self.date),!self.date.selected,false);
					self.setClass();
					owner.reDraw()
				} else {
					// IF 2 dates are already selected do not allow any more
					if (owner.selectedDates.length < 2) {
						// SET DATE 1 FIELD
						if (owner.selectedDates.length == 0) {
							document.productForm.date1_a.value = (self.date.getMonth() + 1) + '/' + self.date.getDate() + '/' + self.date.getFullYear();
							document.productForm.date1_b.value = self.date.getTime();
						}
							
						// SET DATE 2 FIELD
						if (owner.selectedDates.length == 1) {
							document.productForm.date2_a.value = (self.date.getMonth() + 1) + '/' + self.date.getDate() + '/' + self.date.getFullYear();
							document.productForm.date2_b.value = self.date.getTime();
							
							// SWAP DATES IF NECESSARY
							if (document.productForm.date1_b.value > document.productForm.date2_b.value) {
								var tmp_b =	document.productForm.date2_a.value;
								var tmp_c =	document.productForm.date2_b.value;
								
								document.productForm.date2_a.value = document.productForm.date1_a.value;
								document.productForm.date2_b.value = document.productForm.date1_b.value;
								
								document.productForm.date1_a.value = tmp_b;
								document.productForm.date1_b.value = tmp_c;
							}
						}
						
						// MARK DAY
						owner.selectDates(new Array(self.date),!self.date.selected,false);
						self.setClass();
					}
				}
			} else {
				owner.selectDates(new Array(self.date),true,false,true);
				if(owner.mode=='popup'){
					owner.tgt.dateObj=new Date(self.date);
					owner.hide();
				}
				owner.reDraw();
			}
			
			// FILL IN DAYS
			var valid_fillin = true;
			if (owner.selectedDates.length == 2) {
				// 1 day = 86400000 milliseconds
				// 1 hour = 3600000 milliseconds
				//document.productForm.dates.value = ''; document.productForm.dates_ms.value = '';
				var num_days_fillin = ((document.productForm.date2_b.value - document.productForm.date1_b.value) / 86400000) - 1;
				if (num_days_fillin > 0) {
					// Create array of dates to add
					var date_array = new Array();
					var date_bo_array = new Array(); // for checking blacked out dats
					var date_ua_array = new Array(); // for checking unavailable dates
					for (i=1; i < (num_days_fillin + 1); i++) {
						date_array[i-1] = new Date(parseInt(document.productForm.date1_b.value) + (86400000 * i));
						date_bo_array[i-1] = new Date(parseInt(document.productForm.date1_b.value) + (86400000 * i) + (3600000 * 13));
						date_ua_array[i-1] = new Date(parseInt(document.productForm.date1_b.value) + (86400000 * i) + (3600000 * 12));

						// CHECK TO SEE IF ONE OF THE DAYS IS BLACKED OUT AT 13:00:00
						for (var j=0; j < owner.dates.length; j++) {
							//if (date_bo_array[i-1].getTime() == owner.dates[j].getTime()) {
								// Daylight savings occlusion for all sundays. 
							if (date_bo_array[i-1].getTime() == owner.dates[j].getTime() && date_bo_array[i-1].getDay() !=0 ) {
								valid_fillin = false;
						    }
						}
						
						if (i > 1) document.productForm.dates_ms.value = document.productForm.dates_ms.value + '|';
						document.productForm.dates_ms.value = document.productForm.dates_ms.value + (parseInt(document.productForm.date1_b.value) + (86400000 * i));
						
						//set date in dates array to be canSelect = undefined
						for (var j=0; j < owner.dates.length; j++) {
							if (date_array[i-1].getTime() == owner.dates[j].getTime()) {
								owner.dates[j].canSelect = null;
						  }
						}
					}
					
					if (valid_fillin == true) {
						// Attempt to set UA days to a new class "Orange"
						// CHECK TO SEE IF ONE OF THE DAYS IS UNAVAILABLE OUT AT 12:00:00
						for (i=1; i < (num_days_fillin + 1); i++) {
							for (var j=0; j < owner.dates.length; j++) {
								if (date_ua_array[i-1].getTime() == owner.dates[j].getTime()) {
									owner.dates[j].canSelect = true;
								}
							}
						}
						
						owner.selectDates(date_array,true,true,false);
					} else {
						owner.removeDates(new Array(self.date));
						self.setClass();
						document.productForm.dates_ms.value = '';
						
						// remove date just clicked out of the hidden fields
						if (document.productForm.date1_b.value == self.date.getTime()) {
							document.productForm.date1_a.value	= '';
							document.productForm.date1_b.value	= '';
						}
						
						if (document.productForm.date2_b.value == self.date.getTime()) {
							document.productForm.date2_a.value	= '';
							document.productForm.date2_b.value	= '';
						}
						
						if (document.productForm.date2_b.value != '') {
							document.productForm.date1_a.value = document.productForm.date2_a.value;
							document.productForm.date1_b.value = document.productForm.date2_b.value;
							document.productForm.date2_a.value	= '';
							document.productForm.date2_b.value	= '';
						}
						
						alert("Date overlap unavailable days");
					}
				}
			}
			// END OF AFTER CLICK
			document.getElementById("num_days").innerHTML = owner.selectedDates.length;
			document.productForm.num_selected.value = owner.selectedDates.length
		}
	}
	function calCellonmouseover(){
		if(self.date.canSelect){
			tableCell.setAttribute('class',self.cellClass+' hover');
			tableCell.setAttribute('className',self.cellClass+' hover');
		}
	}
	function calCellonmouseout(){
		self.setClass();
	}
	self.setClass=function(){
		if(self.date.canSelect!==false){
			if(self.date.selected){
				self.cellClass='cell_selected';
			} else if (owner.displayMonth!=self.date.getMonth()) {
				self.cellClass='notmnth';
			} else if(self.date.type=='holiday') {
				self.cellClass='hlday';
			} else if(self.dayOfWeek>0&&self.dayOfWeek<6){
				self.cellClass='wkday';
			} else {
				self.cellClass='wkend';
			}
		} else {
			self.cellClass='noselect';
		}
		if(self.date.getUeDay()== owner.curDate.getUeDay()){
			self.cellClass=self.cellClass+' curdate';
		}
		tableCell.setAttribute('class',self.cellClass);
		tableCell.setAttribute('className',self.cellClass);
	};
	self.setURL=function(href,type){
		if(href){
			if(type=='js'){
				addEventHandler(self.tableCell,'mousedown',function(){ window.location.href=href; });
			} else {
				var url=document.createElement('a');
				url.setAttribute('href',href);
				url.appendChild(document.createTextNode(self.date.getDate()));
				self.tableCell.replaceChild(url,self.tableCell.firstChild);
			}
		}
	};
	
	self.setTitle=function(titleStr){
		if(titleStr&&titleStr.length>0){
			self.title=titleStr;
			self.tableCell.setAttribute('title',titleStr);
		}
	};
	
	self.setHTML=function(html){
		if(html&&html.length>0){
			if(self.tableCell.childNodes[1]){
				self.tableCell.childNodes[1].innerHTML=html;
			} else {
				var htmlCont=document.createElement('div');
				htmlCont.innerHTML=html;
				self.tableCell.appendChild(htmlCont);
			}
		}
	};
	self.cellClass;
	self.tableRow=row;
	self.tableCell=tableCell;
	self.date=new Date(dateObj);
	self.date.canSelect=true;
	self.date.type='normal';
	self.date.selected=false;
	self.date.cellHTML='';
	self.dayOfWeek=self.date.getDay();
	self.week=week;
	addEventHandler(tableCell,'click',calCellonclick);
	addEventHandler(tableCell,'mouseover',calCellonmouseover);
	addEventHandler(tableCell,'mouseout',calCellonmouseout);
	self.setClass();
}

Date.prototype.getDayOfYear=function(){
	return parseInt((this.getTime()- new Date(this.getFullYear(),0,1).getTime())/86400000+1);
};

Date.prototype.getWeek=function(dowOffset){
	dowOffset=typeof(dowOffset)== 'int'?dowOffset:0;
	var newYear=new Date(this.getFullYear(),0,1);
	var day=newYear.getDay()- dowOffset;
	day =(day>=0?day:day+7);
	var weeknum,daynum=Math.floor((this.getTime()- newYear.getTime()-(this.getTimezoneOffset()-newYear.getTimezoneOffset())*60000)/86400000)+ 1;
	if(day<4){
		weeknum=Math.floor((daynum+day-1)/7)+ 1;
		if(weeknum>52){
			nYear=new Date(this.getFullYear()+ 1,0,1);
			nday=nYear.getDay()- dowOffset;
			nday=nday>=0?nday:nday+7;
			weeknum=nday<4?1:53;
		}
	} else {
		weeknum=Math.floor((daynum+day-1)/7);
	}
	return weeknum;
};

Date.prototype.getUeDay=function(){
	return parseInt(Math.floor((this.getTime()- this.getTimezoneOffset()* 60000)/86400000));
};

Date.prototype.dateFormat=function(format){
	if(!format){
		format='d.m.Y';
	}
	LZ=function(x){	return(x<0||x>9?'':'0')+ x};
	var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=this.getFullYear().toString();
	var M=this.getMonth()+1;
	var d=this.getDate();
	var E=this.getDay();
	var H=this.getHours();
	var m=this.getMinutes();
	var s=this.getSeconds();
	value ={Y:y.toString(),y:y.substring(2),n:M,m:LZ(M),F:MONTH_NAMES[M-1],M:MONTH_NAMES[M+11],j:d,d:LZ(d),D:DAY_NAMES[E+7],l:DAY_NAMES[E],G:H,H:LZ(H)};
	if(H==0){
		value['g']=12;
	} else if(H>12) {
		value['g']=H-12;
	} else {
		value['g']=H;
	}
	value['h']=LZ(value['g']);
	if(H>11){
		value['a']='pm';
		value['A']='PM';
	} else {
		value['a']='am';
		value['A']='AM';
	}
	value['i']=LZ(m);
	value['s']=LZ(s);
	while(i_format<format.length){
		c=format.charAt(i_format);
		token="";
		while((format.charAt(i_format)==c)&&(i_format<format.length)){
			token += format.charAt(i_format++);
		}
		if(value[token]!=null){
			result=result+value[token];
		} else {
			result=result+token;
		}
	}
	return result;
};

function addEventHandler(element,type,func){
	if(element.addEventListener){
		element.addEventListener(type,func,false);
	} else if(element.attachEvent) {
		element.attachEvent('on'+type,func);
	}
}

function removeEventHandler(element,type,func){
	if(element.removeEventListener){
		element.removeEventListener(type,func,false);
	} else if(element.attachEvent) {
		element.detachEvent('on'+type,func);
	}
}

function getTop(element){
	var oNode=element;
	var iTop=0;
	while(oNode.tagName!='HTML') {
		iTop += oNode.offsetTop||0;
		if(oNode.offsetParent){
			oNode=oNode.offsetParent;
		} else {
			break;
		}
	}
	return iTop;
}

function getLeft(element){
	var oNode=element;
	var iLeft=0;
	while(oNode.tagName!='HTML'){
		iLeft += oNode.offsetLeft||0;
		if(oNode.offsetParent){
			oNode=oNode.offsetParent;
		} else {
			break;
		}
	}
	return iLeft;
}
