"use strict";
/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// FIXME:
//  - Touch event

/**
 * CSS class names.
 *
 * @enum {string}
 */
var ClassNames = {
    Available: "available",
    CancelButton: "cancel-button",
    ClearButton: "clear-button",
    Day: "day",
    DayLabel: "day-label",
    DayLabelContainer: "day-label-container",
    DaysArea: "days-area",
    DaysAreaContainer: "days-area-container",
    Monday: "monday",
    MonthMode: "month-mode",
    MonthSelector: "month-selector",
    MonthSelectorBox: "month-selector-box",
    MonthSelectorPopup: "month-selector-popup",
    MonthSelectorPopupContents: "month-selector-popup-contents",
    MonthSelectorPopupEntry: "month-selector-popup-entry",
    MonthSelectorWall: "month-selector-wall",
    NoFocusRing: "no-focus-ring",
    NotThisMonth: "not-this-month",
    Selected: "day-selected",
    SelectedMonthYear: "selected-month-year",
    Sunday: "sunday",
    TodayButton: "today-button",
    TodayClearArea: "today-clear-area",
    Unavailable: "unavailable",
    WeekContainer: "week-container",
    WeekColumn: "week-column",
    WeekMode: "week-mode",
    YearMonthArea: "year-month-area",
    YearMonthButton: "year-month-button",
    YearMonthButtonLeft: "year-month-button-left",
    YearMonthButtonRight: "year-month-button-right",
    YearMonthUpper: "year-month-upper"
};

/**
 * @type {Object}
 */
var global = {
    argumentsReceived: false,
    params: null,
    picker: null
};

// ----------------------------------------------------------------
// Utility functions

/**
 * @return {!string} lowercase locale name. e.g. "en-us"
 */
function getLocale() {
    return (global.params.locale || "en-us").toLowerCase();
}

/**
 * @return {!string} lowercase language code. e.g. "en"
 */
function getLanguage() {
    var locale = getLocale();
    var result = locale.match(/^([a-z]+)/);
    if (!result)
        return "en";
    return result[1];
}

/**
 * @param {!number} number
 * @return {!string}
 */
function localizeNumber(number) {
    return window.pagePopupController.localizeNumberString(number);
}

/**
 * @const
 * @type {number}
 */
var ImperialEraLimit = 2087;

/**
 * @param {!number} year
 * @param {!number} month
 * @return {!string}
 */
function formatJapaneseImperialEra(year, month) {
    // We don't show an imperial era if it is greater than 99 becase of space
    // limitation.
    if (year > ImperialEraLimit)
        return "";
    if (year > 1989)
        return "(平成" + localizeNumber(year - 1988) + "年)";
    if (year == 1989)
        return "(平成元年)";
    if (year >= 1927)
        return "(昭和" + localizeNumber(year - 1925) + "年)";
    if (year > 1912)
        return "(大正" + localizeNumber(year - 1911) + "年)";
    if (year == 1912 && month >= 7)
        return "(大正元年)";
    if (year > 1868)
        return "(明治" + localizeNumber(year - 1867) + "年)";
    if (year == 1868)
        return "(明治元年)";
    return "";
}

/**
 * @return {!string}
 */
Month.prototype.toLocaleString = function() {
    if (isNaN(this.year) || isNaN(this.year))
        return "Invalid Month";
    if (getLanguage() == "ja")
        return "" + this.year + "年" + formatJapaneseImperialEra(this.year, this.month) + " " + (this.month + 1) + "月";
    return window.pagePopupController.formatMonth(this.year, this.month);
};

function createUTCDate(year, month, date) {
    var newDate = new Date(0);
    newDate.setUTCFullYear(year);
    newDate.setUTCMonth(month);
    newDate.setUTCDate(date);
    return newDate;
};

/**
 * @param {string} dateString
 * @return {?Day|Week|Month}
 */
function parseDateString(dateString) {
    var month = Month.parse(dateString);
    if (month)
        return month;
    var week = Week.parse(dateString);
    if (week)
        return week;
    return Day.parse(dateString);
}

/**
 * @constructor
 * @param {!number|Day} valueOrDayOrYear
 * @param {!number=} month
 * @param {!number=} date
 */
function Day(valueOrDayOrYear, month, date) {
    var dateObject;
    if (arguments.length == 3)
        dateObject = createUTCDate(valueOrDayOrYear, month, date);
    else if (valueOrDayOrYear instanceof Day)
        dateObject = createUTCDate(valueOrDayOrYear.year, valueOrDayOrYear.month, valueOrDayOrYear.date);
    else
        dateObject = new Date(valueOrDayOrYear);
    this.year = dateObject.getUTCFullYear();    
    this.month = dateObject.getUTCMonth();
    this.date = dateObject.getUTCDate();
};

Day.ISOStringRegExp = /^(\d+)-(\d+)-(\d+)/;

/**
 * @param {!string} str
 * @return {?Month}
 */
Day.parse = function(str) {
    var match = Day.ISOStringRegExp.exec(str);
    if (!match)
        return null;
    var year = parseInt(match[1], 10);
    var month = parseInt(match[2], 10) - 1;
    var date = parseInt(match[3], 10);
    return new Day(year, month, date);
};

/**
 * @param {!Date} date
 * @return {!Day}
 */
Day.createFromDate = function(date) {
    return new Day(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
};

/**
 * @return {!Day}
 */
Day.createFromToday = function() {
    var now = new Date();
    return new Day(now.getFullYear(), now.getMonth(), now.getDate());
};

/**
 * @param {!Day} other
 * @return {!bool}
 */
Day.prototype.equals = function(other) {
    return this.year === other.year && this.month === other.month && this.date === other.date;
};

/**
 * @return {!Day}
 */
Day.prototype.previous = function() {
    return new Day(this.year, this.month, this.date - 1);
};

/**
 * @return {!Day}
 */
Day.prototype.next = function() {
    return new Day(this.year, this.month, this.date + 1);
};

/**
 * @return {!Date}
 */
Day.prototype.startDate = function() {
    return createUTCDate(this.year, this.month, this.date);
};

/**
 * @return {!Date}
 */
Day.prototype.endDate = function() {
    return createUTCDate(this.year, this.month, this.date + 1);
};

/**
 * @return {!number}
 */
Day.prototype.valueOf = function() {
    return this.startDate().getTime();
};

/**
 * @return {!string}
 */
Day.prototype.toString = function() {
    var yearString = String(this.year);
    if (yearString.length < 4)
        yearString = ("000" + yearString).substr(-4, 4);
    return yearString + "-" + ("0" + (this.month + 1)).substr(-2, 2) + "-" + ("0" + this.date).substr(-2, 2);
};

// See WebCore/platform/DateComponents.h.
Day.Minimum = new Day(-62135596800000.0);
Day.Maximum = new Day(8640000000000000.0);
// See WebCore/html/DayInputType.cpp.
Day.DefaultStep = 86400000;
Day.DefaultStepBase = 0;

/**
 * @constructor
 * @param {!number|Week} valueOrWeekOrYear
 * @param {!number=} week
 */
function Week(valueOrWeekOrYear, week) {
    if (arguments.length === 2) {
        this.year = valueOrWeekOrYear;
        this.week = week;
        // Number of years per year is either 52 or 53.
        if (this.week < 1 || (this.week > 52 && this.week > Week.numberOfWeeksInYear(this.year))) {
            var normalizedWeek = Week.createFromDate(this.startDate());
            this.year = normalizedWeek.year;
            this.week = normalizedWeek.week;
        }
    } else if (valueOrWeekOrYear instanceof Week) {
        this.year = valueOrWeekOrYear.year;
        this.week = valueOrWeekOrYear.week;
    } else {
        var week = Week.createFromDate(new Date(valueOrWeekOrYear));
        this.year = week.year;
        this.week = week.week;
    }
}

Week.MillisecondsPerWeek = 7 * 24 * 60 * 60 * 1000;
Week.ISOStringRegExp = /^(\d+)-[wW](\d+)$/;
// See WebCore/platform/DateComponents.h.
Week.Minimum = new Week(1, 1);
Week.Maximum = new Week(275760, 37);
// See WebCore/html/WeekInputType.cpp.
Week.DefaultStep = 604800000;
Week.DefaultStepBase = -259200000;

/**
 * @param {!string} str
 * @return {?Week}
 */
Week.parse = function(str) {
    var match = Week.ISOStringRegExp.exec(str);
    if (!match)
        return null;
    var year = parseInt(match[1], 10);
    var week = parseInt(match[2], 10);
    return new Week(year, week);
};

/**
 * @param {!Date} date
 * @return {!Week}
 */
Week.createFromDate = function(date) {
    var year = date.getUTCFullYear();
    if (year <= Week.Maximum.year && Week.weekOneStartDateForYear(year + 1).getTime() <= date.getTime())
        year++;
    else if (year > 1 && Week.weekOneStartDateForYear(year).getTime() > date.getTime())
        year--;
    var week = 1 + Week._numberOfWeeksSinceDate(Week.weekOneStartDateForYear(year), date);
    return new Week(year, week);
};

/**
 * @return {!Week}
 */
Week.createFromToday = function() {
    var now = new Date();
    return Week.createFromDate(createUTCDate(now.getFullYear(), now.getMonth(), now.getDate()));
};

/**
 * @param {!number} year
 * @return {!Date}
 */
Week.weekOneStartDateForYear = function(year) {
    if (year < 1)
        return createUTCDate(1, 0, 1);
    // The week containing January 4th is week one.
    var yearStartDay = createUTCDate(year, 0, 4).getUTCDay();
    return createUTCDate(year, 0, 4 - (yearStartDay + 6) % 7);
};

/**
 * @param {!number} year
 * @return {!number}
 */
Week.numberOfWeeksInYear = function(year) {
    if (year < 1 || year > Week.Maximum.year)
        return 0;
    else if (year === Week.Maximum.year)
        return Week.Maximum.week;
    return Week._numberOfWeeksSinceDate(Week.weekOneStartDateForYear(year), Week.weekOneStartDateForYear(year + 1));
};

/**
 * @param {!Date} baseDate
 * @param {!Date} date
 * @return {!number}
 */
Week._numberOfWeeksSinceDate = function(baseDate, date) {
    return Math.floor((date.getTime() - baseDate.getTime()) / Week.MillisecondsPerWeek);
};

/**
 * @param {!Week} other
 * @return {!bool}
 */
Week.prototype.equals = function(other) {
    return this.year === other.year && this.week === other.week;
};

/**
 * @return {!Week}
 */
Week.prototype.previous = function() {
    return new Week(this.year, this.week - 1);
};

/**
 * @return {!Week}
 */
Week.prototype.next = function() {
    return new Week(this.year, this.week + 1);
};

/**
 * @return {!Date}
 */
Week.prototype.startDate = function() {
    var weekStartDate = Week.weekOneStartDateForYear(this.year);
    weekStartDate.setUTCDate(weekStartDate.getUTCDate() + (this.week - 1) * 7);
    return weekStartDate;
};

/**
 * @return {!Date}
 */
Week.prototype.endDate = function() {
    if (this.equals(Week.Maximum))
        return Day.Maximum.startDate();
    return this.next().startDate();
};

/**
 * @return {!number}
 */
Week.prototype.valueOf = function() {
    return this.startDate().getTime() - createUTCDate(1970, 0, 1).getTime();
};

/**
 * @return {!string}
 */
Week.prototype.toString = function() {
    var yearString = String(this.year);
    if (yearString.length < 4)
        yearString = ("000" + yearString).substr(-4, 4);
    return yearString + "-W" + ("0" + this.week).substr(-2, 2);
};

/**
 * @constructor
 * @param {!number|Month} valueOrMonthOrYear
 * @param {!number=} month
 */
function Month(valueOrMonthOrYear, month) {
    if (arguments.length == 2) {
        this.year = valueOrMonthOrYear;
        this.month = month;
    } else if (valueOrMonthOrYear instanceof Month) {
        this.year = valueOrMonthOrYear.year;
        this.month = valueOrMonthOrYear.month;
    } else {
        this.year = 1970;
        this.month = valueOrMonthOrYear;
    }
    this.year = this.year + Math.floor(this.month / 12);
    this.month = this.month < 0 ? this.month % 12 + 12 : this.month % 12;
    if (this.year <= 0 || Month.Maximum < this) {
        this.year = NaN;
        this.month = NaN;
    }
};

Month.ISOStringRegExp = /^(\d+)-(\d+)$/;

// See WebCore/platform/DateComponents.h.
Month.Minimum = new Month(1, 0);
Month.Maximum = new Month(275760, 8);
// See WebCore/html/MonthInputType.cpp.
Month.DefaultStep = 1;
Month.DefaultStepBase = 0;

/**
 * @param {!string} str
 * @return {?Month}
 */
Month.parse = function(str) {
    var match = Month.ISOStringRegExp.exec(str);
    if (!match)
        return null;
    var year = parseInt(match[1], 10);
    var month = parseInt(match[2], 10) - 1;
    return new Month(year, month);
};

/**
 * @param {!Date} date
 * @return {!Month}
 */
Month.createFromDate = function(date) {
    return new Month(date.getUTCFullYear(), date.getUTCMonth());
};

/**
 * @return {!Month}
 */
Month.createFromToday = function() {
    var now = new Date();
    return new Month(now.getFullYear(), now.getMonth());
};

/**
 * @param {!Month} other
 * @return {!bool}
 */
Month.prototype.equals = function(other) {
    return this.year === other.year && this.month === other.month;
};

/**
 * @return {!Month}
 */
Month.prototype.previous = function() {
    return new Month(this.year, this.month - 1);
};

/**
 * @return {!Month}
 */
Month.prototype.next = function() {
    return new Month(this.year, this.month + 1);
};

/**
 * @return {!Date}
 */
Month.prototype.startDate = function() {
    return createUTCDate(this.year, this.month, 1);
};

/**
 * @return {!Date}
 */
Month.prototype.endDate = function() {
    if (this.equals(Month.Maximum))
        return Day.Maximum.startDate();
    return this.next().startDate();
};

/**
 * @return {!number}
 */
Month.prototype.valueOf = function() {
    return (this.year - 1970) * 12 + this.month;
};

/**
 * @return {!string}
 */
Month.prototype.toString = function() {
    var yearString = String(this.year);
    if (yearString.length < 4)
        yearString = ("000" + yearString).substr(-4, 4);
    return yearString + "-" + ("0" + (this.month + 1)).substr(-2, 2);
};

// ----------------------------------------------------------------
// Initialization

/**
 * @param {Event} event
 */
function handleMessage(event) {
    if (global.argumentsReceived)
        return;
    global.argumentsReceived = true;
    initialize(JSON.parse(event.data));
}

function handleArgumentsTimeout() {
    if (global.argumentsReceived)
        return;
    var args = {
        dayLabels : ["d1", "d2", "d3", "d4", "d5", "d6", "d7"],
        todayLabel : "Today",
        clearLabel : "Clear",
        cancelLabel : "Cancel",
        currentValue : "",
        weekStartDay : 0,
        step : CalendarPicker.DefaultStepScaleFactor,
        stepBase: CalendarPicker.DefaultStepBase
    };
    initialize(args);
}

/**
 * @param {!Object} config
 * @return {?string} An error message, or null if the argument has no errors.
 */
CalendarPicker.validateConfig = function(config) {
    if (!config.dayLabels)
        return "No dayLabels.";
    if (config.dayLabels.length != 7)
        return "dayLabels is not an array with 7 elements.";
    if (!config.clearLabel)
        return "No clearLabel.";
    if (!config.todayLabel)
        return "No todayLabel.";
    if (config.weekStartDay) {
        if (config.weekStartDay < 0 || config.weekStartDay > 6)
            return "Invalid weekStartDay: " + config.weekStartDay;
    }
    return null;
}

/**
 * @param {!Object} args
 */
function initialize(args) { 
    global.params = args;
    var errorString = CalendarPicker.validateConfig(args);
    if (args.suggestionValues)
        errorString = errorString || SuggestionPicker.validateConfig(args)
    if (errorString) {
        var main = $("main");
        main.textContent = "Internal error: " + errorString;
        resizeWindow(main.offsetWidth, main.offsetHeight);
    } else {
        if (global.params.suggestionValues && global.params.suggestionValues.length)
            openSuggestionPicker();
        else
            openCalendarPicker();
    }
}

function closePicker() {
    if (global.picker)
        global.picker.cleanup();
    var main = $("main");
    main.innerHTML = "";
    main.className = "";
};

function openSuggestionPicker() {
    closePicker();
    global.picker = new SuggestionPicker($("main"), global.params);
};

function openCalendarPicker() {
    closePicker();
    global.picker = new CalendarPicker($("main"), global.params);
};

/**
 * @constructor
 * @param {!Element} element
 * @param {!Object} config
 */
function CalendarPicker(element, config) {
    Picker.call(this, element, config);
    if (this._config.mode === "month") {
        this.selectionConstructor = Month;
        this._daysTable = new MonthPickerDaysTable(this);
        this._element.classList.add(ClassNames.MonthMode);
    } else if (this._config.mode === "week") {
        this.selectionConstructor = Week;
        this._daysTable = new WeekPickerDaysTable(this);
        this._element.classList.add(ClassNames.WeekMode);
    } else {
        this.selectionConstructor = Day;
        this._daysTable = new DaysTable(this);
    }
    this._element.classList.add("calendar-picker");
    this._element.classList.add("preparing");
    this._handleWindowResizeBound = this._handleWindowResize.bind(this);
    window.addEventListener("resize", this._handleWindowResizeBound, false);
    // We assume this._config.min/max are valid dates or months.
    var minimum = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min) : this.selectionConstructor.Minimum;
    var maximum = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max) : this.selectionConstructor.Maximum;
    this._minimumValue = minimum.valueOf();
    this._maximumValue = maximum.valueOf();
    this.step = (typeof this._config.step !== undefined) ? Number(this._config.step) : this.selectionConstructor.DefaultStep;
    this.stepBase = (typeof this._config.stepBase !== "undefined") ? Number(this._config.stepBase) : this.selectionConstructor.DefaultStepBase;
    this._minimumMonth = Month.createFromDate(minimum.startDate());
    this.maximumMonth = Month.createFromDate(maximum.startDate());
    this._currentMonth = new Month(NaN, NaN);
    this._yearMonthController = new YearMonthController(this);
    this._hadKeyEvent = false;
    this._layout();
    var initialSelection = parseDateString(this._config.currentValue);
    if (!initialSelection)
        initialSelection = this.selectionConstructor.createFromToday();
    if (initialSelection.valueOf() < this._minimumValue)
        initialSelection = new this.selectionConstructor(this._minimumValue);
    else if (initialSelection.valueOf() > this._maximumValue)
        initialSelection = new this.selectionConstructor(this._maximumValue);
    this.showMonth(Month.createFromDate(initialSelection.startDate()));
    this._daysTable.selectRangeAndShowEntireRange(initialSelection);
    this.fixWindowSize();
    this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this);
    document.body.addEventListener("keydown", this._handleBodyKeyDownBound, false);
}
CalendarPicker.prototype = Object.create(Picker.prototype);

CalendarPicker.NavigationBehaviour = {
    None: 0,
    Animate: 1 << 0,
    KeepSelectionPosition: 1 << 1
};

CalendarPicker.prototype._handleWindowResize = function() {
    this._element.classList.remove("preparing");
};

CalendarPicker.prototype.cleanup = function() {
    document.body.removeEventListener("keydown", this._handleBodyKeyDownBound, false);
};

CalendarPicker.prototype._layout = function() {
    if (this._config.isCalendarRTL)
        this._element.classList.add("rtl");
    this._yearMonthController.attachTo(this._element);
    this._daysTable.attachTo(this._element);
    this._layoutButtons();
    // DaysTable will have focus but we don't want to show its focus ring until the first key event.
    this._element.classList.add(ClassNames.NoFocusRing);
};

CalendarPicker.prototype.handleToday = function() {
    var today = this.selectionConstructor.createFromToday();
    this._daysTable.selectRangeAndShowEntireRange(today);
    this.submitValue(today.toString());
};

CalendarPicker.prototype.handleClear = function() {
    this.submitValue("");
};

CalendarPicker.prototype.fixWindowSize = function() {
    var yearMonthRightElement = this._element.getElementsByClassName(ClassNames.YearMonthButtonRight)[0];
    var daysAreaElement = this._element.getElementsByClassName(ClassNames.DaysArea)[0];
    var headers = daysAreaElement.getElementsByClassName(ClassNames.DayLabel);
    var maxCellWidth = 0;
    for (var i = 0; i < headers.length; ++i) {
        if (maxCellWidth < headers[i].offsetWidth)
            maxCellWidth = headers[i].offsetWidth;
    }
    var DaysAreaContainerBorder = 1;
    var yearMonthEnd;
    var daysAreaEnd;
    if (global.params.isCalendarRTL) {
        var startOffset = this._element.offsetLeft + this._element.offsetWidth;
        yearMonthEnd = startOffset - yearMonthRightElement.offsetLeft;
        daysAreaEnd = startOffset - (daysAreaElement.offsetLeft + daysAreaElement.offsetWidth) + maxCellWidth * 7 + DaysAreaContainerBorder;
    } else {
        yearMonthEnd = yearMonthRightElement.offsetLeft + yearMonthRightElement.offsetWidth;
        daysAreaEnd = daysAreaElement.offsetLeft + maxCellWidth * 7 + DaysAreaContainerBorder;
    }
    var maxEnd = Math.max(yearMonthEnd, daysAreaEnd);
    var MainPadding = 6; // FIXME: Fix name.
    var MainBorder = 1;
    var desiredBodyWidth = maxEnd + MainPadding + MainBorder;

    var elementHeight = this._element.offsetHeight;
    this._element.style.width = "auto";
    daysAreaElement.style.width = "100%";
    daysAreaElement.style.tableLayout = "fixed";
    this._element.getElementsByClassName(ClassNames.YearMonthUpper)[0].style.display = "-webkit-box";
    this._element.getElementsByClassName(ClassNames.MonthSelectorBox)[0].style.display = "block";
    resizeWindow(desiredBodyWidth, elementHeight);
};

CalendarPicker.prototype._layoutButtons = function() {
    var container = createElement("div", ClassNames.TodayClearArea);
    this.today = createElement("input", ClassNames.TodayButton);
    this.today.disabled = !this.isValidDate(this.selectionConstructor.createFromToday());
    this.today.type = "button";
    this.today.value = this._config.todayLabel;
    this.today.addEventListener("click", this.handleToday.bind(this), false);
    container.appendChild(this.today);
    this.clear = null;
    if (!this._config.required) {
        this.clear = createElement("input", ClassNames.ClearButton);
        this.clear.type = "button";
        this.clear.value = this._config.clearLabel;
        this.clear.addEventListener("click", this.handleClear.bind(this), false);
        container.appendChild(this.clear);
    }
    this._element.appendChild(container);

    this.lastFocusableControl = this.clear || this.today;
};

/**
 * @param {!Month} month
 * @return {!bool}
 */
CalendarPicker.prototype.shouldShowMonth = function(month) {
    return this._minimumMonth.valueOf() <= month.valueOf() && this.maximumMonth.valueOf() >= month.valueOf();
};

/**
 * @param {!Month} month
 * @param {!CalendarPicker.NavigationBehaviour=} navigationBehaviour
 */
CalendarPicker.prototype.showMonth = function(month, navigationBehaviour) {
    if (this._currentMonth.equals(month))
        return;
    else if (month.valueOf() < this._minimumMonth.valueOf())
        month = this._minimumMonth;
    else if (month.valueOf() > this.maximumMonth.valueOf())
        month = this.maximumMonth;
    this._yearMonthController.setMonth(month);
    this._daysTable.navigateToMonth(month, navigationBehaviour || CalendarPicker.NavigationBehaviour.None);
    this._currentMonth = month;
};

/**
 * @return {!Month}
 */
CalendarPicker.prototype.currentMonth = function() {
    return this._currentMonth;
};

// ----------------------------------------------------------------

/**
 * @constructor
 * @param {!CalendarPicker} picker
 */
function YearMonthController(picker) {
    this.picker = picker;
}

/**
 * @param {!Element} element
 */
YearMonthController.prototype.attachTo = function(element) {
    var outerContainer = createElement("div", ClassNames.YearMonthArea);

    var innerContainer = createElement("div", ClassNames.YearMonthUpper);
    outerContainer.appendChild(innerContainer);

    this._attachLeftButtonsTo(innerContainer);

    var box = createElement("div", ClassNames.MonthSelectorBox);
    innerContainer.appendChild(box);
    // We can't use <select> popup in PagePopup.
    this._monthPopup = createElement("div", ClassNames.MonthSelectorPopup);
    this._monthPopup.addEventListener("click", this._handleYearMonthChange.bind(this), false);
    this._monthPopup.addEventListener("keydown", this._handleMonthPopupKey.bind(this), false);
    this._monthPopup.addEventListener("mousemove", this._handleMouseMove.bind(this), false);
    this._updateSelectionOnMouseMove = true;
    this._monthPopup.tabIndex = 0;
    this._monthPopupContents = createElement("div", ClassNames.MonthSelectorPopupContents);
    this._monthPopup.appendChild(this._monthPopupContents);
    box.appendChild(this._monthPopup);
    this._month = createElement("div", ClassNames.MonthSelector);
    this._month.addEventListener("click", this._showPopup.bind(this), false);
    box.appendChild(this._month);

    this._attachRightButtonsTo(innerContainer);
    element.appendChild(outerContainer);

    this._wall = createElement("div", ClassNames.MonthSelectorWall);
    this._wall.addEventListener("click", this._closePopup.bind(this), false);
    element.appendChild(this._wall);

    var month = this.picker.maximumMonth;
    var maxWidth = 0;
    for (var m = 0; m < 12; ++m) {
        this._month.textContent = month.toLocaleString();
        maxWidth = Math.max(maxWidth, this._month.offsetWidth);
        month = month.previous();
    }
    if (getLanguage() == "ja" && ImperialEraLimit < this.picker.maximumMonth.year) {
        for (var m = 0; m < 12; ++m) {
            this._month.textContent = new Month(ImperialEraLimit, m).toLocaleString();
            maxWidth = Math.max(maxWidth, this._month.offsetWidth);
        }
    }
    this._month.style.minWidth = maxWidth + 'px';

    this.picker.firstFocusableControl = this._left2; // FIXME: Should it be this.month?
};

YearMonthController.addTenYearsButtons = false;

/**
 * @param {!Element} parent
 */
YearMonthController.prototype._attachLeftButtonsTo = function(parent) {
    var container = createElement("div", ClassNames.YearMonthButtonLeft);
    parent.appendChild(container);

    if (YearMonthController.addTenYearsButtons) {
        this._left3 = createElement("input", ClassNames.YearMonthButton);
        this._left3.type = "button";
        this._left3.value = "<<<";
        this._left3.addEventListener("click", this._handleButtonClick.bind(this), false);
        container.appendChild(this._left3);
    }

    this._left2 = createElement("input", ClassNames.YearMonthButton);
    this._left2.type = "button";
    this._left2.value = "<<";
    this._left2.addEventListener("click", this._handleButtonClick.bind(this), false);
    container.appendChild(this._left2);

    this._left1 = createElement("input", ClassNames.YearMonthButton);
    this._left1.type = "button";
    this._left1.value = "<";
    this._left1.addEventListener("click", this._handleButtonClick.bind(this), false);
    container.appendChild(this._left1);
};

/**
 * @param {!Element} parent
 */
YearMonthController.prototype._attachRightButtonsTo = function(parent) {
    var container = createElement("div", ClassNames.YearMonthButtonRight);
    parent.appendChild(container);
    this._right1 = createElement("input", ClassNames.YearMonthButton);
    this._right1.type = "button";
    this._right1.value = ">";
    this._right1.addEventListener("click", this._handleButtonClick.bind(this), false);
    container.appendChild(this._right1);

    this._right2 = createElement("input", ClassNames.YearMonthButton);
    this._right2.type = "button";
    this._right2.value = ">>";
    this._right2.addEventListener("click", this._handleButtonClick.bind(this), false);
    container.appendChild(this._right2);

    if (YearMonthController.addTenYearsButtons) {
        this._right3 = createElement("input", ClassNames.YearMonthButton);
        this._right3.type = "button";
        this._right3.value = ">>>";
        this._right3.addEventListener("click", this._handleButtonClick.bind(this), false);
        container.appendChild(this._right3);
    }
};

/**
 * @param {!Month} month
 */
YearMonthController.prototype.setMonth = function(month) {
    var monthValue = month.valueOf();
    if (this._left3)
        this._left3.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 13));
    this._left2.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 2));
    this._left1.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 1));
    this._right1.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 1));
    this._right2.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 2));
    if (this._right3)
        this._left3.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 13));
    this._month.innerText = month.toLocaleString();
    while (this._monthPopupContents.hasChildNodes())
        this._monthPopupContents.removeChild(this._monthPopupContents.firstChild);

    for (var m = monthValue - 6; m <= monthValue + 6; m++) {
        var month = new Month(m);
        if (!this.picker.shouldShowMonth(month))
            continue;
        var option = createElement("div", ClassNames.MonthSelectorPopupEntry, month.toLocaleString());
        option.dataset.value = month.toString();
        this._monthPopupContents.appendChild(option);
        if (m == monthValue)
            option.classList.add(ClassNames.SelectedMonthYear);
    }
};

YearMonthController.prototype._showPopup = function() {
    this._monthPopup.style.display = "block";
    this._monthPopup.style.zIndex = "1000"; // Larger than the days area.
    this._monthPopup.style.left = this._month.offsetLeft + (this._month.offsetWidth - this._monthPopup.offsetWidth) / 2 + "px";
    this._monthPopup.style.top = this._month.offsetTop + this._month.offsetHeight + "px";

    this._wall.style.display = "block";
    this._wall.style.zIndex = "999"; // This should be smaller than the z-index of monthPopup.

    var popupHeight = this._monthPopup.clientHeight;
    var fullHeight = this._monthPopupContents.clientHeight;
    if (fullHeight > popupHeight) {
        var selected = this._getSelection();
        if (selected) {
           var bottom = selected.offsetTop + selected.clientHeight;
           if (bottom > popupHeight)
               this._monthPopup.scrollTop = bottom - popupHeight;
        }
        this._monthPopup.style.webkitPaddingEnd = getScrollbarWidth() + 'px';
    }
    this._monthPopup.focus();
};

YearMonthController.prototype._closePopup = function() {
    this._monthPopup.style.display = "none";
    this._wall.style.display = "none";
    var container = document.querySelector("." + ClassNames.DaysAreaContainer);
    container.focus();
};

/**
 * @return {Element} Selected element in the month-year popup.
 */
YearMonthController.prototype._getSelection = function()
{
    return document.querySelector("." + ClassNames.SelectedMonthYear);
}

/**
 * @param {Event} event
 */
YearMonthController.prototype._handleMouseMove = function(event)
{
    if (!this._updateSelectionOnMouseMove) {
        // Selection update turned off while navigating with keyboard to prevent a mouse
        // move trigged during a scroll from resetting the selection. Automatically
        // rearm control to enable mouse-based selection.
        this._updateSelectionOnMouseMove = true;
    } else {
        var target = event.target;
        var selection = this._getSelection();
        if (target && target != selection && target.classList.contains(ClassNames.MonthSelectorPopupEntry)) {
            if (selection)
                selection.classList.remove(ClassNames.SelectedMonthYear);
            target.classList.add(ClassNames.SelectedMonthYear);
        }
    }
    event.stopPropagation();
    event.preventDefault();
}

/**
 * @param {Event} event
 */
YearMonthController.prototype._handleMonthPopupKey = function(event)
{
    var key = event.keyIdentifier;
    if (key == "Down") {
        var selected = this._getSelection();
        if (selected) {
            var next = selected.nextSibling;
            if (next) {
                selected.classList.remove(ClassNames.SelectedMonthYear);
                next.classList.add(ClassNames.SelectedMonthYear);
                var bottom = next.offsetTop + next.clientHeight;
                if (bottom > this._monthPopup.scrollTop + this._monthPopup.clientHeight) {
                    this._updateSelectionOnMouseMove = false;
                    this._monthPopup.scrollTop = bottom - this._monthPopup.clientHeight;
                }
            }
        }
        event.stopPropagation();
        event.preventDefault();
    } else if (key == "Up") {
        var selected = this._getSelection();
        if (selected) {
            var previous = selected.previousSibling;
            if (previous) {
                selected.classList.remove(ClassNames.SelectedMonthYear);
                previous.classList.add(ClassNames.SelectedMonthYear);
                if (previous.offsetTop < this._monthPopup.scrollTop) {
                    this._updateSelectionOnMouseMove = false;
                    this._monthPopup.scrollTop = previous.offsetTop;
                }
            }
        }
        event.stopPropagation();
        event.preventDefault();
    } else if (key == "U+001B") {
        this._closePopup();
        event.stopPropagation();
        event.preventDefault();
    } else if (key == "Enter") {
        this._handleYearMonthChange();
        event.stopPropagation();
        event.preventDefault();
    }
}

YearMonthController.prototype._handleYearMonthChange = function() {
    this._closePopup();
    var selection = this._getSelection();
    if (!selection)
        return;
    this.picker.showMonth(Month.parse(selection.dataset.value));
};

/**
 * @const
 * @type {number}
 */
YearMonthController.PreviousTenYears = -120;
/**
 * @const
 * @type {number}
 */
YearMonthController.PreviousYear = -12;
/**
 * @const
 * @type {number}
 */
YearMonthController.PreviousMonth = -1;
/**
 * @const
 * @type {number}
 */
YearMonthController.NextMonth = 1;
/**
 * @const
 * @type {number}
 */
YearMonthController.NextYear = 12;
/**
 * @const
 * @type {number}
 */
YearMonthController.NextTenYears = 120;

/**
 * @param {Event} event
 */
YearMonthController.prototype._handleButtonClick = function(event) {
    if (event.target == this._left3)
        this.moveRelatively(YearMonthController.PreviousTenYears);
    else if (event.target == this._left2)
        this.moveRelatively(YearMonthController.PreviousYear);
    else if (event.target == this._left1)
        this.moveRelatively(YearMonthController.PreviousMonth);
    else if (event.target == this._right1)
        this.moveRelatively(YearMonthController.NextMonth)
    else if (event.target == this._right2)
        this.moveRelatively(YearMonthController.NextYear);
    else if (event.target == this._right3)
        this.moveRelatively(YearMonthController.NextTenYears);
    else
        return;
};

/**
 * @param {!number} amount
 */
YearMonthController.prototype.moveRelatively = function(amount) {
    var current = this.picker.currentMonth().valueOf();
    var updated = new Month(current + amount);
    this.picker.showMonth(updated, CalendarPicker.NavigationBehaviour.Animate | CalendarPicker.NavigationBehaviour.KeepSelectionPosition);
};

// ----------------------------------------------------------------

/**
 * @constructor
 * @param {!CalendarPicker} picker
 */
function DaysTable(picker) {
    this.picker = picker;
}

/**
 * @return {!boolean}
 */
DaysTable.prototype._hasSelection = function() {
    return !!this._firstNodeInSelectedRange();
}

/**
 * The number of week lines in the screen.
 * @const
 * @type {number}
 */
DaysTable._Weeks = 6;

/**
 * @param {!Element} element
 */
DaysTable.prototype.attachTo = function(element) {
    this._daysContainer = createElement("table", ClassNames.DaysArea);
    this._daysContainer.addEventListener("click", this._handleDayClick.bind(this), false);
    this._daysContainer.addEventListener("mouseover", this._handleMouseOver.bind(this), false);
    this._daysContainer.addEventListener("mouseout", this._handleMouseOut.bind(this), false);
    this._daysContainer.addEventListener("webkitTransitionEnd", this._moveInDays.bind(this), false);
    var container = createElement("tr", ClassNames.DayLabelContainer);
    var weekStartDay = global.params.weekStartDay || 0;
    container.appendChild(createElement("th", ClassNames.DayLabel + " " + ClassNames.WeekColumn, global.params.weekLabel));
    for (var i = 0; i < 7; i++)
        container.appendChild(createElement("th", ClassNames.DayLabel, global.params.dayLabels[(weekStartDay + i) % 7]));
    this._daysContainer.appendChild(container);
    this._days = [];
    this._weekNumbers = [];
    for (var w = 0; w < DaysTable._Weeks; w++) {
        container = createElement("tr", ClassNames.WeekContainer);
        var week = [];
        var weekNumberNode = createElement("td", ClassNames.Day + " " + ClassNames.WeekColumn, " ");
        weekNumberNode.dataset.positionX = -1;
        weekNumberNode.dataset.positionY = w;
        this._weekNumbers.push(weekNumberNode);
        container.appendChild(weekNumberNode);
        for (var d = 0; d < 7; d++) {
            var day = createElement("td", ClassNames.Day, " ");
            day.setAttribute("data-position-x", String(d));
            day.setAttribute("data-position-y", String(w));
            week.push(day);
            container.appendChild(day);
        }
        this._days.push(week);
        this._daysContainer.appendChild(container);
    }
    container = createElement("div", ClassNames.DaysAreaContainer);
    container.appendChild(this._daysContainer);
    container.tabIndex = 0;
    container.addEventListener("keydown", this._handleKey.bind(this), false);
    element.appendChild(container);

    container.focus();
};

/**
 * @param {!number} value
 * @return {!boolean}
 */
CalendarPicker.prototype._stepMismatch = function(value) {
    var nextAllowedValue = Math.ceil((value - this.stepBase) / this.step) * this.step + this.stepBase;
    return nextAllowedValue >= value + this.selectionConstructor.DefaultStep
}

/**
 * @param {!number} value
 * @return {!boolean}
 */
CalendarPicker.prototype._outOfRange = function(value) {
    return value < this._minimumValue || value > this._maximumValue;
}

/**
 * @param {!Month|Day} range
 * @return {!boolean}
 */
CalendarPicker.prototype.isValidDate = function(range) {
    var value = range.valueOf();
    return !this._outOfRange(value) && !this._stepMismatch(value);
}

/**
 * @param {!Month} month
 */
DaysTable.prototype._renderMonth = function(month) {
    var dayIterator = month.startDate();
    var monthStartDay = dayIterator.getUTCDay();
    var weekStartDay = global.params.weekStartDay || 0;
    var startOffset = weekStartDay - monthStartDay;
    if (startOffset >= 0)
        startOffset -= 7;
    dayIterator.setUTCDate(startOffset + 1);
    var mondayOffset = (8 - weekStartDay) % 7;
    var sundayOffset = weekStartDay % 7;
    for (var w = 0; w < DaysTable._Weeks; w++) {
        for (var d = 0; d < 7; d++) {
            var iterMonth = Month.createFromDate(dayIterator);
            var iterWeek = Week.createFromDate(dayIterator);
            var time = dayIterator.getTime();
            var element = this._days[w][d];
            element.innerText = localizeNumber(dayIterator.getUTCDate());
            element.className = ClassNames.Day;
            element.dataset.submitValue = Day.createFromDate(dayIterator).toString();
            element.dataset.weekValue = iterWeek.toString();
            element.dataset.monthValue = iterMonth.toString();
            if (isNaN(time)) {
                element.innerText = "-";
                element.classList.add(ClassNames.Unavailable);
            } else if (!this.picker.isValidDate(this._rangeForNode(element)))
                element.classList.add(ClassNames.Unavailable);
            else if (!iterMonth.equals(month)) {
                element.classList.add(ClassNames.Available);
                element.classList.add(ClassNames.NotThisMonth);
            } else
                element.classList.add(ClassNames.Available);
            if (d === mondayOffset) {
                element.classList.add(ClassNames.Monday);
                if (this._weekNumbers[w]) {
                    this._weekNumbers[w].dataset.weekValue = iterWeek.toString();
                    this._weekNumbers[w].innerText = localizeNumber(iterWeek.week);
                    if (element.classList.contains(ClassNames.Available))
                        this._weekNumbers[w].classList.add(ClassNames.Available);
                    else
                        this._weekNumbers[w].classList.add(ClassNames.Unavailable);
                }
            } else if (d === sundayOffset)
                element.classList.add(ClassNames.Sunday);
            dayIterator.setUTCDate(dayIterator.getUTCDate() + 1);
        }
    }
};

/**
 * @param {!Month} month
 * @param {!CalendarPicker.NavigationBehaviour} navigationBehaviour
 */
DaysTable.prototype.navigateToMonth = function(month, navigationBehaviour) {
    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
    if (navigationBehaviour & CalendarPicker.NavigationBehaviour.Animate)
        this._startMoveInAnimation(month);
    this._renderMonth(month);
    if (navigationBehaviour & CalendarPicker.NavigationBehaviour.KeepSelectionPosition && firstNodeInSelectedRange) {
        var x = parseInt(firstNodeInSelectedRange.dataset.positionX, 10);
        var y = parseInt(firstNodeInSelectedRange.dataset.positionY, 10);
        this._selectRangeAtPosition(x, y);
    }
};

/**
 * @param {!Month} month
 */
DaysTable.prototype._startMoveInAnimation = function(month) {
    var daysStyle = this._daysContainer.style;
    daysStyle.position = "relative";
    daysStyle.webkitTransition = "left 0.1s ease";
    daysStyle.left = (this.picker.currentMonth().valueOf() > month.valueOf() ? "" : "-") + this._daysContainer.offsetWidth + "px";
};

DaysTable.prototype._moveInDays = function() {
    var daysStyle = this._daysContainer.style;
    if (daysStyle.left == "0px")
        return;
    daysStyle.webkitTransition = "";
    daysStyle.left = (daysStyle.left.charAt(0) == "-" ? "" : "-") + this._daysContainer.offsetWidth + "px";
    this._daysContainer.offsetLeft; // Force to layout.
    daysStyle.webkitTransition = "left 0.1s ease";
    daysStyle.left = "0px";
};

/**
 * @param {!Day} day
 */
DaysTable.prototype._markRangeAsSelected = function(day) {
    var dateString = day.toString();
    for (var w = 0; w < DaysTable._Weeks; w++) {
        for (var d = 0; d < 7; d++) {
            if (this._days[w][d].dataset.submitValue == dateString) {
                this._days[w][d].classList.add(ClassNames.Selected);
                break;
            }
        }
    }
};

/**
 * @param {!Day} day
 */
DaysTable.prototype.selectRange = function(day) {
    this._deselect();
    if (this.startDate() > day.startDate() || this.endDate() < day.endDate())
        this.picker.showMonth(Month.createFromDate(day.startDate()), CalendarPicker.NavigationBehaviour.Animate);
    this._markRangeAsSelected(day);
};

/**
 * @param {!Day} day
 */
DaysTable.prototype.selectRangeAndShowEntireRange = function(day) {
    this.selectRange(day);
};

/**
 * @param {!Element} dayNode
 */
DaysTable.prototype._selectRangeContainingNode = function(dayNode) {
    var range = this._rangeForNode(dayNode);
    if (!range)
        return;
    this.selectRange(range);
};

/**
 * @param {!Element} dayNode
 * @return {?Day}
 */
DaysTable.prototype._rangeForNode = function(dayNode) {
    if (!dayNode)
        return null;
    return Day.parse(dayNode.dataset.submitValue);
};

/**
 * @return {!Date}
 */
DaysTable.prototype.startDate = function() {
    return Day.parse(this._days[0][0].dataset.submitValue).startDate();
};

/**
 * @return {!Date}
 */
DaysTable.prototype.endDate = function() {
    return Day.parse(this._days[DaysTable._Weeks - 1][7 - 1].dataset.submitValue).endDate();
};

/**
 * @param {!number} x
 * @param {!number} y
 */
DaysTable.prototype._selectRangeAtPosition = function(x, y) {
    var node = x === -1 ? this._weekNumbers[y] : this._days[y][x];
    this._selectRangeContainingNode(node);
};

/**
 * @return {!Element}
 */
DaysTable.prototype._firstNodeInSelectedRange = function() {
    return this._daysContainer.getElementsByClassName(ClassNames.Selected)[0];
};

DaysTable.prototype._deselect = function() {
    var selectedNodes = this._daysContainer.getElementsByClassName(ClassNames.Selected);
    for (var node = selectedNodes[0]; node; node = selectedNodes[0])
        node.classList.remove(ClassNames.Selected);
};

/**
 * @param {!CalendarPicker.NavigationBehaviour=} navigationBehaviour
 * @return {!boolean}
 */
DaysTable.prototype._maybeSetPreviousMonth = function(navigationBehaviour) {
    if (typeof navigationBehaviour === "undefined")
        navigationBehaviour = CalendarPicker.NavigationBehaviour.Animate;
    var previousMonth = this.picker.currentMonth().previous();
    if (!this.picker.shouldShowMonth(previousMonth))
        return false;
    this.picker.showMonth(previousMonth, navigationBehaviour);
    return true;
};

/**
 * @param {!CalendarPicker.NavigationBehaviour=} navigationBehaviour
 * @return {!boolean}
 */
DaysTable.prototype._maybeSetNextMonth = function(navigationBehaviour) {
    if (typeof navigationBehaviour === "undefined")
        navigationBehaviour = CalendarPicker.NavigationBehaviour.Animate;
    var nextMonth = this.picker.currentMonth().next();
    if (!this.picker.shouldShowMonth(nextMonth))
        return false;
    this.picker.showMonth(nextMonth, navigationBehaviour);
    return true;
};

/**
 * @param {Event} event
 */
DaysTable.prototype._handleDayClick = function(event) {
    if (event.target.classList.contains(ClassNames.Available))
        this.picker.submitValue(this._rangeForNode(event.target).toString());
};

/**
 * @param {Event} event
 */
DaysTable.prototype._handleMouseOver = function(event) {
    var node = event.target;
    if (node.classList.contains(ClassNames.Selected))
        return;
    this._selectRangeContainingNode(node);
};

/**
 * @param {Event} event
 */
DaysTable.prototype._handleMouseOut = function(event) {
    this._deselect();
};

/**
 * @param {Event} event
 */
DaysTable.prototype._handleKey = function(event) {
    this.picker.maybeUpdateFocusStyle();
    var x = -1;
    var y = -1;
    var key = event.keyIdentifier;
    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
    if (firstNodeInSelectedRange) {
        x = parseInt(firstNodeInSelectedRange.dataset.positionX, 10);
        y = parseInt(firstNodeInSelectedRange.dataset.positionY, 10);
    }
    if (!this._hasSelection() && (key == "Left" || key == "Up" || key == "Right" || key == "Down")) {
        // Put the selection on a center cell.
        this.updateSelection(event, 3, Math.floor(DaysTable._Weeks / 2 - 1));
        return;
    }

    if (key == (global.params.isCalendarRTL ? "Right" : "Left")) {
        if (x == 0) {
            if (y == 0) {
                if (!this._maybeSetPreviousMonth())
                    return;
                y = DaysTable._Weeks - 1;
            } else
                y--;
            x = 6;
        } else
            x--;
        this.updateSelection(event, x, y);

    } else if (key == "Up") {
        if (y == 0) {
            if (!this._maybeSetPreviousMonth())
                return;
            y = DaysTable._Weeks - 1;
        } else
            y--;
        this.updateSelection(event, x, y);

    } else if (key == (global.params.isCalendarRTL ? "Left" : "Right")) {
        if (x == 6) {
            if (y == DaysTable._Weeks - 1) {
                if (!this._maybeSetNextMonth())
                    return;
                y = 0;
            } else
                y++;
            x = 0;
        } else
            x++;
        this.updateSelection(event, x, y);

    } else if (key == "Down") {
        if (y == DaysTable._Weeks - 1) {
            if (!this._maybeSetNextMonth())
                return;
            y = 0;
        } else
            y++;
        this.updateSelection(event, x, y);

    } else if (key == "PageUp") {
        if (!this._maybeSetPreviousMonth())
            return;
        this.updateSelection(event, x, y);

    } else if (key == "PageDown") {
        if (!this._maybeSetNextMonth())
            return;
        this.updateSelection(event, x, y);

    } else if (this._hasSelection() && key == "Enter") {
        var dayNode = this._days[y][x];
        if (dayNode.classList.contains(ClassNames.Available)) {
            this.picker.submitValue(dayNode.dataset.submitValue);
            event.stopPropagation();
        }

    } else if (key == "U+0054") { // 't'
        this.selectRangeAndShowEntireRange(Day.createFromToday());
        event.stopPropagation();
        event.preventDefault();
    }
};

/**
 * @param {Event} event
 * @param {!number} x
 * @param {!number} y
 */
DaysTable.prototype.updateSelection = function(event, x, y) {
    this._selectRangeAtPosition(x, y);
    event.stopPropagation();
    event.preventDefault();
};

/**
 * @constructor
 * @param{!CalendarPicker} picker
 */
function MonthPickerDaysTable(picker) {
    DaysTable.call(this, picker);
}
MonthPickerDaysTable.prototype = Object.create(DaysTable.prototype);

/**
 * @param {!Month} month
 * @param {!CalendarPicker.NavigationBehaviour} navigationBehaviour
 */
MonthPickerDaysTable.prototype.navigateToMonth = function(month, navigationBehaviour) {
    var hadSelection = this._hasSelection();
    if (navigationBehaviour & CalendarPicker.NavigationBehaviour.Animate)
        this._startMoveInAnimation(month);
    this._renderMonth(month);
    if (navigationBehaviour & CalendarPicker.NavigationBehaviour.KeepSelectionPosition && hadSelection)
        this.selectRange(month);
};

/**
 * @param {!Month} month
 */
MonthPickerDaysTable.prototype._markRangeAsSelected = function(month) {
    var monthString = month.toString();
    for (var w = 0; w < DaysTable._Weeks; w++) {
        for (var d = 0; d < 7; d++) {
            if (this._days[w][d].dataset.monthValue == monthString) {
                this._days[w][d].classList.add(ClassNames.Selected);
            }
        }
    }
};

/**
 * @param {!Month} month
 */
MonthPickerDaysTable.prototype.selectRange = function(month) {
    this._deselect();
    if (this.startDate() >= month.endDate() || this.endDate() <= month.startDate())
        this.picker.showMonth(month, CalendarPicker.NavigationBehaviour.Animate);
    this._markRangeAsSelected(month);
};

/**
 * @param {!Month} month
 */
MonthPickerDaysTable.prototype.selectRangeAndShowEntireRange = function(month) {
    this._deselect();
    this.picker.showMonth(month, CalendarPicker.NavigationBehaviour.Animate);
    this._markRangeAsSelected(month);
};

/**
 * @param {!Element} dayNode
 * @return {?Month}
 */
MonthPickerDaysTable.prototype._rangeForNode = function(dayNode) {
    if (!dayNode)
        return null;
    return Month.parse(dayNode.dataset.monthValue);
};

/**
 * @param {Event} event
 */
MonthPickerDaysTable.prototype._handleKey = function(event) {
    this.picker.maybeUpdateFocusStyle();
    var key = event.keyIdentifier;
    var eventHandled = false;
    var currentMonth = this.picker.currentMonth();
    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
    var selectedMonth = this._rangeForNode(firstNodeInSelectedRange);
    if (!firstNodeInSelectedRange
        && (key == "Right" || key == "Left" || key == "Up" || key == "Down" || key == "PageUp" || key == "PageDown")) {
        this.selectRange(currentMonth);
        eventHandled = true;
    } else if (key == (global.params.isCalendarRTL ? "Right" : "Left") || key == "Up" || key == "PageUp") {
        if (selectedMonth.valueOf() > currentMonth.valueOf())
            this.selectRangeAndShowEntireRange(currentMonth);
        else
            this.selectRangeAndShowEntireRange(currentMonth.previous());
        eventHandled = true;
    } else if (key == (global.params.isCalendarRTL ? "Left" : "Right") || key == "Down" || key == "PageDown") {
        if (selectedMonth.valueOf() < currentMonth.valueOf())
            this.selectRangeAndShowEntireRange(currentMonth);
        else
            this.selectRangeAndShowEntireRange(currentMonth.next());
        eventHandled = true;
    } else if (selectedMonth && key == "Enter") {
        if (firstNodeInSelectedRange.classList.contains(ClassNames.Available)) {
            this.picker.submitValue(selectedMonth.toString());
            eventHandled = true;
        }
    } else if (key == "U+0054") { // 't'
        this.selectRangeAndShowEntireRange(Month.createFromToday());
        eventHandled = true;
    }
    if (eventHandled) {
        event.stopPropagation();
        event.preventDefault();
    }
};

/**
 * @constructor
 * @param{!CalendarPicker} picker
 */
function WeekPickerDaysTable(picker) {
    DaysTable.call(this, picker);
}
WeekPickerDaysTable.prototype = Object.create(DaysTable.prototype);

/**
 * @param {!Week} week
 */
WeekPickerDaysTable.prototype._markRangeAsSelected = function(week) {
    var weekString = week.toString();
    for (var w = 0; w < DaysTable._Weeks; w++) {
        for (var d = 0; d < 7; d++) {
            if (this._days[w][d].dataset.weekValue == weekString) {
                this._days[w][d].classList.add(ClassNames.Selected);
            }
        }
    }
    for (var i = 0; i < this._weekNumbers.length; ++i) {
        if (this._weekNumbers[i].dataset.weekValue === weekString) {
            this._weekNumbers[i].classList.add(ClassNames.Selected);
            break;
        }
    }
};

/**
 * @param {!Week} week
 */
WeekPickerDaysTable.prototype.selectRange = function(week) {
    this._deselect();
    var weekStartDate = week.startDate();
    var weekEndDate = week.endDate();
    if (this.startDate() >= weekEndDate)
        this.picker.showMonth(Month.createFromDate(weekEndDate), CalendarPicker.NavigationBehaviour.Animate);
    else if (this.endDate() <= weekStartDate)
        this.picker.showMonth(Month.createFromDate(weekStartDate), CalendarPicker.NavigationBehaviour.Animate);
    this._markRangeAsSelected(week);
};

/**
 * @param {!Week} week
 */
WeekPickerDaysTable.prototype.selectRangeAndShowEntireRange = function(week) {
    this._deselect();
    var weekStartDate = week.startDate();
    var weekEndDate = week.endDate();
    if (this.startDate() > weekStartDate)
        this.picker.showMonth(Month.createFromDate(weekStartDate), CalendarPicker.NavigationBehaviour.Animate);
    else if (this.endDate() < weekEndDate)
        this.picker.showMonth(Month.createFromDate(weekEndDate), CalendarPicker.NavigationBehaviour.Animate);
    this._markRangeAsSelected(week);
};

/**
 * @param {!Element} dayNode
 * @return {?Week}
 */
WeekPickerDaysTable.prototype._rangeForNode = function(dayNode) {
    if (!dayNode)
        return null;
    return Week.parse(dayNode.dataset.weekValue);
};

/**
 * @param {!Event} event
 */
WeekPickerDaysTable.prototype._handleKey = function(event) {
    this.picker.maybeUpdateFocusStyle();
    var key = event.keyIdentifier;
    var eventHandled = false;
    var currentMonth = this.picker.currentMonth();
    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
    var selectedWeek = this._rangeForNode(firstNodeInSelectedRange);
    if (!firstNodeInSelectedRange
        && (key == "Right" || key == "Left" || key == "Up" || key == "Down" || key == "PageUp" || key == "PageDown")) {
        // Put the selection on a center cell.
        this._selectRangeAtPosition(3, Math.floor(DaysTable._Weeks / 2 - 1));
    } else if (key == (global.params.isCalendarRTL ? "Right" : "Left") || key == "Up") {
        this.selectRangeAndShowEntireRange(selectedWeek.previous());
        eventHandled = true;
    } else if (key == (global.params.isCalendarRTL ? "Left" : "Right") || key == "Down") {
        this.selectRangeAndShowEntireRange(selectedWeek.next());
        eventHandled = true;
    } else if (key == "PageUp") {
        if (!this._maybeSetPreviousMonth(CalendarPicker.NavigationBehaviour.Animate | CalendarPicker.NavigationBehaviour.KeepSelectionPosition))
            return;
        eventHandled = true;
    } else if (key == "PageDown") {
        if (!this._maybeSetNextMonth(CalendarPicker.NavigationBehaviour.Animate | CalendarPicker.NavigationBehaviour.KeepSelectionPosition))
            return;
        eventHandled = true;
    } else if (selectedWeek && key == "Enter") {
        if (firstNodeInSelectedRange.classList.contains(ClassNames.Available)) {
            this.picker.submitValue(selectedWeek.toString());
            eventHandled = true;
        }
    } else if (key == "U+0054") { // 't'
        this.selectRangeAndShowEntireRange(Week.createFromToday());
        eventHandled = true;
    }
    if (eventHandled) {
        event.stopPropagation();
        event.preventDefault();
    }
};

/**
 * @param {!Event} event
 */
CalendarPicker.prototype._handleBodyKeyDown = function(event) {
    this.maybeUpdateFocusStyle();
    var key = event.keyIdentifier;
    if (key == "U+0009") {
        if (!event.shiftKey && document.activeElement == this.lastFocusableControl) {
            event.stopPropagation();
            event.preventDefault();
            this.firstFocusableControl.focus();
        } else if (event.shiftKey && document.activeElement == this.firstFocusableControl) {
            event.stopPropagation();
            event.preventDefault();
            this.lastFocusableControl.focus();
        }
    } else if (key == "U+004D") { // 'm'
        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousMonth : YearMonthController.NextMonth);
    } else if (key == "U+0059") { // 'y'
        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousYear : YearMonthController.NextYear);
    } else if (key == "U+0044") { // 'd'
        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousTenYears : YearMonthController.NextTenYears);
    } else if (key == "U+001B") // ESC
        this.handleCancel();
}

CalendarPicker.prototype.maybeUpdateFocusStyle = function() {
    if (this._hadKeyEvent)
        return;
    this._hadKeyEvent = true;
    this._element.classList.remove(ClassNames.NoFocusRing);
}

if (window.dialogArguments) {
    initialize(dialogArguments);
} else {
    window.addEventListener("message", handleMessage, false);
    window.setTimeout(handleArgumentsTimeout, 1000);
}
