/******
 * Author: Sebastian Haller
 * Date: 2005
 * Calendar Class
 */

function calendar(name, objname)
{
	// hide it when user clicks
  var oldfunc = document.onclick;
  if (typeof oldfunc != 'function')
  {
		document.onclick = function() {eval(name+'.hide();');};
  }
  else
  {
    document.onclick = function()
	    {
	      oldfunc();
	      eval(name+'.hide();');
	    };
  }

	this.name = name; // name of object you are creating
	this.objname = objname;
	this.obj = null;
	
	this.op = window.opera;
	this.ie = document.all && !this.op;
	this.ns = document.getElementById && !this.ie && !this.op;
	
	if (this.ie)
	{
		document.write('<iframe id="iframe_'+objname+'" name="iframe_'+objname+'" src="/includes/pixel.gif"  style="position: absolute; left:0; top:0; width:0; height:0; visibility:hidden; filter:alpha(opacity=0); z-index: 1"></iframe>');
		this.iframeobjname = 'iframe_'+objname;
		this.iframeobj = null;
	}

	this.cancelbubble =
		function(e)
		{
			if (window.event)
				event.cancelBubble=true;
			else if (e.stopPropagation)
				e.stopPropagation();

			return false;
		};

	this.hide =
		function()
		{
			if (this.obj == null)
				return false;
		
			this.obj.style.left = this.obj.style.top = -500;
			this.obj.style.visibility = 'hidden';
		
			if (this.ie)
				this.iframeobj.style.visibility = 'hidden';

			clearTimeout(this.timeout);

			return false;
		};

	this.swap =
		// Opens, closes calendar window.
		// @param   string      object
		// @param   string      event
		// @param   string      field name
		// @param   string      edit type - date/timestamp
		function(obj, e, datefield, datetype)
		{
			this.obj = document.getElementById(this.objname);
			if (this.ie)
				this.iframeobj = document.getElementById(this.iframeobjname);
		
			this.cancelbubble(e);

			if (e.type=="click" && (this.obj.style.visibility=='hidden' || this.obj.style.visibility=='') || e.type=="mouseover")
				this.show(obj, datefield, datetype);
			else if (e.type=="click")
				this.hide();
		
			return false;
		};

	this.show =
		// Opens calendar window.
		// @param   string      object
		// @param   string      field name
		// @param   string      edit type - date/timestamp
		function(obj, datefield, datetype)
		{
			this.obj = document.getElementById(this.objname);
			if (this.ie)
				this.iframeobj = document.getElementById(this.iframeobjname);
		
			this.datefield = document.getElementById(datefield);
			this.datetype = datetype
			this.iyear = NaN;
			this.imonth = NaN;
			this.year = NaN;
			this.month = NaN;
			this.day = NaN;
			this.hour = NaN;
			this.minute = NaN;
			this.second = NaN;
	
			this.obj.style.left = this.obj.style.top = -500;
			this.obj.style.left = this.getoffset(obj, 'x') + "px";
			this.obj.style.top = this.getoffset(obj, 'y') + obj.offsetHeight + "px";
		
			this.obj.style.visibility = 'visible';
		
			this.initcalendar();

			if (this.ie)
			{
				this.iframeobj.style.left = this.obj.style.left;
				this.iframeobj.style.top = this.obj.style.top;
				this.iframeobj.style.width = this.obj.offsetWidth;
				this.iframeobj.style.height = this.obj.offsetHeight;
				this.iframeobj.style.visibility = 'visible';
			}
			
			clearTimeout(this.timeout);

			return false;
		};

	this.iecompat =
		function()
		{
			return (document.compatMode && document.compatMode != 'BackCompat') ? document.documentElement : document.body;
		};

	this.getoffset =
		function(obj, which)
		{
			var offset = (which == 'x') ? obj.offsetLeft : obj.offsetTop;
			var parent = obj.offsetParent;
			while (parent!=null)
			{
				offset += (which == 'x') ? parent.offsetLeft : parent.offsetTop;
				parent = parent.offsetParent;
			}
			
			// check, if there is enough space in the broser
			if (which == 'x')
			{
				var windowedge = this.ie ? this.iecompat().scrollLeft+this.iecompat().clientWidth-15 : window.pageXOffset+window.innerWidth-15;
				if (windowedge-offset < this.obj.offsetWidth)
					offset -= this.obj.offsetWidth - obj.offsetWidth;
			}
			else
			{
				var topedge = this.ie ? this.iecompat().scrollTop : window.pageYOffset;
				var windowedge = this.ie ? this.iecompat().scrollTop+this.iecompat().clientHeight-15 : window.pageYOffset+window.innerHeight-18;
				if (windowedge-offset < this.obj.offsetHeight)
				{
					offset -= this.obj.offsetHeight + obj.offsetHeight;
					if (offset-topedge < this.obj.offsetHeight)
						offset = topedge - obj.offsetHeight;
				}
			}
		
			return offset;
		};

	this.formatnum2 =
		// Formats number to two digits.
		// @param   int number to format.
		function(i, valtype)
		{
			f = (i < 10 ? '0' : '') + i;
			if (valtype && valtype != '')
			{
				switch(valtype)
				{
        	case 'month':
						f = (f > 12 ? 12 : f);
						break;
		
					case 'day':
						f = (f > 31 ? 31 : f);
						break;
		
					case 'hour':
						f = (f > 23 ? 23 : f);
						break;
		
					default:
					case 'second':
					case 'minute':
						f = (f > 59 ? 59 : f);
						break;
				}
			}
		
			return f;
		};

	this.formatnum4 =
		// Formats number to four digits.
		// @param   int number to format.
		function(i)
		{
			return (i < 1000 ? i < 100 ? i < 10 ? '000' : '00' : '0' : '') + i;
		};

	// Initializes calendar window.
 this.initcalendar =
		function() {
			if (!this.year && !this.month && !this.day)
			{
				/* Called for first time */
				if (this.datefield.value)
				{
					value = this.datefield.value;
					if (this.datetype == 'datetime' || this.datetype == 'date')
					{
						if (this.datetype == 'datetime')
						{
							parts = value.split(' ');
							value = parts[0];
		
							if (parts[1])
							{
								time = parts[1].split(':');
								this.hour = parseInt(time[0],10);
								this.minute = parseInt(time[1],10);
								this.second = parseInt(time[2],10);
							}
						}
						date = value.split("-");
						this.iyear = parseInt(date[0],10);
						this.imonth = parseInt(date[1],10) - 1;
						this.day = parseInt(date[2],10);
					}
					else
					{
						this.iyear = parseInt(value.substr(0,4),10);
						this.imonth = parseInt(value.substr(4,2),10) - 1;
						this.day = parseInt(value.substr(6,2),10);
						this.hour = parseInt(value.substr(8,2),10);
						this.minute = parseInt(value.substr(10,2),10);
						this.second = parseInt(value.substr(12,2),10);
					}
				}
				if (isNaN(this.iyear) || isNaN(this.imonth) || isNaN(this.day) || !this.day)
				{
					dt = new Date();
					this.iyear = dt.getFullYear();
					this.imonth = dt.getMonth();
					this.day = dt.getDate();
				}
				if (isNaN(this.hour) || isNaN(this.minute) || isNaN(this.second))
				{
					dt = new Date();
					this.hour = dt.getHours();
					this.minute = dt.getMinutes();
					this.second = dt.getSeconds();
				}
				this.year = this.iyear;
				this.month = this.imonth;
			}
			else
			{
				/* Moving in calendar */
				if (this.month > 11)
				{
					this.month = 0;
					this.year++;
				}
				if (this.month < 0)
				{
					this.month = 11;
					this.year--;
				}
			}
		
			str = "";
			//heading table
			str += '<table class="calendar"><tr><th width="50%">';
			str += '<form method="NONE" onsubmit="return 0">';
			str += '<a href="javascript:'+this.name+'.month--; '+this.name+'.initcalendar();">&laquo;</a> ';
			str += '<select id="select_month" name="monthsel" onchange="'+this.name+'.month = parseInt(document.getElementById(\'select_month\').value); '+this.name+'.initcalendar();">';
			for (i =0; i < 12; i++)
			{
				if (i == this.month)
					selected = ' selected="selected"';
				else
					selected = '';
				str += '<option value="' + i + '" ' + selected + '>' + month_names[i] + '</option>';
			}
			str += '</select>';
			str += ' <a href="javascript:'+this.name+'.month++; '+this.name+'.initcalendar();">&raquo;</a>';
			str += '</form>';
			str += '</th><th width="50%">';
			str += '<form method="NONE" onsubmit="return 0">';
			str += '<a href="javascript:'+this.name+'.year--; '+this.name+'.initcalendar();">&laquo;</a> ';
			str += '<select id="select_year" name="yearsel" onchange="'+this.name+'.year = parseInt(document.getElementById(\'select_year\').value); '+this.name+'.initcalendar();">';
			for (i = this.year - 25; i < this.year + 25; i++)
			{
				if (i == this.year)
					selected = ' selected="selected"';
				else
					selected = '';
				str += '<option value="' + i + '" ' + selected + '>' + i + '</option>';
			}
			str += '</select>';
			str += ' <a href="javascript:'+this.name+'.year++; '+this.name+'.initcalendar();">&raquo;</a>';
			str += '</form>';
			str += '</th></tr></table>';
		
			str += '<table class="calendar"><tr>';
			for (i = 0; i < 7; i++)
				str += "<th>" + day_names[i] + "</th>";
			str += "</tr>";
		
			var firstDay = new Date(this.year, this.month, 1).getUTCDay();
			// first day of week is Sunday or Monday (complies with ISO standard 8601, section 3.17)
			//firstDay = (firstDay-1) % 7;
			var lastDay = new Date(this.year, this.month + 1, 0).getDate();
		
			str += "<tr>";
		
			dayInWeek = 0;
			for (i = 0; i < firstDay; i++)
			{
				str += "<td>&nbsp;</td>";
				dayInWeek++;
			}
			for (i = 1; i <= lastDay; i++)
			{
				if (dayInWeek == 7)
				{
					str += "</tr><tr>";
					dayInWeek = 0;
				}
		
				dispmonth = 1 + this.month;
		
				if (this.datetype == 'datetime' || this.datetype == 'date')
					actVal = this.formatnum4(this.year) + "-" + this.formatnum2(dispmonth, 'month') + "-" + this.formatnum2(i, 'day');
				else
					actVal = "" + this.formatnum4(this.year) + this.formatnum2(dispmonth, 'month') + this.formatnum2(i, 'day');
				if (this.year==this.iyear && this.month==this.imonth && i == this.day)
					style = ' class="selected"';
				else
					style = '';
				str += '<td' + style + '><a href="javascript:'+this.name+'.returndate(\'' + actVal + '\');">' + i + '</a></td>';
				dayInWeek++;
			}
			for (i = dayInWeek; i < 7; i++)
				str += '<td>&nbsp;</td>';
		
			str += '</tr></table>';
		
			// Should we handle time also?
			if (this.datetype != 'date')
			{
				str += '<table class="calendar"><tr><td width="100%">';
				str += '<form class="clock">';
				str += '<input id="hour" type="text" size="2" maxlength="2" onblur="this.value='+this.name+'.formatnum2(this.value, \'hour\');'+this.name+'.hour=parseInt(this.value,10)" value="' + this.formatnum2(this.hour, 'hour') + '" />:';
				str += '<input id="minute" type="text" size="2" maxlength="2" onblur="this.value='+this.name+'.formatnum2(this.value, \'minute\');'+this.name+'.minute=parseInt(this.value,10)" value="' + this.formatnum2(this.minute, 'minute') + '" />:';
				str += '<input id="second" type="text" size="2" maxlength="2" onblur="this.value='+this.name+'.formatnum2(this.value, \'second\');'+this.name+'.second=parseInt(this.value,10)" value="' + this.formatnum2(this.second, 'second') + '" />';
				str += '</form>';
				str += '</td></tr></table>';
			}
			
			this.obj.innerHTML = str;
		};

 	this.returndate =
		// Returns date from calendar.
		// @param   string     date text
		function(d)
		{
			var txt = d;
			if (this.datetype != 'date')
			{
				// need to get time
				h = parseInt(document.getElementById('hour').value,10);
				m = parseInt(document.getElementById('minute').value,10);
				s = parseInt(document.getElementById('second').value,10);
				if (this.datetype == 'datetime') {
					txt += ' ' + this.formatnum2(h, 'hour') + ':' + this.formatnum2(m, 'minute') + ':' + this.formatnum2(s, 'second');
				}
				else
				{
					// timestamp
					txt += this.formatnum2(h, 'hour') + this.formatnum2(m, 'minute') + this.formatnum2(s, 'second');
				}
			}
		
			this.datefield.value = txt;
		
			this.hide();
		};

	return true;
}
