<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->


<bindings id="calendar-specific-view-bindings"
    xmlns="http://www.mozilla.org/xbl"
    xmlns:html="http://www.w3.org/1999/xhtml"
    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:xbl="http://www.mozilla.org/xbl">

    <binding id="calendar-day-view"
             extends="chrome://calendar/content/calendar-multiday-view.xml#calendar-multiday-view">
        <implementation implements="calICalendarView">
            <property name="observerID">
                <getter><![CDATA[
                    return "day-view-observer";
                ]]></getter>
            </property>
            <property name="supportsWorkdaysOnly"
                      readonly="true"
                      onget="return false;"/>

            <!--Public methods-->
            <method name="goToDay">
                <parameter name="aDate"/>
                <body><![CDATA[
                    aDate = aDate || currentView().selectedDay;
                    aDate = aDate.getInTimezone(this.timezone);
                    this.setDateRange(aDate, aDate);
                    this.selectedDay = aDate;
                ]]></body>
            </method>
            <method name="moveView">
                <parameter name="aNumber"/>
                <body><![CDATA[
                    if (!aNumber) {
                        this.goToDay(now());
                    } else {
                        var currentDay = this.startDay.clone();
                        currentDay.day += aNumber;
                        this.goToDay(currentDay);
                    }
                ]]></body>
            </method>
        </implementation>
    </binding>

    <binding id="calendar-week-view"
             extends="chrome://calendar/content/calendar-multiday-view.xml#calendar-multiday-view">
        <implementation implements="calICalendarView">
            <constructor><![CDATA[
                // add a listener for the mode change
                let self = this;
                this.mModeHandler = function modeHandler(event) {
                    if (event.attrName == "mode") {
                        self.onModeChanged(event);
                    }
                };
                document.getElementById("modeBroadcaster").addEventListener("DOMAttrModified", this.mModeHandler, true);
            ]]></constructor>
            <destructor><![CDATA[
                document.getElementById("modeBroadcaster").removeEventListener("DOMAttrModified", this.mModeHandler, true);
            ]]></destructor>

            <property name="observerID">
                <getter><![CDATA[
                    return "week-view-observer";
                ]]></getter>
            </property>

            <method name="onModeChanged">
              <parameter name="aEvent"/>
              <body><![CDATA[
                let currentMode = document.getElementById("modeBroadcaster").getAttribute("mode");
                if (currentMode != "calendar") {
                    timeIndicator.cancel();
                }
              ]]></body>
            </method>

            <!--Public methods-->
            <method name="goToDay">
                <parameter name="aDate"/>
                <body><![CDATA[
                    this.displayDaysOff = !this.mWorkdaysOnly;

                    aDate = aDate || currentView().selectedDay;
                    aDate = aDate.getInTimezone(this.timezone);
                    var d1 = getWeekInfoService().getStartOfWeek(aDate);
                    var d2 = d1.clone();
                    d2.day += 6;
                    this.setDateRange(d1, d2);
                    this.selectedDay = aDate;
                ]]></body>
            </method>
            <method name="moveView">
                <parameter name="aNumber"/>
                <body><![CDATA[
                    if (!aNumber) {
                        this.goToDay(now());
                    } else {
                        var d1 = this.selectedDay.clone();
                        d1.day += 7 * aNumber;
                        this.goToDay(d1);
                    }
                ]]></body>
            </method>
        </implementation>
    </binding>

    <binding id="calendar-multiweek-view" extends="chrome://calendar/content/calendar-month-view.xml#calendar-month-base-view">
        <implementation implements="calICalendarView">
	        <constructor><![CDATA[
                this.mWeeksInView = cal.getPrefSafe("calendar.weeks.inview", 4);
            ]]></constructor>

            <field name="mWeeksInView">4</field>

            <property name="weeksInView">
                <getter><![CDATA[
                    return this.mWeeksInView;
                ]]></getter>
                <setter><![CDATA[
                    this.mWeeksInView = val;
                    cal.setPref("calendar.weeks.inview", Number(val));
                    this.refreshView();
                    return val;
                ]]></setter>
            </property>

            <property name="supportsZoom" readonly="true"
                      onget="return true;"/>

            <method name="zoomIn">
              <parameter name="aLevel"/>
              <body><![CDATA[
                let visibleWeeks = cal.getPrefSafe("calendar.weeks.inview", 4);
                visibleWeeks += (aLevel || 1);

                cal.setPref("calendar.weeks.inview", Math.min(visibleWeeks, 6));
              ]]></body>
            </method>
            <method name="zoomOut">
              <parameter name="aLevel"/>
              <body><![CDATA[
                let visibleWeeks = cal.getPrefSafe("calendar.weeks.inview", 4);
                visibleWeeks -= (aLevel || 1);

                cal.setPref("calendar.weeks.inview", Math.max(visibleWeeks, 2));
              ]]></body>
            </method>
            <method name="zoomReset">
              <body><![CDATA[
                cal.setPref("calendar.view.visiblehours", 4);
              ]]></body>
            </method>

            <property name="observerID">
                <getter><![CDATA[
                    return "multiweek-view-observer";
                ]]></getter>
            </property>

            <!--Public methods-->
            <method name="goToDay">
                <parameter name="aDate"/>
                <body><![CDATA[
                    this.showFullMonth = false;
                    this.displayDaysOff = !this.mWorkdaysOnly;

                    // If aDate is null it means that only a refresh is needed
                    // without changing the start and end of the view.
                    if (aDate) {
                        aDate = aDate.getInTimezone(this.timezone);
                        // Get the first date that should be shown. This is the
                        // start of the week of the day that we're centering around
                        // adjusted for the day the week starts on and the number
                        // of previous weeks we're supposed to display.
                        let d1 = getWeekInfoService().getStartOfWeek(aDate);
                        d1.day -= (7 * cal.getPrefSafe("calendar.previousweeks.inview", 0));
                        // The last day we're supposed to show
                        let d2 = d1.clone();
                        d2.day += ((7 * this.mWeeksInView) - 1);
                        this.setDateRange(d1, d2);
                        this.selectedDay = aDate;
                    } else {
                        this.refresh();
                    }
                ]]></body>
            </method>
            <method name="moveView">
                <parameter name="aNumber"/>
                <body><![CDATA[
                    if (!aNumber) {
                        let date = now();
                        this.goToDay(date);
                        this.selectedDay = date;
                    } else {
                        let d1 = this.startDay.clone();
                        let savedSelectedDay = this.selectedDay.clone();
                        // aNumber only corresponds to the number of weeks to move
                        // make sure to compensate for previous weeks in view too
                        d1.day += 7 * (aNumber + cal.getPrefSafe("calendar.previousweeks.inview", 4));
                        this.goToDay(d1);
                        savedSelectedDay.day += 7 * aNumber;
                        this.selectedDay = savedSelectedDay;
                    }
                ]]></body>
            </method>
        </implementation>
    </binding>

    <binding id="calendar-month-view" extends="chrome://calendar/content/calendar-month-view.xml#calendar-month-base-view">
        <implementation implements="calICalendarView">

            <property name="observerID">
                <getter><![CDATA[
                    return "month-view-observer";
                ]]></getter>
            </property>

            <!--Public methods-->
            <method name="goToDay">
                <parameter name="aDate"/>
                <body><![CDATA[
                    this.displayDaysOff = !this.mWorkdaysOnly;

                    if (aDate) {
                        aDate = aDate.getInTimezone(this.timezone);
                    }
                    this.showDate(aDate);
                ]]></body>
            </method>
            <method name="getRangeDescription">
                <body><![CDATA[
                    let monthName = cal.formatMonth(this.rangeStartDate.month + 1,
                                                    "calendar", "monthInYear");
                    return calGetString("calendar", "monthInYear", [monthName, this.rangeStartDate.year]);
                 ]]></body>
             </method>
            <method name="moveView">
                <parameter name="aNumber"/>
                <body><![CDATA[
                    let dates = this.getDateList({});
                    this.displayDaysOff = !this.mWorkdaysOnly;

                    if (!aNumber) {
                        let date = now();
                        this.goToDay(date);
                        this.selectedDay = date;
                    } else {
                        // The first few dates in this list are likely in the month
                        // prior to the one actually being shown (since the month
                        // probably doesn't start on a Sunday).  The 7th item must
                        // be in correct month though.
                        let date = dates[6].clone();

                        date.month += aNumber;
                        // Need to store this before we move
                        let oldSelectedDay = this.selectedDay;

                        this.goToDay(date);

                        // Most of the time we want to select the date with the
                        // same day number in the next month
                        let newSelectedDay = oldSelectedDay.clone();
                        newSelectedDay.month += aNumber;
                        // correct for accidental rollover into the next month
                        if ((newSelectedDay.month - aNumber + 12) % 12 != oldSelectedDay.month) {
                            newSelectedDay.month -= 1;
                            newSelectedDay.day = newSelectedDay.endOfMonth.day;
                        }

                        this.selectedDay = newSelectedDay;
                    }
                ]]></body>
            </method>
        </implementation>
    </binding>
</bindings>
