(function() {
    
    function IntervalCalendar(container, cfg) {
        this._iState = 0;

        // Must be a multi-select CalendarGroup
        cfg = cfg || {};
        cfg.multi_select = true;
        cfg.close = true;


        cfg.START_WEEKDAY = 1;
        cfg.SHOW_WEEK_HEADER = true;
        cfg.WEEKDAYS_SHORT = ["S", "P", "A", "T", "K", "Pn", "\u0160"];
        cfg.MONTHS_LONG = [
        "Sausis",
        "Vasaris",
        "Kovas",
        "Balandis",
        "Gegu\u017eė",
        "Bir\u017eelis",
        "Liepa",
        "Rugpj\u016btis",
        "Rugs\u0117jis",
        "Spalis",
        "Lapkritis",
        "Gruodis"];
        cfg.title = "Nurodykite dat\u0173 interval\u0105";


        // Call parent constructor
        IntervalCalendar.superclass.constructor.call(this, container, cfg);

        // Subscribe internal event handlers
        this.beforeSelectEvent.subscribe(this._intervalOnBeforeSelect, this, true);
        this.selectEvent.subscribe(this._intervalOnSelect, this, true);
        this.beforeDeselectEvent.subscribe(this._intervalOnBeforeDeselect, this, true);
        this.deselectEvent.subscribe(this._intervalOnDeselect, this, true);
    }

    /**
     * Default configuration parameters.
     *
     * @property IntervalCalendar._DEFAULT_CONFIG
     * @final
     * @static
     * @private
     * @type Object
     */
    IntervalCalendar._DEFAULT_CONFIG = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG;

    YAHOO.lang.extend(IntervalCalendar, YAHOO.widget.CalendarGroup, {

        /**
         * Returns a string representation of a date which takes into account
         * relevant localization settings and is suitable for use with
         * YAHOO.widget.CalendarGroup and YAHOO.widget.Calendar methods.
         *
         * @method _dateString
         * @private
         * @param {Date} d The JavaScript Date object of which to obtain a string representation.
         * @return {String} The string representation of the JavaScript Date object.
         */
        _dateString : function(d) {
            var a = [];
            a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_MONTH_POSITION.key)-1] = (d.getMonth() + 1);
            a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_DAY_POSITION.key)-1] = d.getDate();
            a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_YEAR_POSITION.key)-1] = d.getFullYear();
            var s = this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.DATE_FIELD_DELIMITER.key);
            return a.join(s);
        },

        /**
         * Given a lower and upper date, returns a string representing the interval
         * of dates between and including them, which takes into account relevant
         * localization settings and is suitable for use with
         * YAHOO.widget.CalendarGroup and YAHOO.widget.Calendar methods.
         * <p>
         * <b>Note:</b> No internal checking is done to ensure that the lower date
         * is in fact less than or equal to the upper date.
         * </p>
         *
         * @method _dateIntervalString
         * @private
         * @param {Date} l The lower date of the interval, as a JavaScript Date object.
         * @param {Date} u The upper date of the interval, as a JavaScript Date object.
         * @return {String} The string representing the interval of dates between and
         *                   including the lower and upper dates.
         */
        _dateIntervalString : function(l, u) {
            var s = this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.DATE_RANGE_DELIMITER.key);
            return (this._dateString(l)
                + s + this._dateString(u));
        },

        /**
         * Returns the lower and upper dates of the currently selected interval, if an
         * interval is selected.
         *
         * @method getInterval
         * @return {Array} An empty array if no interval is selected; otherwise an array
         *                 consisting of two JavaScript Date objects, the first being the
         *                 lower date of the interval and the second being the upper date.
         */
        getInterval : function() {
            // Get selected dates
            var dates = this.getSelectedDates();
            if(dates.length > 0) {
                // Return lower and upper date in array
                var l = dates[0];
                var u = dates[dates.length - 1];
                return [l, u];
            }
            else {
                // No dates selected, return empty array
                return [];
            }
        },

        /**
         * Sets the currently selected interval by specifying the lower and upper
         * dates of the interval (in either order).
         * <p>
         * <b>Note:</b> The render method must be called after setting the interval
         * for any changes to be seen.
         * </p>
         *
         * @method setInterval
         * @param {Date} d1 A JavaScript Date object.
         * @param {Date} d2 A JavaScript Date object.
         */
        setInterval : function(d1, d2) {
            // Determine lower and upper dates
            var b = (d1 <= d2);
            var l = b ? d1 : d2;
            var u = b ? d2 : d1;
            // Update configuration
            this.cfg.setProperty('selected', this._dateIntervalString(l, u), false);
            this._iState = 2;
        },

        /**
         * Resets the currently selected interval.
         * <p>
         * <b>Note:</b> The render method must be called after resetting the interval
         * for any changes to be seen.
         * </p>
         *
         * @method resetInterval
         */
        resetInterval : function() {
            // Update configuration
            this.cfg.setProperty('selected', [], false);
            this._iState = 0;
        },

        /**
         * Handles beforeSelect event.
         *
         * @method _intervalOnBeforeSelect
         * @private
         */
        _intervalOnBeforeSelect : function(t,a,o) {
            // Update interval state
            this._iState = (this._iState + 1) % 3;
            if(this._iState == 0) {
                // If starting over with upcoming selection, first deselect all
                this.deselectAll();
                this._iState++;
            }
        },

        /**
         * Handles selectEvent event.
         *
         * @method _intervalOnSelect
         * @private
         */
        _intervalOnSelect : function(t,a,o) {
            // Get selected dates
            var dates = this.getSelectedDates();
            if(dates.length > 1) {
                /* If more than one date is selected, ensure that the entire interval
                    between and including them is selected */
                var l = dates[0];
                var u = dates[dates.length - 1];
                this.cfg.setProperty('selected', this._dateIntervalString(l, u), false);
            }
            // Render changes
            this.render();
        },

        /**
         * Handles beforeDeselect event.
         *
         * @method _intervalOnBeforeDeselect
         * @private
         */
        _intervalOnBeforeDeselect : function(t,a,o) {
            if(this._iState != 0) {
                /* If part of an interval is already selected, then swallow up
                    this event because it is superfluous (see _intervalOnDeselect) */
                return false;
            }
        },

        /**
         * Handles deselectEvent event.
         *
         * @method _intervalOnDeselect
         * @private
         */
        _intervalOnDeselect : function(t,a,o) {
            if(this._iState != 0) {
                // If part of an interval is already selected, then first deselect all
                this._iState = 0;
                this.deselectAll();

                // Get individual date deselected and page containing it
                var d = a[0][0];
                var date = YAHOO.widget.DateMath.getDate(d[0], d[1] - 1, d[2]);
                var page = this.getCalendarPage(date);
                if(page) {
                    // Now (re)select the individual date
                    page.beforeSelectEvent.fire();
                    this.cfg.setProperty('selected', this._dateString(date), false);
                    page.selectEvent.fire([d]);
                }
                // Swallow up since we called deselectAll above
                return false;
            }
        }
    });

    YAHOO.namespace("example.calendar");
    YAHOO.example.calendar.IntervalCalendar = IntervalCalendar;
})();




var MultiCalendar = Class.create({

    calendar: null,
    contCal: null,
    start: null,
    end: null,
    dateRegexp: "[0-9]{4}-[0-9]{2}-[0-9]{2}",


    init: function(cal, start, end) {

        this.contCal = $(cal);
        this.start = $(start);
        this.end = $(end);

        this._createCalendar();
    },



    _createCalendar: function() {
        this.calendar = new YAHOO.example.calendar.IntervalCalendar(this.contCal, {
            pages:2
        });

        //this.calendar.selectEvent.subscribe(this._onSelect, this, true);
        this.updateDates();
        this.hide();
        this.calendar.render();

        var div = new Element('div', {align: 'right', 'class': 'calButtons'}).setStyle({
            padding: '6px'
        });
        var ok = new Element('input', {type: 'button', value: 'Patvirtinti' });
        var cancel = new Element('input', {type: 'button', value: 'Atšaukti' });
        div.insert(ok).insert(cancel);
        $(this.contCal).insert(div);

        ok.observe('click', function(event) {
            this._onSelect();
            this.hide();

            //Update filter form on select
            var base_url = $$('base').first().href;
            var filter = new TripsFilter(base_url);
            filter.formId = "formFilter";
            filter.updateForm();

        }.bind(this));

        cancel.observe('click', function(event) {
            this.hide();
        }.bind(this));

    },


    updateDates: function() {

        if (this.start && this.end) {
            var startDate = this._explodeDate(this.start.value);
            var endDate   = this._explodeDate(this.end.value);

            if (startDate && endDate) {
                var start   = YAHOO.widget.DateMath.getDate(startDate[0], startDate[1] - 1, startDate[2]);
                var end     = YAHOO.widget.DateMath.getDate(endDate[0], endDate[1] - 1, endDate[2]);
                this.calendar.setInterval(start, end);
            }
        }
    },

    _explodeDate: function(date) {
        var re = new RegExp(this.dateRegexp);
        
        if (re.exec(date) !== null) {
            return [
                date.substring(0, 4),
                date.substring(5, 7),
                date.substring(8, 10),
            ];
        }
        return null;
    },


    _onSelect: function() {
        interval = this.calendar.getInterval();
        
        if (interval.length == 2) {
            inDate = interval[0];

            this.start.value = this._prepareDate(inDate);

            if (interval[0].getTime() != interval[1].getTime()) {
                outDate = interval[1];
                this.end.value = this._prepareDate(outDate);
            } else {
                this.end.value = "";
            }
        }
    },


    _prepareDate: function(date) {
        var month = (date.getMonth() + 1);
        if (month < 10) {
            month = "0" + month.toString();
        }

        var day = date.getDate();
        if (day < 10) {
            day = "0" + day.toString();
        }
        
        return date.getFullYear() + "-" + month + "-" + day;
    },
    
    show: function() {
        this.calendar.show();
    },

    hide: function() {
        this.calendar.hide();
    }


});


Event.observe(window, 'load', function() {
    var mc = new MultiCalendar();
    mc.init("cal1Container", "date_from", "date_to");

    $$('#formFilter .date').each(function(item) {
        item.observe('focus', function() {
            mc.show();
        });
    });
});