﻿var Order = {};
Order.OrderXml = null;
Order.OrderHtml = null;
Order.ConditionsPageId = 0; 
Order.MustConfirm = typeof(ShowOrderConfirmation) != 'undefined' ? ShowOrderConfirmation : false;

Order.ShowConfirmation = function(html)
{
    Order.LightBox.Show(html);
}

Order.Serialize = function(frm)
{
    var prodOk = false;
    var dateOk = false;
    var reason = '';
    var o;

    // check delivery dates
    var dateCheck = Order.CheckDeliveryDates();
    dateOk = dateCheck.Ok;
    if (!dateOk) reason = dateCheck.Reason;
    
    var html = [];
    html.push('<div class="section" style="padding:24px">');
    html.push('<h1 style="font-size:18px">Bestilling</h1>');
    html.push('<table style="margin-top:2em;margin-left:-8px" class="section" cellspacing="8">');
    html.push('<tr style="font-weight:700"><td class="section">Betegnelse</td><td class="section">Enhed</td><td class="section">Varenr.</td><td class="section">Antal</td><td class="section">Bemærkninger</td></tr>');

    var s = ['<?xml version="1.0" encoding="utf-8" ?>\n'];
    s.push('<fields>\n');
    var coll = frm.getElementsByTagName('input');
    for (var i=0; i<coll.length; i++)
    {
        var inp = coll[i];
        if (inp.type != 'submit' && inp.type != 'reset')
        {
            s.push('<field name="' + inp.id + '" type="' + inp.type + '"');
            var isProdCount = (inp.id.indexOf('productcount') > -1);
            if (isProdCount) s.push(' productcount="true"');
            s.push('>');
            switch (inp.type)
            {
                case 'text':
                case 'hidden':
                if (isProdCount && inp.value != '' && inp.value != '0') 
                {
                    prodOk = true;
                    var prodNum = inp.id.split('_')[1];
                    html.push(Order.GetOrderLineHtml(prodNum, inp.value));
                }
                s.push('[->' + Order.Encode(inp.value) + '<-]');
                break;
                case 'checkbox':
                case 'radio':
                s.push(inp.checked.toString());
                break;
            }
            s.push('</field>\n');
        }
    }
    coll = frm.getElementsByTagName('select');
    for (i=0; i<coll.length; i++)
    {
        var sel = coll[i];
        s.push('<field name="' + sel.id + '" type="select" value="[->' + Order.Encode(sel[sel.selectedIndex].value) + '<-]">[->' + Order.Encode(sel[sel.selectedIndex].innerHTML) + '<-]</field>\n');
    }
    coll = frm.getElementsByTagName('textarea');
    for (i=0; i<coll.length; i++)
    {
        var area = coll[i];
        s.push('<field name="' + area.id + '" type="textarea">[->' + Order.Encode(area.innerHTML) + '<-]</field>\n');
    }
    s.push('</fields>');
    var xml = s.join('').replace(/\&/g, '&amp;');
    var ok = (prodOk && dateOk);
    if (dateOk)
    {
        if (!prodOk) reason = 'Indtast venligst et tal i feltet "Antal" ud for mindst et produkt';
    }
    html.push('</table>');
    var comment = document.getElementById('comments');
    if (comment && comment.value != '') html.push('<p>Bemærkninger til bestilling: ' + comment.value + '</p>');
    var add = document.getElementById('deliveryaddress');
    html.push('<p>Leveringsadresse: ' + add[add.selectedIndex].innerHTML + '.<br />');
    var date = document.getElementById('deliverydate');
    var lastdate = document.getElementById('lastdeliverydate');
    if (lastdate) html.push('Ønsket tidligste leveringsdato: ' + date.value + '. Ønsket seneste leveringsdato: ' + lastdate.value + '.</p>');
    else html.push('Ønsket leveringsdato: ' + date.value + '.</p>');
    html.push('<p><input style="border:none; background:transparent;" type="checkbox" id="chkcond" onclick="document.getElementById(\'orderbtn\').disabled = !this.checked;" /> <label for="chkcond">Jeg har læst og accepterer</label> <a target="_new" class="inlinelink" href="index.dsp?page=' + Order.ConditionsPageId + '">salgsbetingelserne</a>.</p>');
    html.push('<p class="confirmationlinks"><input id="orderbtn" disabled type="button" onclick="parent.Order.Confirmed();" value="Send bestilling" /> ');
    html.push('&nbsp; &nbsp;<input id="orderclosebtn" type="button" onclick="parent.Order.Cancelled();" value="Rediger bestilling" /></p>');
    html.push('<p style="font-size:9px">Klik på "Send bestilling" hvis bestillingen er korrekt. Husk at acceptere salgsbetingelserne først ved at sætte flueben.<br />Klik på "Rediger bestilling" for at gå tilbage og ændre bestillingen.</p>');
    html.push('</div>');
    html = html.join('');
    return {Xml:xml,Html:html,Ok:ok,Reason:reason};
}

Order.GetOrderLineHtml = function(prodNum, prodCount)
{
    var s = [];
    var unit = document.getElementById('productunit_' + prodNum); // span or select
    var u = (unit) ? (unit.tagName.toLowerCase() == 'select') ? unit[unit.selectedIndex].innerHTML : unit.innerHTML : '';
    var name = document.getElementById('productname_' + prodNum); // span
    var n = (name) ? name.innerHTML : '';
    var comment = document.getElementById('productcomment_' + prodNum) || document.getElementById('productsilo_' + prodNum); // input
    var c = (comment) ? comment.value : '';
    s.push('<tr><td class="section">' + n + '</td><td class="section">' + u + '</td><td class="section">' + prodNum + '</td><td class="section" align="right">' + prodCount + '</td><td class="section">' + c + '</td></tr>');
    return s.join('');
}

Order.CheckDeliveryDates = function()
{
    var devDate = document.getElementById('deliverydate');
    var lastDevDate = document.getElementById('lastdeliverydate');
    var dateOk = false;
    var lastDateOk = (lastDevDate == null);
    var reason = '';
    var now = new Date();
    now.setHours(12,0,0,0);
    var minDays = 3;
    if (typeof(NumberOfDaysBeforeDelivery) != 'undefined') minDays = NumberOfDaysBeforeDelivery;
    if (false && devDate)
    {
        var d = Order.GetDateFromInput(devDate);
        if (!d) reason = 'Indtast eller vælg venligst en ønsket leveringsdato (dd-mm-åååå)';
        else if (d <= now) reason = 'Indtast eller vælg venligst en fremtidig leveringsdato';        
        else if (!lastDevDate)
        {
            o = Order.IsValidDeliveryDate(d, minDays, false);
            if (!o.Valid) reason = o.Reason;
            else dateOk = true;
        }
        else dateOk = true;
    }
    if (lastDevDate)
    {
        var ld = Order.GetDateFromInput(lastDevDate);
        if (!ld) reason = 'Indtast eller vælg venligst en ønsket seneste leveringsdato (dd-mm-åååå)';
        else if (ld <= now) reason = 'Indtast eller vælg venligst en fremtidig seneste leveringsdato';        
        else if ((ld - d) < 0) reason = 'Indtast eller vælg venligst en seneste leveringsdato, der ligger efter tidligste leveringsdato';
        else
        {
            o = Order.IsValidDeliveryDate(ld, minDays, true);
            if (!o.Valid) reason = o.Reason;
            else lastDateOk = true;
        }
    }
    var ok = (dateOk && lastDateOk);
    return {Ok:ok,Reason:reason};
}

Order.OnSubmit = function(frm)
{
    var o = Order.Serialize(frm);
    if (!o.Ok)
    {
        if (modal) modal.style.display = 'none';
        alert(o.Reason);
    }
    else
    {
//        alert(o.Xml);
//        return false;
        Order.OrderXml = o.Xml;
        if (Order.MustConfirm) Order.ShowConfirmation(o.Html);
        else Order.Confirmed();
    }
    return false;    
}

Order.Confirmed = function()
{
    Order.LightBox.Hide();
    var modal = document.getElementById('modal');
    if (modal)
    {
        modal.style.height = document.body.offsetHeight + 'px';
        modal.style.width = document.body.offsetWidth + 'px';
        modal.style.display = '';
        window.scrollTo(0,0);
    }
    if (!Order.OrderXml) return;
    var frame = document.getElementById('orderformframe');
    var fld = frame.contentWindow.document.getElementById('idxml');
    var forms = frame.contentWindow.document.getElementsByTagName('form');
    var form = null;
    for (var i=0; i<forms.length; i++)
    {
        if (forms[i].name.indexOf('orderform') > -1)
        {
            form = forms[i];
            continue;
        }
    }
    fld.value = Order.OrderXml;
    if (form)
    {
        form.target = '_parent';
        form.submit();
    }
}

Order.Cancelled = function()
{
    Order.LightBox.Hide();
    Order.OrderXml = null;
}

Order.IsValidDeliveryDate = function(date, minDays, isLast)
{
    var o = {};
    o.Valid = true;
    o.Reason = '';
    var s = (isLast) ? 'Seneste levering ' : 'Levering ';
    var now = new Date();
    now.setHours(12,0,0,0);
    var days = (date - now) / (1000*60*60*24);
    if (days < minDays)
    {
        o.Valid = false;
        o.Reason = s + 'skal ligge tidligst ' + minDays + ' dag(e) frem i tiden';
    }
    if (typeof(InvalidDates) != 'undefined')
    {
        for (var i=0; i<InvalidDates.length; i++)
        {
            var arr = InvalidDates[i];
            var d = Order.GetDateFromString(arr[0].split(' ')[0]);
//          alert(date + ' = ' + d + ' ? ' + (date.toString()===d.toString()));
            if (date.toString() === d.toString())
            {
                o.Valid = false;
                o.Reason = s + 'kan ikke finde sted på den valgte dato, som er ' + arr[1].toLowerCase();
                break;
            }
        }
    }
    return o;
}

Order.DatePartToInt = function(s)
{
    if (s.indexOf('0') == 0) s = s.substring(1);
    return parseInt(s);
}

Order.GetDateFromString = function(s)
{
    var date = new Date();
    var arr = s.split('-');
    date.setFullYear(Order.DatePartToInt(arr[2]));
    date.setMonth(Order.DatePartToInt(arr[1])-1);
    date.setDate(Order.DatePartToInt(arr[0]));
    return date;
}

Order.GetDateFromInput = function(inp)
{
    if (!/\d{2}\-\d{2}\-20\d{2}/.test(inp.value)) return null;
    return Order.GetDateFromString(inp.value);
}

Order.Encode = function(s)
{
    return s.replace(/\&/g, '%26').replace(/\</g, '%3C').replace(/\>/g, '%3E');
}

Order.ValidateEntry = function(evt, allowComma, allowHyphen)
{
    var e = evt || window.event;
    if (!e) return;
    var k = e.keyCode || e.charCode;
    // numbers: 48-57 / 96-105, backspace: 8, tab: 9, del: 46, comma: 110/188
    // arrows: 37-40, home: 36, end: 35, hyphen: 109/189
    var allow = (k == 8 || k == 9 || (k >= 35 && k <= 40) || k == 46 || (k >= 48 && k <= 57) || (k >= 96 && k <= 105) || ((k == 110 || k == 188) && allowComma) || ((k == 109 || k == 189) && allowHyphen));
    if (!allow) 
    {
        e.returnValue = false;
        if (e.preventDefault) e.preventDefault();
        return false;
    }
}

Order.ValidateEntryLength = function(evt, fld, maxLength)
{
    var e = evt || window.event;
    if (!e) return;
    var k = e.keyCode || e.charCode;
    // backspace: 8, tab: 9, del: 46, arrows: 37-40, home: 36, end: 35
    var alwaysAllow = (k == 8 || k == 9 || (k >= 35 && k <= 40) || k == 46);
    var allow = (fld.value.length <= maxLength || alwaysAllow);
    if (!allow) 
    {
        e.returnValue = false;
        if (e.preventDefault) e.preventDefault();
        return false;
    }
}

var Calendar = function(id, culture, year, month, day, hours, minutes)
{
	this.Id = id;
	this.Today = new Date();
	this.InvalidDateRanges = [];
	this.Disabled = false;
	// settings
	this.WeekStartsOnMonday = true;
	this.ShowCloseButton = true;
	this.ShowNavigationBar = true;
	this.ShowTodayInNavigationBar = true;
	this.ShowTimeBar = false;
	// events
	this.OnMonthChanged = null;
	this.OnTimeChanged = null;
	this.OnDaySelected = null;
	this.OnClose = function() {return true};


	this.ApplyCulture = function(culture)
	{
		this.Culture = (culture) ? culture : 'da';
		switch (culture)
		{
			case 'de': /* German */
				this.Months = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
				this.MonthsAbbreviated = ['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'];
				this.Days = ['Mon','Die','Mit','Don','Fre','Sam','Son'];
				this.WeekString = 'Woche';
				this.TodayIsString = 'Heute';
				this.TodayString = 'Heute';
				this.TimeString = '';
				this.PreviousYearString = 'Vorige Jahr';
				this.NextYearString = 'Nächste Jahr';
				this.PreviousMonthString = 'Vorige Monat';
				this.NextMonthString = 'Nächste Monat';
				break;
			case 'no': /* Norwegian */
				this.Months = ['Januar','Februar','Mars','April','Mai','Juni','Juli','August','September','Oktober','November','Desember'];
				this.MonthsAbbreviated = ['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Des'];
				this.Days = ['Man','Tir','Ons','Tor','Fre','Lør','Søn'];
				this.WeekString = 'Uke';
				this.TodayIsString = 'Dagen i dag er';
				this.TodayString = 'I dag';
				this.TimeString = 'Tid';
				this.PreviousYearString = '';
				this.NextYearString = '';
				this.PreviousMonthString = '';
				this.NextMonthString = '';
				break;
			case 'es': /* Spanish */
				this.Months = ['Enero','Febrero','Marzo','April','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
				this.MonthsAbbreviated  = ['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'];
				this.Days = ['Lun','Mar','Mie','Jue','Vie','Sab','Dom'];
				this.WeekString = 'Semana';
				this.TodayIsString = 'Hoy es';
				this.TodayString = 'Hoy';
				this.TimeString = '';
				this.PreviousYearString = '';
				this.NextYearString = '';
				this.PreviousMonthString = '';
				this.NextMonthString = '';
				break;
			case 'fr': /* French */
				this.Months = ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'];
				this.MonthsAbbreviated = ['Jan','Fev','Mar','Avr','Mai','Jun','Jul','Aou','Sep','Oct','Nov','Dec'];
				this.Days = ['Lun','Mar','Mer','Jeu','Ven','Sam','Dim'];
				this.WeekString = 'Sem';
				this.TodayIsString = "Aujourd'hui";
				this.TodayString = 'Aujourd';
				this.TimeString = '';
				this.PreviousYearString = '';
				this.NextYearString = '';
				this.PreviousMonthString = '';
				this.NextMonthString = '';
				break;
			case 'en': /* English */
				this.Months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
				this.MonthsAbbreviated = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
				this.Days = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
				this.WeekString = 'Week';
				this.TodayIsString = '';
				this.TodayString = 'Today';
				this.TimeString = 'Time';
				this.PreviousYearString = 'Previous year';
				this.NextYearString = 'Next year';
				this.PreviousMonthString = 'Previous month';
				this.NextMonthString = 'Next month';
				break;
			default: /* Danish */
				this.Months = ['januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december'];
				this.MonthsAbbreviated = ['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'];
				this.Days = ['man','tir','ons','tor','fre','lør','søn'];
				this.WeekString = 'Uge';
				this.TodayIsString = 'I dag er den';
				this.TodayString = 'Dags dato';
				this.TimeString = 'Tid';
				this.PreviousYearString = 'Forrige år';
				this.NextYearString = 'Næste år';
				this.PreviousMonthString = 'Forrige måned';
				this.NextMonthString = 'Næste måned';
				break;	
		}
	}

	this.ApplyDateTime = function(year, month, day, hours, minutes)
	{
		var d = new Date();
		this.InitialYear = (year) ? year : d.getFullYear();
		this.InitialMonth = (month) ? month : d.getMonth()+1;
		this.InitialDay = (day) ? day : d.getDate();
		this.InitialHours = (hours) ? hours : d.getHours();
		this.InitialMinutes = (minutes) ? minutes : d.getMinutes();
		this.SetDisplayedData();
	}
	
	this.AddInvalidDateRange = function(fromDateAsArray,toDateAsArray)
	{
		var index = this.InvalidDateRanges.length;
		this.InvalidDateRanges[index] = new Object();
		if (fromDateAsArray)
		{
			fromDateAsArray.day = fromDateAsArray.day + '';
			fromDateAsArray.month = fromDateAsArray.month + '';
			fromDateAsArray.year = fromDateAsArray.year + '';
			if (!fromDateAsArray.month) fromDateAsArray.month = fromDateAsArray.month = '1';
			if (!fromDateAsArray.day) fromDateAsArray.day = fromDateAsArray.day = '1';
			if (fromDateAsArray.day.length == 1) fromDateAsArray.day = '0' + fromDateAsArray.day;
			if (fromDateAsArray.month.length==1) fromDateAsArray.month= '0' + fromDateAsArray.month;
			this.InvalidDateRanges[index].fromDate = fromDateAsArray.year + fromDateAsArray.month + fromDateAsArray.day;
		}
		else
		{
			this.InvalidDateRanges[index].fromDate = null;
		}
		if (toDateAsArray)
		{
			toDateAsArray.day = toDateAsArray.day + '';
			toDateAsArray.month = toDateAsArray.month + '';
			toDateAsArray.year = toDateAsArray.year + '';
			if (!toDateAsArray.month) toDateAsArray.month = toDateAsArray.month = '1';
			if (!toDateAsArray.day) toDateAsArray.day = toDateAsArray.day = '1';
			if (toDateAsArray.day.length == 1) toDateAsArray.day = '0' + toDateAsArray.day;
			if (toDateAsArray.month.length == 1) toDateAsArray.month = '0' + toDateAsArray.month;
			this.InvalidDateRanges[index].toDate = toDateAsArray.year + toDateAsArray.month + toDateAsArray.day;
		}
		else
		{
			this.InvalidDateRanges[index].toDate = null;
		}
	}
	
	this.IsValidDate = function(inputDate)
	{
		if (this.InvalidDateRanges.length == 0) return true;
		var month = inputDate.month + '';
		if (month.length == 1) month = '0' + month;
		var day = inputDate.day + '';
		if (day.length == 1) day = '0' + day;
		var dateToCheck = inputDate.year + month + day;
		for (var i=0; i<this.InvalidDateRanges.length; i++)
		{
			if (!this.InvalidDateRanges[i].fromDate && this.InvalidDateRanges[i].toDate >= dateToCheck) return false;
			if (!this.InvalidDateRanges[i].toDate && this.InvalidDateRanges[i].fromDate <= dateToCheck) return false;
			if (this.InvalidDateRanges[i].fromDate <= dateToCheck && this.InvalidDateRanges[i].toDate >= dateToCheck) return false;
		}
		return true;
	}
	
	this.SetDateFromString = function(dateString, format)
	{
		if (dateString && dateString.length > 0)
		{
			if (!format.match(/^[0-9]*?$/gi))
			{
				var items = dateString.split(/[^0-9]/gi);
				var positionArray = new Object();
				positionArray.m = format.indexOf('mm');
				if (positionArray.m == -1) positionArray.m = format.indexOf('m');
				positionArray.d = format.indexOf('dd');
				if (positionArray.d == -1) positionArray.d = format.indexOf('d');
				positionArray.y = format.indexOf('yyyy');
				positionArray.h = format.indexOf('hh');
				positionArray.i = format.indexOf('ii');
				var positionArrayNumeric = Array();
				positionArrayNumeric[0] = positionArray.m;
				positionArrayNumeric[1] = positionArray.d;
				positionArrayNumeric[2] = positionArray.y;
				positionArrayNumeric[3] = positionArray.h;
				positionArrayNumeric[4] = positionArray.i;
				positionArrayNumeric = positionArrayNumeric.sort(this.SortItems);
				var itemIndex = -1;
				this.initialHour = '00';
				this.initialMinute = '00';
				for (var i = 0; i<positionArrayNumeric.length; i++)
				{
					if (positionArrayNumeric[i] == -1) continue;
					itemIndex++;
					if (positionArrayNumeric[i] == positionArray['m'])
					{
						this.InitialMonth = items[itemIndex];
						continue;
					}
					if (positionArrayNumeric[i] == positionArray['y'])
					{
						this.InitialYear = items[itemIndex];
						continue;
					}
					if (positionArrayNumeric[i] == positionArray['d'])
					{
						tmpDay = items[itemIndex];
						continue;
					}
					if (positionArrayNumeric[i] == positionArray['h'])
					{
						this.InitialHours = items[itemIndex];
						continue;
					}
					if (positionArrayNumeric[i] == positionArray['i'])
					{
						this.InitialMinutes = items[itemIndex];
						continue;
					}
				}
				this.InitialMonth = this.InitialMonth / 1;
				tmpDay = tmpDay / 1;
				this.InitialDay = tmpDay;
			}
			else
			{
				var monthPos = format.indexOf('mm');
				this.InitialMonth = dateString.substr(monthPos,2)/1;
				var yearPos = format.indexOf('yyyy');
				this.InitialYear = dateString.substr(yearPos,4);
				var dayPos = format.indexOf('dd');
				tmpDay = dateString.substr(dayPos,2);
				this.InitialDay = tmpDay;
				var hourPos = format.indexOf('hh');
				if (hourPos >= 0)
				{
					tmpHour = dateString.substr(hourPos,2);
					this.InitialHours = tmpHour;
				}
				else
				{
					this.InitialHours = '00';
				}
				var minutePos = format.indexOf('ii');
				if (minutePos >= 0)
				{
					tmpMinute = dateString.substr(minutePos,2);
					this.InitialMinutes = tmpMinute;
				}
				else
				{
					this.InitialMinutes = '00';
				}
			}
		}
		this.ResetDisplayedMonth();
	}
	
	this.SetDateFromInput = function(input, format)
	{
		if (input && input.value && input.value.length > 0)
		{
			this.SetDateFromString(input.value, format)
		}
	}

	this.SetDisplayedData = function()
	{
		this.DisplayedYear = this.InitialYear;
		this.DisplayedMonth = this.InitialMonth;
		this.DisplayedDay = this.InitialDay;
		this.DisplayedHours = this.InitialHours;
		this.DisplayedMinutes = this.InitialMinutes;
	}

	this.SortItems = function(a,b)
	{
		return a/1-b/1;
	}
	
	this.IsLeapYear = function(year)
	{
		return (year %400 == 0 || (year %4 == 0 && year %100 != 0));
	}
	
	this.PutZero = function(val)
	{
		if (val && val.toString && val.toString().length == 1) val = '0' + val.toString();
		return val + '';
	}
	
	this.GetMonthName = function(numOfMonth)
	{
		return this.Months[numOfMonth-1];
	}
	
	this.PreviousYear = function()
	{
		this.DisplayedYear--;
	}
	
	this.NextYear = function()
	{
		this.DisplayedYear++;
	}
	
	this.PreviousMonth = function()
	{
		this.DisplayedMonth--;
		if (this.DisplayedMonth < 1)
		{
			this.DisplayedMonth = 12;
			this.DisplayedYear--;
		}
	}
	
	this.NextMonth = function()
	{
		this.DisplayedMonth++;
		if (this.DisplayedMonth > 12)
		{
			this.DisplayedMonth = 1;
			this.DisplayedYear++;
		}
	}

	this.GetPreviousYearAndMonthAsArray = function()
	{
		var month = this.DisplayedMonth-1;
		var year = this.DisplayedYear;
		if (month == 0)
		{
			month = 12;
			year -= 1;
		}
		return [year,month];
	}		
	
	this.GetNumberOfDaysInCurrentMonth = function()
	{
		return this.GetNumberOfDaysInAMonth(this.DisplayedYear, this.DisplayedMonth);
	}

	this.GetNumberOfDaysInAMonth = function(year, month)
	{
		var daysInMonthArray = [31,28,31,30,31,30,31,31,30,31,30,31];
		var daysInMonth = daysInMonthArray[month-1];
		if (daysInMonth == 28)
		{
			if (this.IsLeapYear(year)) daysInMonth = 29;
		}
		return daysInMonth/1;
	}
	
	this.GetSundayToSaturday = function()
	{
		var retArray = this.Days.concat();
		var lastDay = new Array(retArray[retArray.length-1]);
		retArray.pop();
		return lastDay.concat(retArray);
	}
	
	this.GetWeekNumber = function(year, month, day)
	{
		day = day/1;
		year = year/1;
		month = month/1;
		if (!this.WeekStartsOnMonday) return this.GetWeekNumberStartingWithSunday(year, month, day);
		var a = Math.floor((14 - (month)) / 12);
		var y = year + 4800 - a;
		var m = (month) + (12*a) - 3;
		var jd = day + Math.floor(((153*m) + 2) / 5) + (365*y) + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400) - 32045;
		var d4 = (jd + 31741 - (jd%7))%146097%36524%1461;
		var L = Math.floor(d4/1460);
		var d1 = ((d4-L)%365) + L;
		return Math.floor(d1/7) + 1;
	}

	this.GetWeekNumberStartingWithSunday = function(year, month, day)
	{
		month--;
		var now = Date.UTC(year, month, day + 1, 0, 0, 0);
		var firstDay = new Date();
		firstDay.setYear(year);
		firstDay.setMonth(0);
		firstDay.setDate(1);
		var then = Date.UTC(year, 0, 1, 0, 0, 0);
		var compensation = firstDay.getDay();
		if (compensation > 3) compensation -= 4;
		else compensation += 3;
		return Math.round((((now - then) / 86400000) + compensation) / 7);
	}	
	
	this.GetNumberOfFirstDayInYear = function(year)
	{
		var d = new Date();
		d.setFullYear(year);
		d.setDate(1);
		d.setMonth(0);
		return d.getDay();
	}	
	
	this.GetRemainingDaysInPreviousMonthAsArray = function()
	{
		var d = new Date();
		d.setFullYear(this.DisplayedYear);
		d.setDate(1);
		d.setMonth(this.DisplayedMonth-1);
		var dayStartOfMonth = d.getDay();
		if (this.WeekStartsOnMonday)
		{
			if (dayStartOfMonth == 0) dayStartOfMonth = 7;
			dayStartOfMonth--;
		}
		var previousMonthArray = this.GetPreviousYearAndMonthAsArray();
		var daysInPreviousMonth = this.GetNumberOfDaysInAMonth(previousMonthArray[0], previousMonthArray[1]);
		var returnArray = new Array();
		for (var i=0; i<dayStartOfMonth; i++)
		{
			returnArray[returnArray.length] = daysInPreviousMonth - dayStartOfMonth + i + 1;
		}
		return returnArray;
	}

	this.ResetDisplayedMonth = function()
	{
		if (!this.Element) return;
		this.SetDisplayedData();
		this.UpdateHeading();
		this.UpdateMonthView();
		this.UpdateTimeBar();
	}

	this.Render = function()
	{
		if (!this.Element)
		{
			this.CreateMainElements();
			this.CreateHeading();
			this.CreateNavigationBar();
			this.UpdateNavigationBar();
			this.UpdateHeading();
			this.CreateMonthView();
			this.UpdateMonthView();
			this.CreateTimeBar();
			this.UpdateTimeBar();
			this.AddEvents();
		}
		else
		{
			this.Element.style.display = 'block';
			this.UpdateHeading();
			this.UpdateMonthView();
		}
		this.UpdatePrimaryFrame();
	}

	this.Ensure = function()
	{
		if (!this.Element) this.Render();
	}
	
	this.GetElement = function(elm)
	{
		try
		{
			if (typeof(elm).toLowerCase() == 'string')
			{
				elm = document.getElementById(elm);
			}
		}
		catch(e)
		{}
		return elm;
	}
	
	this.Show = function()
	{
		this.Ensure();
		this.Element.style.display = 'block';
		this.Element.style.visibility = 'visible';
	}
	
	this.ShowBefore = function(elm)
	{
		elm = this.GetElement(elm);
		if (!elm) return;
		this.Ensure();
		elm.parentNode.insertBefore(this.Element, elm);
		this.Element.style.display = 'block';		
	}

	this.ShowAfter = function(elm)
	{
		elm = this.GetElement(elm);
		if (!elm) return;
		this.Ensure();
		var relativeNode = (elm.nextSibling && elm.nextSibling.parentNode == elm.parentNode) ? elm.nextSibling : null;
		elm.parentNode.insertBefore(this.Element, relativeNode);
		this.Element.style.display = 'block';		
	}
	
	this.ShowInside = function(elm)
	{
		elm = this.GetElement(elm);
		if (!elm) return;
		this.Ensure();
		elm.insertBefore(this.Element, null);
		this.Element.style.display = 'block';		
	}
	
	this.ShowRelativeTo = function(elm, halign, valign)
	{
		// halign: left / right
		// valign: top / bottom
		elm = this.GetElement(elm);
		if (!elm) return;
		if (!halign) halign = 'left';
		if (!valign) valign = 'bottom';
		this.Ensure();
		var pos = this.GetPosition(elm);
		var left = pos.X;
		this.Element.style.position = 'absolute';
		this.Element.style.zIndex = 10000;
		this.Element.style.visibility = 'hidden';
		this.Element.style.display = 'block';
		if (halign.toLowerCase() == 'right') left += elm.offsetWidth - this.Element.offsetWidth;
		var top = pos.Y;
		if (valign.toLowerCase() == 'bottom') top += elm.offsetHeight;
		else top -= this.Element.offsetHeight;
		this.Element.style.top = top + 'px';
		this.Element.style.left = left + 'px';
		this.Element.style.visibility = 'visible';
	}
	
	this.GetPosition = function(elm)
	{
        var curleft = curtop = 0;
        if (elm.offsetParent) 
        {
            do 
            {
	            curleft += elm.offsetLeft;
	            curtop += elm.offsetTop;
	        }
            while (elm = elm.offsetParent);
        }
        return {X:curleft,Y:curtop};   
	}
	
	this.Hide = function()
	{
		var cal = (this.calendar) ? this.calendar : this;
		if (!cal) return true;
		if (!cal.OnClose()) return false;
		cal.Element.style.display = 'none';
		cal.Element.style.visibility = 'hidden';
		return true;
	}
	
	this.Disable = function()
	{
	    if (!this.Element) return;
		var cls = this.Element.className;
		if (cls.indexOf('disabled') == -1) this.Element.className += ' disabled';
		cls = this.Content.className;
		if (cls.indexOf('disabled') == -1) this.Content.className += ' disabled';
		this.Disabled = true;
	}

	this.Enable = function()
	{
		var cls = this.Element.className;
		this.Element.className = cls.replace(' disabled', '');
		cls = this.Content.className;
		this.Content.className = cls.replace(' disabled', '');
		this.Disabled = false;
	}
	
	this.IsVisible = function()
	{
		if (!this.Element) return false;
		return this.Element.style.display == 'block';
	}

	this.SetDisplayedYear = function(year)
	{
		this.DisplayedYear = year;
		this.UpdateHeading();
		this.UpdateMonthView();
		this.FireEvent('MonthChanged');
	}

	this.SetDisplayedMonth = function(month)
	{
		this.DisplayedMonth = month;
		this.UpdateHeading();
		this.UpdateMonthView();
		this.FireEvent('MonthChanged');
	}

	this.SetDisplayedDay = function(day)
	{
		this.DisplayedDay = day;
		this.UpdateMonthView();
	}

	this.SetDisplayedHours = function(hours)
	{
		this.DisplayedHours = hours;
		this.UpdateTimeBar();
	}

	this.SetDisplayedMinutes = function(minutes)
	{
		this.DisplayedMinutes = minutes;
		this.UpdateTimeBar();
	}

	this.CreateMainElements = function()
	{
		this.Element = document.createElement('div');
		this.Element.className = 'Calendar';
		this.Content = document.createElement('div');
		this.Element.appendChild(this.Content);
		this.Content.className = 'CalendarContent';
		document.body.appendChild(this.Element);
		if (navigator.userAgent.indexOf('MSIE') > -1)
		{
			// insert a backdrop iframe to hide windowed elements in IE
			this.Frame = document.createElement('<iframe src="about:blank" frameborder="0">');
			this.Frame.className = 'CalendarFrame';
			this.Element.appendChild(this.Frame);
		}
	}

	this.CreateHeading = function()
	{
		this.Heading = document.createElement('div');
		this.Heading.className = 'CalendarHeading';
		this.Content.appendChild(this.Heading);
		this.Heading.style.position = 'relative';
		this.Close = document.createElement('div');
		this.Close.className = 'CalendarCloseButton';
		this.Close.calendar = this;
		this.Heading.appendChild(this.Close);
		if (!this.ShowCloseButton) this.Close.style.display = 'none';
		this.HeadingTxt = document.createElement('div');
		this.HeadingTxt.className = 'CalendarHeadingText';
		var table = document.createElement('table');
		table.setAttribute('cellpadding',0);
		table.setAttribute('cellspacing',2);
		table.setAttribute('border',0);
		table.style.margin = '0 auto';
		table.style.borderCollapse = 'collapse';
		var tbody = document.createElement('tbody');
		table.appendChild(tbody);
		this.HeadingTxt.appendChild(table);
		var row = tbody.insertRow(0);
		var cell = row.insertCell(-1);
		this.MonthNInHead = document.createElement('div');
		this.MonthNInHead.className = 'CalendarHeaderMonthAndYear';
		cell.appendChild(this.MonthNInHead);
		cell = row.insertCell(-1);
		var span = document.createElement('span');
		span.className = 'CalendarHeaderMonthAndYear';
		span.style.cursor = 'default';
		span.innerHTML = '-';
		cell.appendChild(span);
		cell = row.insertCell(-1);
		this.YearInHeading = document.createElement('div');
		this.YearInHeading.className = 'CalendarHeaderMonthAndYear';
		cell.appendChild(this.YearInHeading);
		this.Heading.appendChild(this.HeadingTxt);
	}

	this.CreateNavigationBar = function()
	{
		this.NavBar = document.createElement('div');
		this.NavBar.className = 'CalendarNavigationBar';
		this.NavBar.calendar = this;
		this.Content.appendChild(this.NavBar);
		this.BtnPreviousYear = document.createElement('div');
		this.BtnPreviousYear.className = 'CalendarBtnPreviousYear';
		this.BtnPreviousYear.innerHTML = '<span></span>';
		this.BtnPreviousYear.title = this.PreviousYearString;
		this.NavBar.appendChild(this.BtnPreviousYear);
		this.BtnNextYear = document.createElement('div');
		this.BtnNextYear.className = 'CalendarBtnNextYear';
		this.BtnNextYear.innerHTML = '<span></span>';
		this.BtnNextYear.title = this.NextYearString;
		this.NavBar.appendChild(this.BtnNextYear);
		this.BtnPrvMonth = document.createElement('div');
		this.BtnPrvMonth.className = 'CalendarBtnPreviousMonth';
		this.BtnPrvMonth.innerHTML = '<span></span>';
		this.BtnPrvMonth.title = this.PreviousMonthString;
		this.NavBar.appendChild(this.BtnPrvMonth);
		this.BtnNextMonth = document.createElement('div');
		this.BtnNextMonth.className = 'CalendarBtnNextMonth';
		this.BtnNextMonth.innerHTML = '<span></span>';
		this.BtnNextMonth.title = this.NextMonthString;
		this.NavBar.appendChild(this.BtnNextMonth);
		this.TodayInNavBar = document.createElement('div');
		this.TodayInNavBar.className = 'CalendarNavigationBarToday';
		this.TodayInNavBar.title = this.TodayString;
		this.NavBar.appendChild(this.TodayInNavBar);
		if (!this.ShowNavigationBar) this.NavBar.style.display = 'none';
		if (!this.ShowTodayInNavigationBar) this.TodayInNavBar.style.display = 'none';
	}

	this.UpdateNavigationBar = function()
	{
		this.TodayInNavBar.innerHTML = '';
		var span = document.createElement('span');
		span.innerHTML = this.TodayString;
		span.onclick = this.ShowMonthOfToday;
		this.TodayInNavBar.appendChild(span);
	}

	this.CreateMonthView = function()
	{
		this.MonthView = document.createElement('div');
		this.MonthView.className = 'CalendarMonthView';
		this.Content.appendChild(this.MonthView);
	}

	this.UpdateMonthView = function()
	{
	    var days, row, cell;
		this.MonthView.innerHTML = '';
		var table = document.createElement('table');
		table.setAttribute('cellpadding',0);
		table.setAttribute('cellspacing',2);
		table.setAttribute('border',0);
		table.width = '100%';
		var tbody = document.createElement('tbody');
		table.appendChild(tbody);
		this.MonthView.appendChild(table);
		row = tbody.insertRow(-1);
		row.className = 'CalendarMonthViewHeaderRow';
		cell = row.insertCell(-1);
		cell.className = 'CalendarMonthViewFirstColumn';
		cell.innerHTML = this.WeekString;
		if (this.WeekStartsOnMonday)
		{
			days = this.Days;
		}
		else
		{
			days = this.GetSundayToSaturday();
		}
		for (var i=0; i<days.length; i++)
		{
			cell = row.insertCell(-1);
			cell.innerHTML = days[i];
			cell.className = 'CalendarMonthViewHeaderCell';
			if (this.WeekStartsOnMonday && i == 6)
			{
				cell.className = 'CalendarMonthViewHeaderSunday';
			}
			else if (!this.WeekStartsOnMonday && i == 0)
			{
				cell.className = 'CalendarMonthViewHeaderSunday';
			}
		}
		row = tbody.insertRow(-1);
		cell = row.insertCell(-1);
		cell.className = 'CalendarMonthViewFirstColumn';
		var week = this.GetWeekNumber(this.DisplayedYear, this.DisplayedMonth, 1);
		cell.innerHTML = week > 0 ? week : 53;
		var daysRemainingInPreviousMonth = this.GetRemainingDaysInPreviousMonthAsArray();
		for (i = 0; i<daysRemainingInPreviousMonth.length; i++)
		{
			cell = row.insertCell(-1);
			cell.innerHTML = daysRemainingInPreviousMonth[i];
			cell.className = 'CalendarMonthViewDaysInOtherMonths';
			cell.calendar = this;
			cell.onmousedown = this.DayInPreviousMonthInCalendar;
		}
		var daysInCurrentMonth = this.GetNumberOfDaysInCurrentMonth();
		var cellCounter = daysRemainingInPreviousMonth.length + 1;
		for (i = 1; i<=daysInCurrentMonth; i++)
		{
			cell = row.insertCell(-1);
			cell.innerHTML = i;
			cell.className = 'CalendarMonthViewDaysInThisMonth';
			if (cellCounter%7 == 0 && this.WeekStartsOnMonday)
			{
				cell.className = 'CalendarMonthViewSundayInThisMonth';
			}
			else if (cellCounter%7 == 1 && !this.WeekStartsOnMonday)
			{
				cell.className = 'CalendarMonthViewSundayInThisMonth';
			}
			if (i == this.InitialDay && this.DisplayedYear == this.InitialYear && this.DisplayedMonth == this.InitialMonth)
			{
				cell.className = 'CalendarMonthViewInitialDate';
			}
			if (!this.IsValidDate({year:this.DisplayedYear,month:this.DisplayedMonth,day:i}))
			{
				cell.className = 'CalendarMonthViewInvalidDate';
			}
			else
			{
				cell.calendar = this;
				cell.onmousedown = this.DayInCalendar;
				cell.onmouseover = this.MouseOverCalendarDay;
				cell.onmouseout = this.MouseOutCalendarDay;
			}
			if (i == this.Today.getDate() && this.DisplayedYear == this.Today.getFullYear() && this.DisplayedMonth == (this.Today.getMonth() + 1))
			{
				cell.className += ' CalendarMonthViewCurrentDate';
				cell.title = this.TodayString;
			}
			if (cellCounter%7 == 0 && i < daysInCurrentMonth)
			{
				row = tbody.insertRow(-1);
				cell = row.insertCell(-1)
				cell.className = 'CalendarMonthViewFirstColumn';
				week++;
				cell.innerHTML = week;
			}
			cellCounter ++;
		}
		if ((cellCounter-1)%7 > 0)
		{
			var dayCounter = 1;
			for (i = (cellCounter-1)%7; i<7; i++)
			{
				cell = row.insertCell(-1);
				cell.innerHTML = dayCounter;
				cell.className = 'CalendarMonthViewDaysInOtherMonths';
				cell.calendar = this;
				cell.onmousedown = this.DayInNextMonthInCalendar;
				dayCounter++;
			}
		}
	}

	this.CreateTimeBar = function()
	{
		this.TimeBar = document.createElement('div');
		this.TimeBar.className = 'CalendarTimeBar';
		this.Content.appendChild(this.TimeBar);
		var table = document.createElement('table');
		table.setAttribute('cellpadding',0);
		table.setAttribute('cellspacing',2);
		table.setAttribute('border',0);
		table.style.margin = '0 auto';
		this.TimeBar.appendChild(table);
		var row = table.insertRow(0);
		row.calendar = this;
		this.TimeStringInTimeBar = row.insertCell(-1);
		this.TimeStringInTimeBar.className = 'CalendarTimeBarTimeString';
		this.HrInTimeBar = row.insertCell(-1);
		this.HrInTimeBar.className = 'CalendarTimeBarHour';
		var delim = row.insertCell(-1);
		delim.innerHTML = ':';
		this.MinInTimeBar = row.insertCell(-1);
		this.MinInTimeBar.className = 'CalendarTimeBarMinute';
		if (!this.ShowTimeBar) this.TimeBar.style.display = 'none';
	}

	this.UpdateTimeBar = function()
	{
		this.HrInTimeBar.innerHTML = this.PutZero(this.DisplayedHours);
		this.MinInTimeBar.innerHTML = this.PutZero(this.DisplayedMinutes);
		this.TimeStringInTimeBar.innerHTML = this.TimeString;
	}

	this.UpdateHeading = function()
	{
		this.MonthNInHead.innerHTML = this.GetMonthName(this.DisplayedMonth);
		this.YearInHeading.innerHTML = this.DisplayedYear;
	}

	this.DayInCalendar = function(e)
	{
		if (this.calendar.Disabled) return;
		if (!e && window.event) e = window.event;
		this.calendar.SetDisplayedDay(this.innerHTML);
		this.calendar.FireEvent('DaySelected');
	}

	this.DayInPreviousMonthInCalendar = function(e)
	{
		if (this.calendar.Disabled) return;
		if (!e && window.event) e = window.event;
		this.calendar.PreviousMonth();
		this.calendar.UpdateHeading();
		this.calendar.SetDisplayedDay(this.innerHTML);
		this.calendar.FireEvent('DaySelected');
	}
	
	this.DayInNextMonthInCalendar = function(e)
	{
		if (this.calendar.Disabled) return;
		if (!e && window.event) e = window.event;
		this.calendar.NextMonth();
		this.calendar.UpdateHeading();
		this.calendar.SetDisplayedDay(this.innerHTML);
		this.calendar.FireEvent('DaySelected');
	}
	
	this.FireEvent = function(evt)
	{
		var eventargs;
		var func;
		switch(evt)
		{
			case 'DaySelected':
				if (this.OnDaySelected) func = this.OnDaySelected;
				break;
			case 'MonthChanged':
				if (this.OnMonthChanged) func = this.OnMonthChanged;
				break;
			case 'TimeChanged':
				if (this.OnTimeChanged) func = this.OnTimeChanged;
				break;
			case 'CalendarClosed':
				if (this.OnClose) func = this.OnClose;
				break;
		}
		if (func)
		{
			eventargs = new Object();
			eventargs.Year = this.DisplayedYear;
			eventargs.Month = this.PutZero(this.DisplayedMonth);
			eventargs.MonthName = this.GetMonthName(this.DisplayedMonth);
			eventargs.Day = this.PutZero(this.DisplayedDay);
			eventargs.Hours = this.PutZero(this.DisplayedHours);
			eventargs.Minutes = this.PutZero(this.DisplayedMinutes);
			eventargs.Calendar = this;
			eventargs.SetAsInitialDateTime = true;

			// fire
			func(eventargs);
			
			if ((evt == 'DaySelected' || evt == 'TimeChanged') && eventargs.SetAsInitialDateTime)
			{
				this.InitialDay = this.DisplayedDay;
				this.InitialMonth = this.DisplayedMonth;
				this.InitialYear = this.DisplayedYear;
				this.InitialHours = this.DisplayedHours;
				this.InitialMinutes = this.DisplayedMinutes;
				this.ResetDisplayedMonth();
			}
		}
	}

	this.ShowMonthOfToday = function()
	{
		var cal = this.parentNode.parentNode.calendar;
		if (cal.Disabled) return;
		var d = new Date();
		var month = d.getMonth() + 1;
		var year = d.getFullYear();
		cal.SetDisplayedYear(year);
		cal.SetDisplayedMonth(month);
	}

	this.MoveOneYearBack = function(e, cal)
	{
		if (!cal) cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		cal.PreviousYear();
		cal.UpdateHeading();
		cal.UpdateMonthView();
		cal.FireEvent('MonthChanged');
		cal.NavigationBarTimerId = window.setTimeout(cal.Id + '.MoveOneYearBack(null, ' + cal.Id + ')', 200);
		if (!e && window.event) e = window.event;
		if (e)
		{
			e.cancelBubble = true;
			e.returnValue = false;
			if (e.stopPropagation) e.stopPropagation();
			if (e.preventDefault) e.preventDefault();
		}
		return false;
	}

	this.MoveOneYearForward = function(e, cal)
	{
		if (!cal) cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		cal.NextYear();
		cal.UpdateHeading();
		cal.UpdateMonthView();
		cal.FireEvent('MonthChanged');
		cal.NavigationBarTimerId = window.setTimeout(cal.Id + '.MoveOneYearForward(null, ' + cal.Id + ')', 200);
	}

	this.MoveOneMonthBack = function(e, cal)
	{
		if (!cal) cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		cal.PreviousMonth();
		cal.UpdateHeading();
		cal.UpdateMonthView();
		cal.FireEvent('MonthChanged');
		cal.NavigationBarTimerId = window.setTimeout(cal.Id + '.MoveOneMonthBack(null, ' + cal.Id + ')', 200);
	}

	this.MoveOneMonthForward = function(e, cal)
	{
		if (!cal) cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		cal.NextMonth();
		cal.UpdateHeading();
		cal.UpdateMonthView();
		cal.FireEvent('MonthChanged');
		cal.NavigationBarTimerId = window.setTimeout(cal.Id + '.MoveOneMonthForward(null, ' + cal.Id + ')', 200);
	}
	
	this.StopMoving = function(e, cal)
	{
		if (!cal) cal = this.parentNode.calendar;
		if (cal.NavigationBarTimerId)
		{
			window.clearTimeout(cal.NavigationBarTimerId);
			cal.NavigationBarTimerId = null;
		}
	}
	
	this.HourDragStart = function(e)
	{
		if (!e) e = window.event;
		this.dragging = true;
		this.starthours = parseInt(this.innerHTML);
		this.y = e.clientY;
		var cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		document.calendardragobject = this;
		cal.AddEvent(document.body, 'selectstart', cal.CancelSelection);
		cal.AddEvent(document.body, 'mousemove', cal.HourDrag);
		cal.AddEvent(document.body, 'mouseup', cal.HourDragEnd);
		if (this.setCapture) this.setCapture();
	}
	
	this.HourDrag = function(e)
	{
		if (!e) e = window.event;
		var elm = document.calendardragobject;
		if (!elm) return;
		if (elm.dragging)
		{
			var offset = Math.round((e.clientY - elm.y) / 3);
			var newhours = elm.starthours + offset * -1;
			if (newhours < 0) newhours = 0;
			if (newhours > 23) newhours = 23;
			if (newhours <= 9) newhours = '0' + newhours;
			elm.innerHTML = newhours;
		}
	}
	
	this.HourDragEnd = function(e)
	{
		var elm = document.calendardragobject;
		var cal = elm.parentNode.calendar;
		elm.dragging = false;
		elm.starthours = null;
		elm.y = null;
		cal.SetDisplayedHours(elm.innerHTML);
		cal.FireEvent('TimeChanged');
		elm.onmouseout();
		document.calendardragobject = null;
		cal.RemoveEvent(document.body, 'selectstart', cal.CancelSelection);
		cal.RemoveEvent(document.body, 'mousemove', cal.HourDrag);
		cal.RemoveEvent(document.body, 'mouseup', cal.HourDragEnd);
		if (document.releaseCapture) document.releaseCapture();
	}

	this.MinuteDragStart = function(e)
	{
		if (!e) e = window.event;
		this.dragging = true;
		this.startminutes = parseInt(this.innerHTML);
		this.y = e.clientY;
		var cal = this.parentNode.calendar;
		if (cal.Disabled) return;
		document.calendardragobject = this;
		cal.AddEvent(document.body, 'selectstart', cal.CancelSelection);
		cal.AddEvent(document.body, 'mousemove', cal.MinuteDrag);
		cal.AddEvent(document.body, 'mouseup', cal.MinuteDragEnd);
		if (this.setCapture) this.setCapture();
	}
	
	this.MinuteDrag = function(e)
	{
		if (!e) e = window.event;
		var elm = document.calendardragobject;
		if (!elm) return;
		if (elm.dragging)
		{
			var offset = e.clientY - elm.y;
			var newminutes = elm.startminutes + offset * -1;
			if (newminutes < 0) newminutes = 0;
			if (newminutes > 59) newminutes = 59;
			if (newminutes <= 9) newminutes = '0' + newminutes;
			elm.innerHTML = newminutes;
		}
	}
	this.MinuteDragEnd = function(e)
	{
		var elm = document.calendardragobject;
		var cal = elm.parentNode.calendar;
		elm.dragging = false;
		elm.startminutes = null;
		elm.y = null;
		cal.SetDisplayedMinutes(elm.innerHTML);
		cal.FireEvent('TimeChanged');
		elm.onmouseout();
		document.calendardragobject = null;
		cal.RemoveEvent(document.body, 'selectstart', cal.CancelSelection);
		cal.RemoveEvent(document.body, 'mousemove', cal.MinuteDrag);
		cal.RemoveEvent(document.body, 'mouseup', cal.MinuteDragEnd);
		if (document.releaseCapture) document.releaseCapture();
	}
	
	this.CancelSelection = function()
	{
		return false;
	}
		
	this.AddEvents = function()
	{
		this.Close.onmouseover = this.MouseOverCalendarButton;
		this.Close.onmouseout = this.MouseOutCalendarButton;
		this.Close.onclick = this.Hide;
		this.BtnPreviousYear.onmouseover = this.MouseOverCalendarButton;
		this.BtnPreviousYear.onmouseout = this.MouseOutCalendarButton;
		this.BtnPreviousYear.onmousedown = this.MoveOneYearBack;
		this.BtnPreviousYear.onmouseup = this.StopMoving;
		this.BtnNextYear.onmouseover = this.MouseOverCalendarButton;
		this.BtnNextYear.onmouseout = this.MouseOutCalendarButton;
		this.BtnNextYear.onmousedown = this.MoveOneYearForward;
		this.BtnNextYear.onmouseup = this.StopMoving;
		this.BtnPrvMonth.onmouseover = this.MouseOverCalendarButton;
		this.BtnPrvMonth.onmouseout = this.MouseOutCalendarButton;
		this.BtnPrvMonth.onmousedown = this.MoveOneMonthBack;
		this.BtnPrvMonth.onmouseup = this.StopMoving;
		this.BtnNextMonth.onmouseover = this.MouseOverCalendarButton;
		this.BtnNextMonth.onmouseout = this.MouseOutCalendarButton;
		this.BtnNextMonth.onmousedown = this.MoveOneMonthForward;
		this.BtnNextMonth.onmouseup = this.StopMoving;
		this.HrInTimeBar.onmouseover = this.MouseOverHourAndMinute;
		this.HrInTimeBar.onmouseout = this.MouseOutHourAndMinute;
		this.HrInTimeBar.onmousedown = this.HourDragStart;
		this.MinInTimeBar.onmouseover = this.MouseOverHourAndMinute;
		this.MinInTimeBar.onmouseout = this.MouseOutHourAndMinute;
		this.MinInTimeBar.onmousedown = this.MinuteDragStart;
		this.AddEvent(this.Element, 'selectstart', this.CancelSelection);
	}
	
	this.AddEvent = function(elm, evt, handler)
	{
		if (elm.addEventListener)
		{
			elm.addEventListener(evt, handler, true);
		}
		else if (elm.attachEvent)
		{
			elm.attachEvent('on' + evt, handler);
		}
		else
		{
			elm['on' + evt] = handler;
		}
	}

	this.RemoveEvent = function(elm, evt, handler)
	{
		if (elm.removeEventListener)
		{
			elm.removeEventListener(evt, handler, true);
		}
		else if (elm.detachEvent)
		{
			elm.detachEvent('on' + evt, handler);
		}
		else
		{
			elm['on' + evt] = null;
		}
	}
	
	this.UpdatePrimaryFrame = function()
	{
		if (!this.Frame)return;
		this.Frame.style.width = this.Element.clientWidth + 'px';
		this.Frame.style.height = this.Element.clientHeight + 'px';
	}

	this.MouseOverCalendarDay = function()
	{
		if (this.calendar.Disabled) return;
		this.className = this.className + ' CalendarDayOver';
	}

	this.MouseOutCalendarDay = function()
	{
		this.className = this.className.replace(' CalendarDayOver','');
	}

	this.MouseOverCalendarButton = function()
	{
		if (this.parentNode && this.parentNode.calendar && this.parentNode.calendar.Disabled) return;
		this.className = this.className + ' CalendarButtonOver';
	}

	this.MouseOutCalendarButton = function()
	{
		this.className = this.className.replace(' CalendarButtonOver','');
		if (this.onmouseup) this.onmouseup();
	}

	this.MouseOverHourAndMinute = function()
	{
		if (this.parentNode.calendar.Disabled) return;
		this.className = this.className + ' CalendarTimeBarHourAndMinuteOver';
	}

	this.MouseOutHourAndMinute = function()
	{
		this.className = this.className.replace(' CalendarTimeBarHourAndMinuteOver','');
	}
	
	// initialize
	this.ApplyCulture(culture);
	this.ApplyDateTime(year, month, day, hours, minutes);
			
}

Order.ValidateDate = function(fld)
{
    var d = fld.value;
    if (false && d != '')
    {
        var ok = /\d{2}\-\d{2}\-20\d{2}/gi.test(d);
        if (!ok) 
        {
            fld.select();
            fld.focus();
            alert('Indtast venligst leveringsdato i formatet dd-mm-åååå, f.eks. 10-07-2009');
        }
    }
}

Order.CalendarDaySelected = function(date)
{
    var fld = Order.Calendar.ActiveField;
    fld.value = date.Day + '-' + date.Month + '-' + date.Year;
    Order.Calendar.Hide();
}

Order.ShowCalendar = function(icon, fld)
{
    this.Calendar.SetDateFromInput(fld, 'dd-mm-yyyy');
    this.Calendar.ShowRelativeTo(icon, 'left', 'bottom');
    this.Calendar.ActiveField = fld;
}

Order.Calendar = new Calendar('Order.Calendar', 'da');
Order.Calendar.ShowTodayInNavigationBar = false;
Order.Calendar.OnDaySelected = Order.CalendarDaySelected;


Order.LightBox = {};

Order.LightBox.Id = 'Order.LightBox';
Order.LightBox.Initialized = false;
Order.LightBox.Visible = false;

Order.LightBox.Show = function(html)
{
    this.EnsureControls();
    var p = this.Panel;
    p.innerHTML = html;
    p.style.visibility = 'visible';
    var ml = this.ModalLayer;
    ml.style.display = '';
    var w = this.Wrapper;
    w.style.display = '';
    this.Visible = true;
    this.Position();
}

Order.LightBox.Position = function(fromScrollEvent)
{
    if (!this.Visible) return;
    this.EnsureControls();
    var ml = this.ModalLayer;
    // reset modal layer before measuring document height
    ml.style.height = 'auto';
    ml.style.display = '';
    var html = document.body.parentNode;
    html.style.height = '100%';
    var w = this.Wrapper;

    // trinol (company id 1) is in quirks mode - therefore measure body instead of html element
    var company = document.getElementById('company');
    var elm = (company && company.value == '1') ? document.body : html;

    if (w.offsetHeight > elm.offsetHeight && fromScrollEvent) return;
    var t = (((elm.offsetHeight - w.offsetHeight) / 2) + elm.scrollTop);
    var l = (((elm.offsetWidth - w.offsetWidth) / 2) + elm.scrollLeft);
    if (t < 0) t = 0;
    if (l < 0) l = 0;
    w.style.top = t + 'px';
    w.style.left = l + 'px';
    ml.style.height = elm.scrollHeight + 'px';
    ml.style.display = 'block';
}

Order.LightBox.Hide = function()
{
    this.EnsureControls();
    this.ModalLayer.style.display = 'none';
    this.Wrapper.style.display = 'none';
    this.Panel.style.visibility = 'hidden';
    this.Visible = false;
}

Order.LightBox.EnsureControls = function()
{
    if (!this.Initialized)
    {
        var ml = this.ModalLayer = document.createElement('div');
        var html = document.body.parentNode;
        document.body.appendChild(ml);
        ml.id = 'OrderModalLayer';
        ml.style.cssText = 'display:none; width:100%; min-height:20px; position:absolute; z-index:10000; left:0px; top:0px; background:#000; opacity:0.75; filter:alpha(opacity=75); height:' + html.scrollHeight + 'px;';
        var w = this.Wrapper = document.createElement('div');
        document.body.appendChild(w);
        w.id = 'OrderWrapper';
        w.style.cssText = 'display:none; background:#fff; width:640px; height:480px; position:absolute; z-index:10001;';
        var p = this.Panel = document.createElement('div');
        w.appendChild(p);
        p.id = 'OrderPanel';
        p.style.cssText = 'background:#fff; clear:both; visibility:hidden; width:100%; height:100%; overflow:auto';
        var that = this;
        this.AddEvent(window, 'resize', function() {that.Position.apply(that)});
        this.AddEvent(window, 'scroll', function() {that.Position.apply(that, [true])});
        this.Initialized = true;
    }
}

Order.LightBox.AddEvent = function(elm, evt, handler)
{
    if (elm.addEventListener) elm.addEventListener(evt, handler, false);
    else if (elm.attachEvent) elm.attachEvent('on' + evt, handler);
}

Order.LightBox.RemoveEvent = function(elm, evt, handler)
{
    if (elm.removeEventListener) elm.removeEventListener(evt, handler, false);
    else if (elm.detachEvent) elm.detachEvent('on' + evt, handler);
}