

function onLoad(context) {
    if (context == 1) {
        document.getElementById("id_town_search").style.visibility = "visible";
        var textbox = document.getElementById("id_town_textbox");
        var provider = new LocationProvider();
        var formatter = new LocationTextFormatter();
        var callback = function(item) {
            textbox.disabled = true;
            textbox.blur();
            setTimeout(function() { document.location.href = "http://www.rezerviraihotel.com/bg/" + item.country_name_url + "/" + item.town_name_url + ".html"; }, 0);
        }
        var locationAutoSuggest = new AutoSuggest(textbox, provider, formatter, callback);
    } else if (context == 3) {
        if (GBrowserIsCompatible()) {
            __php_showTownMap();
        }
    } else if (context == 4) {
        if (GBrowserIsCompatible()) {
            __php_showAccommodationMap();
        }
    }

    if (context == 2 || context == 3 || context == 4) {
        datePickerArrival = new DatePicker("id_datepicker_arrival");
        datePickerArrival.setDayComboBox(document.getElementById("id_arrival_day"));
        datePickerArrival.setMonthYearComboBox(document.getElementById("id_arrival_month_year"));
        datePickerArrival.setMinDateFromMinControlValues();
        datePickerArrival.setMaxDateFromMaxControlValues();

        datePickerDeparture = new DatePicker("id_datepicker_departure");
        datePickerDeparture.setDayComboBox(document.getElementById("id_departure_day"));
        datePickerDeparture.setMonthYearComboBox(document.getElementById("id_departure_month_year"));
        datePickerDeparture.setMinDateFromMinControlValues();
        datePickerDeparture.setMaxDateFromMaxControlValues();

        datePickerArrival.nextDayDatePicker = datePickerDeparture;
    }
}

function onUnload(context) {
    if (context == 3 || context == 4) {
        if (GBrowserIsCompatible()) {
            GUnload();
        }
    }
}




//
// townMap
//

var townMap = {
    preferences : {
        containerId         : "map",
        iconImage           : "http://www.rezerviraihotel.com/images/general/marker16px.png",
        iconWidth           : 16,
        iconHeight          : 16,
        iconAnchorX         : 8,
        iconAnchorY         : 8,
        infoWindowAnchorX   : 8,
        infoWindowAnchorY   : 8,
        zoomDefault         : 13,
        zoomLocate          : 14
    },

    initialize : function() {
        this.markerIcon = new GIcon();
        this.markerIcon.image = this.preferences.iconImage;
        this.markerIcon.iconSize = new GSize(this.preferences.iconWidth, this.preferences.iconHeight);
        this.markerIcon.iconAnchor = new GPoint(this.preferences.iconAnchorX, this.preferences.iconAnchorY);
        this.markerIcon.infoWindowAnchor = new GPoint(this.preferences.infoWindowAnchorX, this.preferences.iconAnchorY);
        this.markerOptions = { icon : this.markerIcon };
        this.div = document.getElementById(this.preferences.containerId);
        this.zoomDefault = this.preferences.zoomDefault;
        this.zoomLocate = this.preferences.zoomLocate;
        this.items = [];
        this.latSum = 0;
        this.lngSum = 0;
        this.length = 0;
        this.map = undefined;
    },

    addMarker : function(id, lat, lng) {
        if (isNaN(id = parseInt(id.substring(1), 10))) {
            return false;
            }
        this.latSum += lat;
        this.lngSum += lng;
        this.length++;
        this.items[id] = { lat:lat, lng:lng };
            return true;
    },

    showMap : function() {
        if (typeof this.div != "object" ||
            this.map ||
            this.items.length == 0) {
            throw new Error("showMap() error");
        }
        this.map = new GMap2(this.div);
        this.map.addControl(new GSmallMapControl());
        this.map.addControl(new GMapTypeControl());
        this.map.addControl(new GScaleControl());
        this.map.addControl(new GOverviewMapControl());
        this.map.setCenter(new GLatLng(this.latSum / this.length, this.lngSum / this.length), this.zoomDefault, G_NORMAL_MAP);
        for (var id in this.items) {
            this.map.addOverlay(this.createMarker(id, this.map, this.items[id].lat, this.items[id].lng));
        }
    },

    createMarker : function(id, map, lat, lng) {
        var latlng = new GLatLng(lat, lng);
        var marker = new GMarker(latlng, this.markerOptions);
        var html = this.getInfoWindowHTML(id);
        GEvent.addListener(marker, "click", function() { map.openInfoWindowHtml(latlng, html) });
        return marker;
    },

    locateOnMap : function(id) {
        if (!this.map ||
            this.items.length == 0 ||
            !this.items[id]) {
            throw new Error("locateOnMap() error");
        }
        if (this.map.getZoom() < this.zoomLocate) {
            this.map.setZoom(this.zoomLocate);
        }
        this.map.openInfoWindowHtml(new GLatLng(this.items[id].lat, this.items[id].lng), this.getInfoWindowHTML(id));
    },

    getInfoWindowHTML : function(id) {
        return "<div style=\"width:480px\">" + document.getElementById("h" + id).innerHTML + "</div>";
    }
}



//
// accommodationMap
//

var accommodationMap = {
    preferences : {
        containerId         : "map",
        iconImage           : "http://www.rezerviraihotel.com/images/general/marker20px.png",
        iconWidth           : 20,
        iconHeight          : 20,
        iconAnchorX         : 10,
        iconAnchorY         : 10,
        infoWindowAnchorX   : 10,
        infoWindowAnchorY   : 10,
        zoomDefault         : 14
    },

    initialize : function() {
        this.markerIcon = new GIcon();
        this.markerIcon.image = this.preferences.iconImage;
        this.markerIcon.iconSize = new GSize(this.preferences.iconWidth, this.preferences.iconHeight);
        this.markerIcon.iconAnchor = new GPoint(this.preferences.iconAnchorX, this.preferences.iconAnchorY);
        this.markerIcon.infoWindowAnchor = new GPoint(this.preferences.infoWindowAnchorX, this.preferences.iconAnchorY);
        this.markerOptions = { icon : this.markerIcon };
        this.div = document.getElementById(this.preferences.containerId);
        this.zoomDefault = this.preferences.zoomDefault;
        this.map = undefined;
    },

    showMap : function(latitude, longitude) {
        if (typeof this.div != "object" || this.map) {
            throw new Error("showMap() error");
        }
        var ll = new GLatLng(latitude, longitude);
        this.map = new GMap2(this.div);
        this.map.addControl(new GSmallMapControl());
        this.map.addControl(new GMapTypeControl());
        this.map.addControl(new GScaleControl());
        this.map.addControl(new GOverviewMapControl());
        this.map.setCenter(ll, this.zoomDefault, G_HYBRID_MAP);
        this.map.addOverlay(new GMarker(ll, this.markerOptions));
    }
}




//
// AutoSuggest
//

function AutoSuggest(textbox, provider, formatter, callback) {
    this.textbox = textbox;
    this.provider = provider;
    this.formatter = formatter;
    this.callback = callback;
    this.text = this.textbox.value;
    this.dropDown = null;
    this.timeoutId = null;
    this.items = null;
    this.selectedNode = null;
    this.selectedIndex = 0;
    this.delay = 250;
    this.init();
}

AutoSuggest.prototype.init = function() {
    Utilities.addEvent(this.textbox, "keydown", Utilities.createEventHandlerMethod(this, "onKeyDown"));
    Utilities.addEvent(this.textbox, "keyup", Utilities.createEventHandlerMethod(this, "onKeyUp"));
    Utilities.addEvent(this.textbox, "blur", Utilities.createEventHandlerMethod(this, "hideDropDown"));
    this.createDropDown();
}

AutoSuggest.prototype.onKeyDown = function(event) {
    event = Utilities.getEvent(event);

    switch (event.keyCode) {
        case 38: //up arrow
            this.selectSuggestionOffset(-1);
            this.updateTextbox(this.selectedNode);
            break;
        case 40: //down arrow
            this.selectSuggestionOffset(1);
            this.updateTextbox(this.selectedNode);
            break;
        case 27: //esc
            this.hideDropDown();
            this.textbox.value = "";
            break;
        case 13: //enter
            var exec = (this.dropDown.style.visibility == "visible");
            this.updateTextbox(this.selectedNode);
            this.hideDropDown();
            event.returnValue = false;

            if (event.preventDefault) {
                event.preventDefault();
            }

            if (exec) {
                this.executeCallback();
            }
            break;
    }
}

AutoSuggest.prototype.onKeyUp = function(event) {
    var keyCode = Utilities.getEvent(event).keyCode;
    var _this = this;
    this.text = this.textbox.value;

    if (this.timeoutId) {
        clearTimeout(this.timeoutId);
    }

    if (keyCode == 8 || //backspace
        keyCode == 46 || //del
        keyCode == 32 || //space
        (keyCode >= 48 && keyCode <= 111) ||
        keyCode > 123) {
        this.timeoutId = setTimeout(function() { _this.provider.doSuggestions(_this) }, this.delay);
    }
}

AutoSuggest.prototype.selectSuggestion = function(div) {
    var divs = this.dropDown.childNodes;
    for (var i = 0; i < divs.length; i++) {
        if (divs[i] == div) {
            divs[i].className = "suggestion-selected";
            this.selectedNode = divs[i];
            this.selectedIndex = i;
        } else {
            divs[i].className = "suggestion-normal";
        }
    }
}

AutoSuggest.prototype.selectSuggestionOffset = function(offset) {
    var divs = this.dropDown.childNodes;
    if (this.selectedNode) {
        for (var i = 0; i < divs.length; i++) {
            if (divs[i] == this.selectedNode) {
                var index = Math.max(0, Math.min(divs.length - 1, i + offset));
                divs[i].className = "suggestion-normal";
                divs[index].className = "suggestion-selected";
                this.selectedNode = divs[index];
                this.selectedIndex = index;
                break;
            }
        }
    }
}

AutoSuggest.prototype.updateTextbox = function(div) {
    this.textbox.value = div.firstChild.nodeValue;
}

AutoSuggest.prototype.executeCallback = function() {
    if (this.callback) {
        this.callback(this.items[this.selectedIndex]);
    }
}

AutoSuggest.prototype.createDropDown = function() {
    if (this.dropDown) {
        return;
    }

    this.dropDown = document.createElement("div");
    this.dropDown.className = "dropdown";
    document.body.appendChild(this.dropDown);

    var pos = Utilities.getElementPosition(this.textbox);
    this.dropDown.style.left = pos[0] + "px";
    this.dropDown.style.top = (pos[1] + this.textbox.offsetHeight - 1) + "px";
}

AutoSuggest.prototype.showDropDown = function(items) {
    if (!items || items.length == 0) {
        this.hideDropDown();
        return;
    }

    var div = null;
    var _this = this;

    var onMouseOver = function(event) {
        event = event || window.event;
        _this.selectSuggestion(event.target || event.srcElement);
    }

    var onMouseDown = function(event) {
        event = event || window.event;
        div = event.target || event.srcElement;
        _this.selectSuggestion(div);
        _this.updateTextbox(div);
        _this.hideDropDown();
        _this.executeCallback();
    }

    this.dropDown.innerHTML = "";
    this.items = items;

    for (var i = 0; i < items.length; i++) {
        div = document.createElement("div");
        div.className = "suggestion-normal";
        div.appendChild(document.createTextNode(this.formatter.format(items[i])));
        this.dropDown.appendChild(div);

        div.onmouseover = onMouseOver;
        div.onmousedown = onMouseDown;
    }

    this.selectSuggestion(this.dropDown.firstChild);
    this.dropDown.style.height = div.offsetHeight * items.length;
    this.dropDown.style.visibility = "visible";
    this.dropDown.style.zIndex = 100;
}

AutoSuggest.prototype.hideDropDown = function() {
    this.dropDown.style.visibility = "hidden";
    this.dropDown.style.zIndex = -100;
    this.selectedNode = null;
}




//
// LocationProvider
//

LocationProvider = function() {
    this.request = Ajax.createRequest();
    this.url = "http://www.rezerviraihotel.com/suggest.php";
    this.minLength = 2;
}

LocationProvider.prototype.doSuggestions = function(control) {
    if (this.request.readyState != 0) {
        this.request.abort();
    }

    if (control && control.text.length < this.minLength) {
        control.hideDropDown();
        return;
    }

    var _this = this;
    var url = this.url + "?s=" + encodeURIComponent(control.text);

    this.request.open("GET", url, true);
    this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    this.request.setRequestHeader("Cache-Control", "no-cache");
    this.request.onreadystatechange = function() {
        if (_this.request.readyState == 4) {
            if (_this.request.status == 200) {
                var items = _this.request.responseText.length > 0 ? eval("(" + _this.request.responseText + ")") : "";
                control.showDropDown(items);
            }
        }
    }

    this.request.send(null);
}




//
// LocationTextFormatter
//

LocationTextFormatter = function() {
}

LocationTextFormatter.prototype.format = function(item) {
    return item.town_name + " (" + item.country_name + ")";
}




//
// Ajax
//

function Ajax() {
}

Ajax.createRequest = function() {
    if (typeof(XMLHttpRequest) != "undefined") {
        return new XMLHttpRequest();
    } else if (typeof(ActiveXObject) != "undefined") {
        var versions = new Array(
              "Msxml2.XMLHTTP.7.0",
              "Msxml2.XMLHTTP.6.0",
              "Msxml2.XMLHTTP.5.0",
              "Msxml2.XMLHTTP.4.0",
              "MSXML2.XMLHTTP.3.0",
              "MSXML2.XMLHTTP",
              "Microsoft.XMLHTTP"
        );

        for (var i = 0; i < versions.length; i++) {
            try {
                var request = new ActiveXObject(versions[i]);
                return request;
            } catch (e) {
            }
        }
    }

    throw new Error("Unable to create request object");
}




//
// Calendar
//

function Calendar(id, date) {
    this.id = id;
    this.date = date;
    this.nowDate = new Date();
    this.minDate = null;
    this.maxDate = null;
    this.dayNames = ["п", "в", "с", "ч", "п", "с", "н"];
    this.monthNames = ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"];
    this.dayCells = new Array(42);
    this.onSelected = null;
    this.showToday = true;

    for (var i = 0; i < this.dayCells.length; i++) {
        this.dayCells[i] = { "disabled": false, "number": 0 };
    }

    this.tableHeader = null;
    this.tableCalendar = null;
    this.divWindow = null;
}

Calendar.prototype.show = function(parent) {
    this.tableHeader = this.createHeader();
    this.tableCalendar = this.createGrid();

    this.divWindow = document.createElement("div");
    this.divWindow.id = this.id + "_window";
    this.divWindow.className = "calendar";
    this.divWindow.appendChild(this.tableHeader);
    this.divWindow.appendChild(this.tableCalendar);
    parent.appendChild(this.divWindow);
    Utilities.disableSelection(this.divWindow);

    this.refresh();
}

Calendar.prototype.createHeader = function() {
    var table = document.createElement("table");
    var tbody = document.createElement("tbody");
    var tr = document.createElement("tr");
    var td = null;

    table.id = this.id + "_header";
    table.cellSpacing = 0;
    table.cellPadding = 0;
    table.className = "calendar-header";

    td = document.createElement("td");
    td.id = this.id + "_button_left";
    td.className = "calendar-header-button-left";
    tr.appendChild(td);
    Utilities.addEvent(td, "mousedown", Utilities.createEventHandlerMethod(this, "onMouseDown"));

    td = document.createElement("td");
    td.id = this.id + "_title";
    td.className = "calendar-header-title";
    td.innerHTML = "Title";
    tr.appendChild(td);

    td = document.createElement("td");
    td.id = this.id + "_button_right";
    td.className = "calendar-header-button-right";
    tr.appendChild(td);
    Utilities.addEvent(td, "mousedown", Utilities.createEventHandlerMethod(this, "onMouseDown"));

    tbody.appendChild(tr);
    table.appendChild(tbody);

    return table;
}

Calendar.prototype.createGrid = function() {
    var table = document.createElement("table");
    var tbody = document.createElement("tbody");
    var tr = null;
    var td = null;

    table.id = this.id + "_grid";
    table.cellSpacing = 0;
    table.cellPadding = 0;
    table.className = "calendar-grid";

    var i = 0;

    for (var row = 0; row < 7; row++) {
        tr = document.createElement("tr");
        for (var col = 0; col < 7; col++) {
            td = document.createElement("td");
            if (row == 0) {
                td.className = "calendar-grid-cell-header";
                td.innerHTML = this.dayNames[col];
            } else {
                td.id = this.id + "_day_" + i++;
            }
            tr.appendChild(td);
        }
        tbody.appendChild(tr);
    }
    table.appendChild(tbody);
    Utilities.addEvent(table, "mousedown", Utilities.createEventHandlerMethod(this, "onMouseDown"));

    return table;
}

Calendar.prototype.getDaysInMonth = function(month, year) {
    return (month == 2) ? ((year % 4 == 0) ? ((year % 100 == 0 && year % 400 > 0) ? 28 : 29) : 28) : ((month - 1) % 7 % 2 ? 30 : 31);
}

Calendar.prototype.refresh = function() {
    var i = 0;
    var pos = 0;
    var prevMonthDate = new Date(this.date.getFullYear(), this.date.getMonth() - 1, 1, 0, 0, 0);
    var currMonthDate = new Date(this.date.getFullYear(), this.date.getMonth(), 1, 0, 0, 0);
    var prevDays = this.getDaysInMonth(prevMonthDate.getMonth() + 1, prevMonthDate.getFullYear());
    var currDays = this.getDaysInMonth(currMonthDate.getMonth() + 1, currMonthDate.getFullYear());
    var firstDayPos = currMonthDate.getDay() == 0 ? 6 : (currMonthDate.getDay() == 1 ? 7 : currMonthDate.getDay() - 1);

    while (pos < firstDayPos) {
        this.dayCells[pos].disabled = true;
        this.dayCells[pos++].number = prevDays + pos - firstDayPos;
    }

    i = 1;
    while (i <= currDays) {
        currMonthDate.setDate(i);
        if ((this.maxDate && this.maxDate.getTime() < currMonthDate.getTime()) ||
            (this.minDate && this.minDate.getTime() > currMonthDate.getTime())) {
            this.dayCells[pos].disabled = true;
        } else {
            this.dayCells[pos].disabled = false;
        }
        this.dayCells[pos++].number = i++;
    }

    i = 1;
    while (pos < this.dayCells.length) {
        this.dayCells[pos].disabled = true;
        this.dayCells[pos++].number = i++;
    }

    for (i = 0; i < this.dayCells.length; i++) {
        var day = document.getElementById(this.id + "_day_" + i);
        day.innerHTML = this.dayCells[i].number;

        if (this.dayCells[i].disabled) {
            day.className = "calendar-grid-cell-grayed";
        } else {
            if (this.showToday &&
            this.date.getFullYear() == this.nowDate.getFullYear() &&
            this.date.getMonth() == this.nowDate.getMonth() &&
            this.dayCells[i].number == this.nowDate.getDate()) {
                day.className = "calendar-grid-cell-today"
            } else {
                day.className = "calendar-grid-cell-normal";
            }
        }
    }

    var e = document.getElementById(this.id + "_title");
    if (e) {
        e.innerHTML = this.monthNames[this.date.getMonth()] + " " + this.date.getFullYear();
    }
}

Calendar.prototype.onMouseDown = function(event) {
    var target = Utilities.getEventTarget(event);

    if (target.id.length > 0) {
        if (/^.*?_day_(\d+)$/.test(target.id)) {
            if (!this.dayCells[parseInt(RegExp.$1)].disabled) {
                this.date.setDate(parseInt(target.innerHTML));
                if (this.onSelect) {
                    this.onSelect(this);
                }
            }
        } else if (target.id == (this.id + "_button_left")) {
            this.prevMonth();
        } else if (target.id == (this.id + "_button_right")) {
            this.nextMonth();
        }
    }
}

Calendar.prototype.prevMonth = function() {
    this.date.setDate(1);
    this.date.setMonth(this.date.getMonth() - 1);
    this.refresh();
}

Calendar.prototype.nextMonth = function() {
    this.date.setDate(1);
    this.date.setMonth(this.date.getMonth() + 1);
    this.refresh();
}




//
// DatePicker (inherits Calendar)
//

DatePicker.prototype = new Calendar;

function DatePicker(id) {
    var now = new Date();

    this.base = Calendar;
    this.base(id, new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0));


    this.nextDayDatePicker = null;
    this.dayComboBox = null;
    this.monthYearComboBox = null;
    this.monthYearSeparator = "_";
    this.selectedDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
    this.iconElement = null;
    this.isVisible = false;

    this.show(document.body);
    this.divWindow.style.position = "absolute";
    this.divWindow.style.top = "-500px";
    this.divWindow.style.visibility = "hidden";
    this.onSelect = Utilities.createEventHandlerMethod(this, "onSelectHandler");

    Utilities.addEvent(document, "mousedown", Utilities.createEventHandlerMethod(this, "onBodyMouseDownHandler"));
}

DatePicker.prototype.setDayComboBox = function(element) {
    this.dayComboBox = element;
    this.setControlsMaxDays();
    this.selectedDate = this.getControlsDate();
    Utilities.addEvent(this.dayComboBox, "change", Utilities.createEventHandlerMethod(this, "onControlsChangedHandler"));
}

DatePicker.prototype.setMonthYearComboBox = function(element) {
    this.monthYearComboBox = element;
    this.setControlsMaxDays();
    this.selectedDate = this.getControlsDate();
    Utilities.addEvent(this.monthYearComboBox, "change", Utilities.createEventHandlerMethod(this, "onControlsChangedHandler"));
}

DatePicker.prototype.showUnder = function(iconElement, underElement) {
    this.iconElement = iconElement;
    var lt = Utilities.getElementPosition(underElement);
    this.divWindow.style.left = lt[0] + "px";
    this.divWindow.style.top = (lt[1] + underElement.offsetHeight + 1) + "px";
    this.divWindow.style.visibility = "visible";
    this.selectedDate = this.getControlsDate();
    this.syncDate(this.selectedDate, this.date);
    this.refresh();
    this.isVisible = true;
}

DatePicker.prototype.hide = function() {
    this.divWindow.style.visibility = "hidden";
    this.isVisible = false;
}

DatePicker.prototype.toggle = function(iconElement, underElement) {
    if (this.isVisible) {
        this.hide();
    } else {
        this.showUnder(iconElement, underElement);
    }
}

DatePicker.prototype.setMinDateToday = function() {
    this.minDate = new Date(this.nowDate.getFullYear(), this.nowDate.getMonth(), this.nowDate.getDate(), 0, 0, 0);
}

DatePicker.prototype.setMinDateTomorrow = function() {
    this.minDate = new Date(this.nowDate.getFullYear(), this.nowDate.getMonth(), this.nowDate.getDate() + 1, 0, 0, 0);
}

DatePicker.prototype.setMinDateFromCurrentControlValues = function() {
    var date = this.getControlsDate();
    this.minDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
}

DatePicker.prototype.setMinDateFromMinControlValues = function() {
    if (this.monthYearComboBox && this.monthYearComboBox.options.length > 0) {
        var value = this.monthYearComboBox.options[0].value;
        if (value) {
            var my = value.split(this.monthYearSeparator);
            if (my && my.length == 2) {
                my[0] = parseInt(my[0]);
                my[1] = parseInt(my[1]);
                if (!isNaN(my[0]) && !isNaN(my[1])) {
                    this.minDate = new Date(my[1], my[0] - 1, 1, 0, 0, 0);
                }
            }
        }
    }
}

DatePicker.prototype.setMaxDateFromMaxControlValues = function() {
    if (this.monthYearComboBox && this.monthYearComboBox.options.length > 0) {
        var value = this.monthYearComboBox.options[this.monthYearComboBox.options.length - 1].value;
        if (value) {
            var my = value.split(this.monthYearSeparator);
            if (my && my.length == 2) {
                my[0] = parseInt(my[0]);
                my[1] = parseInt(my[1]);
                if (!isNaN(my[0]) && !isNaN(my[1])) {
                    this.maxDate = new Date(my[1], my[0] - 1, this.getDaysInMonth(my[0], my[1]), 0, 0, 0);
                }
            }
        }
    }
}

DatePicker.prototype.getControlsDate = function() {
    var date = new Date(this.selectedDate);
    var value;

    if (this.dayComboBox && this.dayComboBox.options.length > 0) {
        value = this.dayComboBox.options[this.dayComboBox.selectedIndex].value;
        if (value != null) {
            var day = parseInt(value);
            if (!isNaN(day)) {
                date.setDate(day);
            }
        }
    }

    if (this.monthYearComboBox && this.monthYearComboBox.options.length > 0) {
        value = this.monthYearComboBox.options[this.monthYearComboBox.selectedIndex].value;
        if (value != null) {
            var my = value.split(this.monthYearSeparator);
            if (my && my.length == 2) {
                my[0] = parseInt(my[0]);
                my[1] = parseInt(my[1]);
                if (!isNaN(my[0]) && !isNaN(my[1])) {
                    date.setMonth(my[0] - 1);
                    date.setFullYear(my[1]);
                }
            }
        }
    }

    return date;
}

DatePicker.prototype.setControlsDate = function(date) {
    var value, i;
    if (this.dayComboBox) {
        value = date.getDate();
        for (i = 0; i < this.dayComboBox.options.length; i++) {
            if (this.dayComboBox.options[i].value == value) {
                this.dayComboBox.selectedIndex = i;
                break;
            }
        }
    }

    if (this.monthYearComboBox) {
        value = (date.getMonth() + 1) + this.monthYearSeparator + date.getFullYear();
        for (i = 0; i < this.monthYearComboBox.options.length; i++) {
            if (this.monthYearComboBox.options[i].value == value) {
                this.monthYearComboBox.selectedIndex = i;
                break;
            }
        }
    }
}

DatePicker.prototype.syncDate = function(srcDate, dstDate) {
    dstDate.setFullYear(srcDate.getFullYear());
    dstDate.setMonth(srcDate.getMonth());
    dstDate.setDate(srcDate.getDate());
}

DatePicker.prototype.setControlsMaxDays = function() {
    if (this.dayComboBox && this.dayComboBox.options.length > 0 && this.monthYearComboBox && this.monthYearComboBox.length > 0) {
        var value = this.monthYearComboBox.options[this.monthYearComboBox.selectedIndex].value;
        var i;

        if (value == null) {
            return;
        }

        var my = value.split(this.monthYearSeparator);

        if (!my || my.length != 2) {
            return;
        }

        my[0] = parseInt(my[0]);
        my[1] = parseInt(my[1]);

        if (isNaN(my[0]) || isNaN(my[1])) {
            return;
        }

        var daysMax = this.getDaysInMonth(my[0], my[1]);
        var daysInControl = this.dayComboBox.options.length;
        var option = null;

        if (daysInControl > daysMax) {
            if (this.dayComboBox.selectedIndex >= daysMax) {
                this.dayComboBox.selectedIndex = daysMax - 1;
            }
            for (i = 0; i < (daysInControl - daysMax); i++) {
                this.dayComboBox.options[daysMax] = null;
            }
        } else if (daysInControl < daysMax) {
            for (i = daysInControl + 1; i <= daysMax; i++) {
                option = document.createElement("option");
                option.text = i;
                option.value = i;
                this.dayComboBox.options.add(option);
            }
        }
    }
}

DatePicker.prototype.updateNextDayDatePicker = function(date) {
    if (this.nextDayDatePicker) {
        if (this.nextDayDatePicker.selectedDate <= date) {
            var dateNextDay = new Date(date);
            dateNextDay.setDate(dateNextDay.getDate() + 1);
            this.nextDayDatePicker.selectedDate = dateNextDay;
            this.nextDayDatePicker.setControlsDate(dateNextDay);
            this.nextDayDatePicker.setControlsMaxDays();
        }
    }
}

DatePicker.prototype.onSelectHandler = function(o) {
    this.syncDate(this.date, this.selectedDate);
    this.setControlsDate(this.selectedDate);
    this.setControlsMaxDays();
    this.updateNextDayDatePicker(this.selectedDate);
    this.hide();
}

DatePicker.prototype.onControlsChangedHandler = function(event) {
    this.setControlsMaxDays();
    this.selectedDate = this.getControlsDate();
    this.updateNextDayDatePicker(this.selectedDate);
}

DatePicker.prototype.onBodyMouseDownHandler = function(event) {
    if (this.isVisible) {
        var target = Utilities.getEventTarget(event);
        if (target.id != this.iconElement.id && target.id.indexOf(this.id) != 0) {
            this.hide();
        }
    }
}




//
// Utilities
//

var Utilities = {
    createEventHandlerMethod: function(object, method) {
        return function() {
            object[method].apply(object, arguments);
        }
    },

    addEvent: function(object, event, handler) {
        if (object.addEventListener) {
            object.addEventListener(event, handler, false);
        } else if (object.attachEvent) {
            object.attachEvent("on" + event, handler);
        }
    },

    removeEvent: function(object, event, handler) {
        if (object.remoteEventListener) {
            object.removeEventListener(event, handler, false);
        } else if (object.detachEvent) {
            object.detachEvent("on" + event, handler);
        }
    },

    stopEvent: function(event) {
        if (event) {
            if (window.event) {
                event.cancelBubble = true;
                event.returnValue = false;
            } else {
                event.preventDefault();
                event.stopPropagation();
            }
        }
        return false;
    },

    getEvent: function(event) {
        return (window.event) ? window.event : event;
    },

    getEventTarget: function(event) {
        return (window.event) ? window.event.srcElement : event.target;
    },

    disableSelection: function(object) {
        object.onselectstart = function() {
            return false;
        }
        object.unselectable = "on";
        object.style.MozUserSelect = "none";
    },

    getElementPosition: function(object) {
        var l = t = 0;

        if (object.offsetParent) {
            l = object.offsetLeft;
            t = object.offsetTop;
            while (object = object.offsetParent) {
                l += object.offsetLeft;
                t += object.offsetTop;
            }
        }

        return [l, t];
    },

    hasClass: function(element, cls) {
        if (element && element.className) {
            var reg = new RegExp("(^|\\s+)(" + cls + ")(\\s+|$)");
            return reg.test(element.className);
        } else {
            return false;
        }
    },

    addClass: function(element, cls) {
        if (element) {
            if (!element.className) {
                element.className = cls;
            } else if (!this.hasClass(element, cls)) {
                element.className += " " + cls;
            }
        }
    },

    removeClass: function(element, cls) {
        if (element && element.className) {
            if (this.hasClass(element, cls)) {
                var classes = element.className.split(/\s+/);
                for (var i = 0; i < classes.length; i++) {
                    if (classes[i] == cls) {
                        classes.splice(i, 1);
                        element.className = classes.join(" ");
                    }
                }
            }
        }
    },

    replaceClass: function(element, clsSearch, clsReplace) {
        if (element && element.className) {
            if (this.hasClass(element, clsSearch)) {
                var reg = new RegExp("(^|\\s+)(" + clsSearch + ")(\\s+|$)");
                element.className = element.className.replace(reg, "$1" + clsReplace + "$3");
            }
        }
    }
}
