function cal(sCalName){
	this.sName=sCalName;
	this.iOneDay=24*3600*1000;
	this.today=new Date();
	this.today=new Date(this.today.getFullYear(),this.today.getMonth(),this.today.getDate(),12);
	this.selType=null;
	this.selDate=null;
	this.tPopulatedDays=[];
	// all the following values can be set before calling this.render()
	this.clicked=null;
	this.getPopulatedDays=null;
	this.sToday="Today";
	this.sTomorrow="Tomorrow";
	this.tMonths=["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"];
	this.tDays=["Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota","Nedjelja"];
	this.headerColor='#DDDDDD';
	this.mouseOverColor='white';
	this.selectColor='#CCCCEE';
	this.previousMonthImageUrl="";
	this.nextMonthImageUrl="";
	this.bDaySelectable=true;
	this.bMonthSelectable=false;
}
// 'select' is called from the outside when an external action leads to a new selection
cal.prototype.select=function(sPeriod,date){
	this.updateSelection(sPeriod,date);
	this.show();
}
// 'selectInternal' is called on each click on the calendar
cal.prototype.selectInternal=function(sPeriod,date){
	this.select(sPeriod,date);
	if(this.clicked&&(
		(sPeriod=='day'&&this.bDaySelectable)||
		(sPeriod=='month'&&this.bMonthSelectable)
		))
		this.clicked(sPeriod,date);
}
cal.prototype.updateSelection=function(sPeriod,date){
	// move to the right month
	this.iFirstOfMonth=new Date(date.getFullYear(),date.getMonth(),1,12);
	// if the month changes, query the populated days
	if(this.selDate==null||!this.selDate.isSameMonth(this.iFirstOfMonth)){
		this.tPopulatedDays=[];
		if(this.getPopulatedDays)
			this.getPopulatedDays(this.iFirstOfMonth);
	}
	// store the new selection
	this.selType=sPeriod;
	this.selDate=date.clone();
}
cal.prototype.goToday=function(bClick){
	this.iFirstOfMonth=new Date(this.today.getFullYear(),this.today.getMonth(),1,12);
	this.show();
	if(bClick)
		this.selectInternal('day',this.today);
}
cal.prototype.goTomorrow=function(){
	var tomorrow=new Date(this.today.getTime()+this.iOneDay);
	this.iFirstOfMonth=new Date(tomorrow.getFullYear(),tomorrow.getMonth(),1,12);
	this.show();
	this.selectInternal('day',tomorrow);
}
cal.prototype.setPopulatedDays=function(tDays){
	this.tPopulatedDays=tDays;
	this.show();
}
cal.prototype.show=function(){
	var oTitle=document.getElementById(this.sName+"Title");
	oTitle.innerHTML=this.tMonths[this.iFirstOfMonth.getMonth()];

	var iFirstOfCal=this.iFirstOfMonth.lastMonday();
	for(var w=0;w<6;++w){
		for(var d=0;d<7;++d){
			var day=new Date(iFirstOfCal+this.iOneDay*(w*7+d));
			var oCell=this.oDays.rows[w+1].cells[d];
			oCell.innerHTML=day.getDate();
			oCell.date=day;
			if(!day.isSameMonth(this.iFirstOfMonth))
				oCell.style.color="#999999";
			else
				oCell.style.color="";
			oCell.bToday=day.isSameDay(this.today);
			this.setStyle(oCell,'day');
		}
	}
}
cal.prototype.initCells=function(){
	for(var w=0;w<6;++w){
		var oCell=this.oDays.rows[w+1].cells[0];
		for(var d=0;d<7;++d){
			var oCell=this.oDays.rows[w+1].cells[d];
			oCell.onmouseover=Function("this.bHover=true;"+this.sName+".cal.setStyle(this,'day')");
			oCell.onmouseout=Function("this.bHover=false;"+this.sName+".cal.setStyle(this,'day')");
			oCell.onclick=Function(this.sName+".cal.selectInternal('day',this.date)");
		}
	}
}
cal.prototype.setStyle=function(oCell,cellType){
	var bPopulated=false;
	for(var i=0;i<this.tPopulatedDays.length;++i)
		if(this.tPopulatedDays[i]==oCell.date.getDate()&&oCell.date.isSameMonth(this.iFirstOfMonth))
			bPopulated=true;
	if(oCell.bToday)
		oCell.className='dani_today';
	else if(bPopulated)
		oCell.className='dani_event';
	else
		oCell.className='dani';
	return;
	var s=oCell.style;
//	s.borderWidth=(oCell.bToday?'1px':'0');
	s.borderWidth='0';
	s.borderStyle='solid';
	s.borderColor='red';
	s.fontWeight=(oCell.bToday||bPopulated?'bold':'');
	var bSelected=false;
	if(this.selType=='day'&&oCell.date.isSameDay(this.selDate))
		bSelected=true;
	if((cellType=='month'||this.selType=='month')&&this.selDate&&oCell.date.isSameMonth(this.selDate))
		bSelected=true;
	s.backgroundColor=(bSelected?this.selectColor:oCell.bHover?this.mouseOverColor:'');
}
cal.prototype.moveMonth=function(dMonth){
	var absMonth=this.iFirstOfMonth.getMonth()+this.iFirstOfMonth.getFullYear()*12+dMonth;
	var iMonth=absMonth%12;
	var iYear=(absMonth-iMonth)/12;
	this.iFirstOfMonth=new Date(iYear,iMonth,1,12);
	this.updateSelection('month',this.iFirstOfMonth);
	this.show();
}
cal.prototype.moveYear=function(dYear){
	this.iFirstOfMonth=new Date(this.iFirstOfMonth.getFullYear()+dYear,this.iFirstOfMonth.getMonth(),1,12);
	this.show();
}
cal.prototype.render=function(){
	var s=[];
	s.push('<table id="'+this.sName+'" border="0" cellspacing="0" cellpadding="0" style="cursor:default" align="center">');
	s.push('<tr><td align="center" valign="top" bgcolor="#E6E6E6">');
	s.push('	<table width="170" height="21" border="0" cellpadding="0" cellspacing="0" bgcolor="'+this.headerColor+'" class="mjesec">');
	s.push('		<tr align="center" valign="middle">');
	s.push('		<td width="15"><a href="#" onclick="event.returnValue=false;'+this.sName+'.cal.moveMonth(-1)" ondblclick="this.onclick()"><img src="'+this.previousMonthImageUrl+'" border="0"></a></td>');
	s.push('		<td align="center"><b id="'+this.sName+'Title"></b></td>');
	s.push('		<td width="15"><a href="#" onclick="event.returnValue=false;'+this.sName+'.cal.moveMonth(1)" ondblclick="this.onclick()"><img src="'+this.nextMonthImageUrl+'" border="0"></a></td>');
	s.push('		</tr>');
	s.push('	</table>');
	s.push('	<table width="170" height="1" border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF"><tr><td><img src="site/_space.gif" width="1" height="1"></td></tr></table>');
	s.push('	<table width="160" height="16" border="0" cellspacing="0" cellpadding="0" bgcolor="white" id="'+this.sName+'Days" class="dani" background="site/kal_n_blank.gif">');
	s.push('		<tr align="center" valign="middle">');
	for(var i=0;i<7;++i)
	s.push('			<td width="16" height="16" title="'+this.tDays[i]+'"><b>'+this.tDays[i].charAt(0)+'</b></td>');
	s.push('		</tr>');
	for(var i=0;i<6;++i)
		s.push('		<tr align="center" valign="middle"><td width="16" height="16"></td><td width="16" height="16"></td><td width="16" height="16"></td><td width="16" height="16"></td><td width="16" height="16"></td><td width="16" height="16"></td><td width="16" height="16"></td></tr>');
	s.push('	</table>');
	s.push('	<table width="170" height="10" border="0" cellpadding="0" cellspacing="0"><tr><td><img src="site/_space.gif" width="1" height="1"></td></tr></table>');
	s.push('</td></tr></table>');
	document.write(s.join(''));
	this.oTable=document.getElementById(this.sName);
	this.oTable.cal=this;
	this.oDays=document.getElementById(this.sName+'Days');
	this.oMonths=document.getElementById(this.sName+'Months');
	this.initCells();
	this.goToday(false);
}
// Date object enhancements
Date.prototype.oneDay=24*3600*1000;
Date.prototype.clone=function(){
	return new Date(this.getFullYear(),this.getMonth(),this.getDate(),12);
}
Date.prototype.isSameMonth=function(d){
	return this.getFullYear()==d.getFullYear()&&this.getMonth()==d.getMonth();
}
Date.prototype.isSameWeek=function(d){
	var myMonday=new Date(this-this.weekDay()*this.oneDay);
	var dsMonday=new Date(d-d.weekDay()*this.oneDay);
	return myMonday.isSameDay(dsMonday);
}
Date.prototype.isSameDay=function(d){
	return this.getFullYear()==d.getFullYear()&&this.getMonth()==d.getMonth()&&this.getDate()==d.getDate();
}
Date.prototype.weekDay=function(){//0=monday
	return (this.getDay()+7-1)%7;
}
Date.prototype.lastMonday=function(){
	return this.clone()-this.weekDay()*this.oneDay;
}
Date.prototype.getWeek=function(){
	var dayJan01=new Date(this.getFullYear(),0,1,12);
	return Math.floor((this-dayJan01.lastMonday())/7/this.oneDay)+1;
}
Date.prototype.toShortDateString=function(){
	return this.getDate()+'/'+(this.getMonth()+1)+'/'+this.getFullYear()+' '+this.toTimeString();
}