var Scal = {
	classNameToAttachTo : 'scal',
	calendarClassName : 'scal',
	monthNames : new Array('January','February','March','April','May','June','July','August','September','Octomber','November','December'),
	dateFormat: 'yyyy-mm-dd',
	/* *********** */	
	monthValue : new Array(42),
	currentMonth : null,
	currentYear : null,
	activeDay : null,
	activeMonth : null,
	activeYear : null,
	inputObject : null,
	container : null,
	dateFormatRegex : null,
	indexYear : null,
	indexMonth : null,
	indexDay : null,
	
	init : function()  {
		now = new Date;
		this.currentMonth=now.getMonth();
		this.currentYear=now.getFullYear();
		a = getElementsByClassName(this.classNameToAttachTo);

		for(i=0;i<a.length; i++)
		{	
			addEvent(a[i], 'focus', this.onElementFocus);
			addEvent(a[i], 'click', this.onElementClick);
			addEvent(a[i], 'blur', this.onElementBlur);
		}

  	addEvent(document, 'click', this.outsideClick);
  	addEvent(window, 'resize', this.setPosition);
  	
  	html = '<table id="scal" class="'+this.calendarClassName+'">';
		html += '<tr><th onclick="Scal.prevMonth();">&laquo;</th><th colspan="5" id="scal_head"></th><th onclick="Scal.nextMonth()">&raquo;</th></tr>';
		html += '<tr class="scal_months"><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>';
		
		for(i=0;i<6;i++) {
			html +='<tr>';
			for(j=0;j<7;j++) {
				html +='<td id="scal_cell_' + (7*i+j+1) + '">&nbsp;</td>';
			}
			html +='</tr>';
		}
		html +='</table>';

		var container = document.createElement("div");
		container.setAttribute('id','scal_container');
		container.innerHTML= html;
		container.style.position='absolute';
		container.style.display='none';
		
		document.getElementsByTagName("body").item(0).appendChild(container);
		
		this.dateFormatRegex = this.dateFormat.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, "\\$&");
		this.dateFormatRegex = this.dateFormatRegex.replace('yyyy', '([0-9]{4})');
		this.dateFormatRegex = this.dateFormatRegex.replace('mm', '([0-9]{2})');
		this.dateFormatRegex = this.dateFormatRegex.replace('dd', '([0-9]{2})');
		
		indexYear = this.dateFormat.indexOf('yyyy');
		indexMonth = this.dateFormat.indexOf('mm');
		indexDay = this.dateFormat.indexOf('dd');
		arr = new Array(3);
		arr[0] = indexYear;
		arr[1] = indexMonth;
		arr[2] = indexDay;
		arr.sort();
		
		this.indexYear = arr.indexOf(indexYear);
		this.indexMonth = arr.indexOf(indexMonth);
		this.indexDay = arr.indexOf(indexDay);

		this.container = container;	
	},
	show : function(obj) {
		
		this.inputObject=obj;
		 	
		this.setPosition(obj);
	
		this.container.style.display = 'block';
		
		re = new RegExp(this.dateFormatRegex);
		
		arrDate = re.exec(obj.value);

		if (!arrDate || arrDate.length != 4)
		{
			now = new Date;
			this.currentMonth=now.getMonth();
			this.currentYear=now.getFullYear();
			
			this.prepare();
		}
		else
		{
			this.activeYear = arrDate[this.indexYear+1];
			this.activeMonth =arrDate[this.indexMonth+1]-1;
			this.activeDay = arrDate[this.indexDay+1];

			this.currentMonth = this.activeMonth;
			this.currentYear = this.activeYear;
			
			this.prepare();
		}
		
		return;	
	},
	setPosition : function()
	{
		if (Scal.inputObject){
			Scal.container.style.top = getAbsoluteTop(Scal.inputObject)+ obj.offsetHeight + 'px';
			Scal.container.style.left = getAbsoluteLeft(Scal.inputObject) + 1 +'px';
		}
	},
	prepare : function(){
		date=new Date();
		date.setDate(1);
		date.setMonth(this.currentMonth);
		date.setFullYear(this.currentYear);
		
		startDay=date.getDay()-1;
		if (startDay==-1) startDay=6;
	
		getObj('scal_head').innerHTML=this.monthNames[this.currentMonth]+ ' ' + this.currentYear;
		daysOfMonth = this.getDays(this.currentYear)[this.currentMonth];
	
		for(i=1;i<=42;i++) {
			cell = getObj('scal_cell_'+i);
			cell.className='';
		
			if ((i >= startDay +1) && (i<=startDay+daysOfMonth)) {
				if (i-startDay==this.activeDay && this.currentMonth==this.activeMonth && this.currentYear==this.activeYear){
					cell.className='active';
				}
				cell.innerHTML=i-startDay;
				cell.onmouseover=this.cellOver;
				cell.onmouseout=this.cellOut;
				cell.onclick=this.cellClick;
				value = this.dateFormat;
				value = value.replace('yyyy', ''+this.currentYear);
				value = value.replace('mm', ''+(this.currentMonth+1<10?'0':'')+(this.currentMonth+1));
				value = value.replace('dd', ''+(i-startDay<10?'0':'')+(i-startDay));
				
				this.monthValue[i] = value;
				//this.monthValue[i]=''+this.currentYear+'-'+(this.currentMonth+1<10?'0':'')+(this.currentMonth+1)+'-'+(i-startDay<10?'0':'')+(i-startDay);
			}
			else {			
				cell.innerHTML='&nbsp;';
				cell.onmouseover=null;
				cell.onmouseout=null;
				cell.className='noday';
			}
		}
	},	
	nextMonth : function()	{	
		if (++this.currentMonth>=12) {
			this.currentMonth=0;
			this.currentYear++;
		}
		this.prepare();
	},	
	prevMonth : function()	{
		if (--this.currentMonth<0) {
			this.currentMonth=11;
			this.currentYear--;
		}
		this.prepare();
	},
	getDays : function(year){
		var daysNoLeap=new Array(31,28,31,30,31,30,31,31,30,31,30,31);
		var daysLeap=new Array(31,29,31,30,31,30,31,31,30,31,30,31);
		return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? daysLeap : daysNoLeap;
	},	
	cellOver : function(){
		if (this.className != 'active') this.className = 'hover';
	},
	cellOut : function(){
		if (this.className != 'active') this.className = '';
	},
	cellClick : function()	{
		Scal.inputObject.value=Scal.monthValue[this.id.substring(10)];
		Scal.container.style.display='none';
	},
	onElementFocus : function(e){
		obj = getEventTarget(e);

		obj.select();
		Scal.show(obj);
	},
	onElementClick : function(e){
		e.cancelBubble=true;
	},
	onElementBlur : function(e){
	},
	outsideClick : function(e) {
		obj=getEventTarget(e);
		if (Scal.container && !isChild(obj,Scal.container))
				Scal.container.style.display='none';
	}
};


function addEvent(obj, ev, func)
{
	if (obj.attachEvent) obj.attachEvent('on'+ev,func);
	else if (obj.addEventListener) obj.addEventListener(ev,func,false);
	else obj['on'+ev]=func;
}
function getEventTarget(e)
{
	e=e?e:window.event;
	var el;
	if(e.target)el=e.target;
	else if(e.srcElement)el=e.srcElement;
	if(el.nodeType==3)el=el.parentNode;
	return el;
}
function getObj(id)
{
	if (document.getElementById) {return document.getElementById(id);}
	else if (document.all) {return document.all[id];}
	else if (document.layers) {return document.layers[id];}
}
function getElementsByClassName(classname, node) {
	if(!node) node = document.getElementsByTagName("body").item(0);
	var a = [];
	var re = new RegExp('\\b' + classname + '\\b');
	var els = node.getElementsByTagName("*");
	for(var i=0,j=els.length; i<j; i++)
		if(re.test(els[i].className))
			a.push(els[i]);
	return a;
}
function getAbsoluteTop(obj)
{
	var top = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			top += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		top = obj.y;
		
	return top;
}
function getAbsoluteLeft(obj)
{
	var left = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			left += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		left += obj.x;
		
	return left;
}
function isChild(obj,container) {
	while(obj) {
		if (obj==container) return true;
		obj=obj.parentNode;
	}
	return false;
}  

if (typeof Array.indexOf != 'function') {
	Array.prototype.indexOf = function(f, s) {
		if (typeof s == 'undefined') s = 0;
			for (var i = s; i < this.length; i++) {
				if (f === this[i]) return i;
			}
		return -1;
	}
}


addEvent(window, 'load', function(){Scal.init();});
