﻿// Register the namespace for the control.
Type.registerNamespace('Bookt.UI.Controls.Extenders');

Bookt.UI.Controls.Extenders.CalendarExtender = function(element) {
    /// <summary>
    /// A behavior that attaches a calendar date selector to a textbox
    /// </summmary>
    /// <param name="element" type="Sys.UI.DomElement">The element to attach to</param>

    Bookt.UI.Controls.Extenders.CalendarExtender.initializeBase(this, [element]);

    this._lowerBoundDate = null;
    this._upperBoundDate = null;
}
Bookt.UI.Controls.Extenders.CalendarExtender.prototype = {
    initialize: function() {
        /// <summary>
        /// Initializes the components and parameters for this behavior
        /// </summary>

        Bookt.UI.Controls.Extenders.CalendarExtender.callBaseMethod(this, "initialize");
    },
    dispose: function() {
        /// <summary>
        /// Disposes this behavior's resources
        /// </summary>

        Bookt.UI.Controls.Extenders.CalendarExtender.callBaseMethod(this, "dispose");
    },

    get_lowerBoundDate: function() {
        /// <summary>
        /// The date currently visible in the calendar
        /// </summary>
        /// <value type="Date" />
        if (this._lowerBoundDate != null) {
            return this._lowerBoundDate;
        }
    },
    set_lowerBoundDate: function(value) {
        if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
            value = new Date(value);
        }
        if (value) value = value.getDateOnly();
        if (this._lowerBoundDate != value) {
            this._lowerBoundDate = value;
            this.raisePropertyChanged("lowerBoundDate");
        }
    },

    get_upperBoundDate: function() {
        /// <value type="Date">
        /// The date to use for "Today"
        /// </value>
        if (this._upperBoundDate != null) {
            return this._upperBoundDate;
        }
    },
    set_upperBoundDate: function(value) {
        if (value && (String.isInstanceOfType(value)) && (value.length != 0)) {
            value = new Date(value);
        }
        if (value) value = value.getDateOnly();
        if (this._upperBoundDate != value) {
            this._upperBoundDate = value;
            this.raisePropertyChanged("upperBoundDate");
        }
    },

    _performLayout: function() {
        /// <summmary>
        /// Updates the various views of the calendar to match the current selected and visible dates
        /// </summary>

        var elt = this.get_element();
        if (!elt) return;
        if (!this.get_isInitialized()) return;
        if (!this._isOpen) return;

        var dtf = Sys.CultureInfo.CurrentCulture.dateTimeFormat;
        var selectedDate = this.get_selectedDate();
        var visibleDate = this._getEffectiveVisibleDate();
        var todaysDate = this.get_todaysDate();

        switch (this._mode) {
            case "days":

                var firstDayOfWeek = this._getFirstDayOfWeek();
                var daysToBacktrack = visibleDate.getDay() - firstDayOfWeek;
                if (daysToBacktrack <= 0)
                    daysToBacktrack += 7;

                var startDate = new Date(visibleDate.getFullYear(), visibleDate.getMonth(), visibleDate.getDate() - daysToBacktrack, this._hourOffsetForDst);
                var currentDate = startDate;

                for (var i = 0; i < 7; i++) {
                    var dayCell = this._daysTableHeaderRow.cells[i].firstChild;
                    if (dayCell.firstChild) {
                        dayCell.removeChild(dayCell.firstChild);
                    }
                    dayCell.appendChild(document.createTextNode(dtf.ShortestDayNames[(i + firstDayOfWeek) % 7]));
                }
                for (var week = 0; week < 6; week++) {
                    var weekRow = this._daysBody.rows[week];
                    for (var dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
                        var dayCell = weekRow.cells[dayOfWeek].firstChild;
                        if (dayCell.firstChild) {
                            dayCell.removeChild(dayCell.firstChild);
                        }
                        dayCell.appendChild(document.createTextNode(currentDate.getDate()));
                        dayCell.title = currentDate.localeFormat("D");
                        dayCell.date = currentDate;
                        $common.removeCssClasses(dayCell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
                        Sys.UI.DomElement.addCssClass(dayCell.parentNode, this._getCssClass(dayCell.date, 'd'));
                        currentDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1, this._hourOffsetForDst);
                    }
                }

                this._prevArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() - 1, 1, this._hourOffsetForDst);
                this._nextArrow.date = new Date(visibleDate.getFullYear(), visibleDate.getMonth() + 1, 1, this._hourOffsetForDst);
                if (this._title.firstChild) {
                    this._title.removeChild(this._title.firstChild);
                }
                this._title.appendChild(document.createTextNode(visibleDate.localeFormat("MMMM, yyyy")));
                this._title.date = visibleDate;

                break;
            case "months":

                for (var i = 0; i < this._monthsBody.rows.length; i++) {
                    var row = this._monthsBody.rows[i];
                    for (var j = 0; j < row.cells.length; j++) {
                        var cell = row.cells[j].firstChild;
                        cell.date = new Date(visibleDate.getFullYear(), cell.month, 1, this._hourOffsetForDst);
                        cell.title = cell.date.localeFormat("Y");
                        $common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
                        Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'M'));
                    }
                }

                if (this._title.firstChild) {
                    this._title.removeChild(this._title.firstChild);
                }
                this._title.appendChild(document.createTextNode(visibleDate.localeFormat("yyyy")));
                this._title.date = visibleDate;
                this._prevArrow.date = new Date(visibleDate.getFullYear() - 1, 0, 1, this._hourOffsetForDst);
                this._nextArrow.date = new Date(visibleDate.getFullYear() + 1, 0, 1, this._hourOffsetForDst);

                break;
            case "years":

                var minYear = (Math.floor(visibleDate.getFullYear() / 10) * 10);
                for (var i = 0; i < this._yearsBody.rows.length; i++) {
                    var row = this._yearsBody.rows[i];
                    for (var j = 0; j < row.cells.length; j++) {
                        var cell = row.cells[j].firstChild;
                        cell.date = new Date(minYear + cell.year, 0, 1, this._hourOffsetForDst);
                        if (cell.firstChild) {
                            cell.removeChild(cell.lastChild);
                        } else {
                            cell.appendChild(document.createElement("br"));
                        }
                        cell.appendChild(document.createTextNode(minYear + cell.year));
                        $common.removeCssClasses(cell.parentNode, ["ajax__calendar_other", "ajax__calendar_disabled", "ajax__calendar_active"]);
                        Sys.UI.DomElement.addCssClass(cell.parentNode, this._getCssClass(cell.date, 'y'));
                    }
                }

                if (this._title.firstChild) {
                    this._title.removeChild(this._title.firstChild);
                }
                this._title.appendChild(document.createTextNode(minYear.toString() + "-" + (minYear + 9).toString()));
                this._title.date = visibleDate;
                this._prevArrow.date = new Date(minYear - 10, 0, 1, this._hourOffsetForDst);
                this._nextArrow.date = new Date(minYear + 10, 0, 1, this._hourOffsetForDst);

                break;
        }
        if (this._today.firstChild) {
            this._today.removeChild(this._today.firstChild);
        }
        this._today.appendChild(document.createTextNode(String.format(AjaxControlToolkit.Resources.Calendar_Today, todaysDate.localeFormat("MMMM d, yyyy"))));
        this._today.date = todaysDate;
    },

    _isOutOfBounds: function(date, part) {
        /// <summary>
        /// Gets whether the supplied date is out of the lower / upper bound date limits
        /// </summary>
        /// <param name="date" type="Date">The date to match</param>
        /// <param name="part" type="String">The most significant part of the date to test</param>
        /// <returns type="Boolean" />                   
        switch (part) {
            case 'd':
                if (this._lowerBoundDate && date < this._lowerBoundDate) {
                    Sys.Debug.trace("1:" + date.toString())
                    return true;
                }
                else if (this._upperBoundDate && date > this._upperBoundDate) {
                    Sys.Debug.trace("2:" + date.toString())
                    return true;
                }
            case 'M':
                /*if (this._lowerBoundDate && (date.getMonth() < this._lowerBoundDate.getMonth() ||
                      date.getFullYear() < this._lowerBoundDate.getFullYear())) {
                    Sys.Debug.trace("3:" + date.toString())
                    return true;
                }
                else if (this._upperBoundDate && (date.getMonth() > this._upperBoundDate.getMonth() ||
                      date.getFullYear() > this._upperBoundDate.getFullYear())) {
                    Sys.Debug.trace("4" + date.toString())
                    return true;
                }*/
            case 'y':
                if (this._lowerBoundDate && date.getFullYear() < this._lowerBoundDate.getFullYear()) {
                    Sys.Debug.trace("5:" + date.toString())
                    return true;
                }
                else if (this._upperBoundDate && date.getFullYear() > this._upperBoundDate.getFullYear()) {
                    Sys.Debug.trace("6:" + date.toString())
                    return true;
                }
        }
        return false;
    },
    _getCssClass: function(date, part) {
        /// <summary>
        /// Gets the cssClass to apply to a cell based on a supplied date
        /// </summary>
        /// <param name="date" type="Date">The date to match</param>
        /// <param name="part" type="String">The most significant part of the date to test</param>
        /// <returns type="String" />
        if (this._isSelected(date, part)) {
            return "ajax__calendar_active";
        } else if (this._isOther(date, part)) {
            if (this._isOutOfBounds(date, part))
                return "ajax__calendar_disabled";
            //return "ajax__calendar_disabled ajax__calendar_other";
            return "ajax__calendar_other";
        } else if (this._isOutOfBounds(date, part)) {
            return "ajax__calendar_disabled";
        } else {
            return "";
        }
    },
    _cell_onclick: function(e) {
        /// <summary> 
        /// Handles the click event of a cell
        /// </summary>
        /// <param name="e" type="Sys.UI.DomEvent">The arguments for the event</param>

        e.stopPropagation();
        e.preventDefault();

        if (!this._enabled) return;

        var target = e.target;
        var visibleDate = this._getEffectiveVisibleDate();
        Sys.UI.DomElement.removeCssClass(target.parentNode, "ajax__calendar_hover");
        switch (target.mode) {
            case "prev":
            case "next":
                this._switchMonth(target.date);
                break;
            case "title":
                switch (this._mode) {
                    case "days": this._switchMode("months"); break;
                    case "months": this._switchMode("years"); break;
                }
                break;
            case "month":
                if (!this._isOutOfBounds(target.date, 'M')) {
                    if (target.month == visibleDate.getMonth()) {
                        this._switchMode("days");
                    } else {
                        this._visibleDate = target.date;
                        this._switchMode("days");
                    }
                }
                break;
            case "year":
                if (!this._isOutOfBounds(target.date, 'y')) {
                    if (target.date.getFullYear() == visibleDate.getFullYear()) {
                        this._switchMode("months");
                    } else {
                        this._visibleDate = target.date;
                        this._switchMode("months");
                    }
                }
                break;
            case "day":
                if (!this._isOutOfBounds(target.date, 'd')) {
                    this.set_selectedDate(target.date);
                    this._switchMonth(target.date);
                    this._blur.post(true);
                    this.raiseDateSelectionChanged();
                }
                break;
            case "today":
                this.set_selectedDate(target.date);
                this._switchMonth(target.date);
                this._blur.post(true);
                this.raiseDateSelectionChanged();
                break;
        }
    }
}
Bookt.UI.Controls.Extenders.CalendarExtender.registerClass("Bookt.UI.Controls.Extenders.CalendarExtender", AjaxControlToolkit.CalendarBehavior);
  
 
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();