"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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

/**
 * @constructor
 * @param {!Element} element
 * @param {!Object} config
 */
function SuggestionPicker(element, config) {
    Picker.call(this, element, config);
    this._isFocusByMouse = false;
    this._containerElement = null;
    this._setColors();
    this._layout();
    this._fixWindowSize();
    this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this);
    document.body.addEventListener("keydown", this._handleBodyKeyDownBound);
    this._element.addEventListener("mouseout", this._handleMouseOut.bind(this), false);
};
SuggestionPicker.prototype = Object.create(Picker.prototype);

SuggestionPicker.NumberOfVisibleEntries = 20;

// An entry needs to be at least this many pixels visible for it to be a visible entry.
SuggestionPicker.VisibleEntryThresholdHeight = 4;

SuggestionPicker.ActionNames = {
    OpenCalendarPicker: "openCalendarPicker"
};

SuggestionPicker.ListEntryClass = "suggestion-list-entry";

SuggestionPicker.validateConfig = function(config) {
    if (config.showOtherDateEntry && !config.otherDateLabel)
        return "No otherDateLabel.";
    if (config.suggestionHighlightColor && !config.suggestionHighlightColor)
        return "No suggestionHighlightColor.";
    if (config.suggestionHighlightTextColor && !config.suggestionHighlightTextColor)
        return "No suggestionHighlightTextColor.";
    if (config.suggestionValues.length !== config.localizedSuggestionValues.length)
        return "localizedSuggestionValues.length must equal suggestionValues.length.";
    if (config.suggestionValues.length !== config.suggestionLabels.length)
        return "suggestionLabels.length must equal suggestionValues.length.";
    if (typeof config.inputWidth === "undefined")
        return "No inputWidth.";
    return null;
};

SuggestionPicker.prototype._setColors = function() {
    var text = "." + SuggestionPicker.ListEntryClass + ":focus {\
        background-color: " + this._config.suggestionHighlightColor + ";\
        color: " + this._config.suggestionHighlightTextColor + "; }";
    text += "." + SuggestionPicker.ListEntryClass + ":focus .label { color: " + this._config.suggestionHighlightTextColor + "; }";
    document.head.appendChild(createElement("style", null, text));
};

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

/**
 * @param {!string} title
 * @param {!string} label
 * @param {!string} value
 * @return {!Element}
 */
SuggestionPicker.prototype._createSuggestionEntryElement = function(title, label, value) {
    var entryElement = createElement("li", SuggestionPicker.ListEntryClass);
    entryElement.tabIndex = 0;
    entryElement.dataset.value = value;
    var content = createElement("span", "content");
    entryElement.appendChild(content);
    var titleElement = createElement("span", "title", title);
    content.appendChild(titleElement);
    if (label) {
        var labelElement = createElement("span", "label", label);
        content.appendChild(labelElement);
    }
    entryElement.addEventListener("mouseover", this._handleEntryMouseOver.bind(this), false);
    return entryElement;
};

/**
 * @param {!string} title
 * @param {!string} actionName
 * @return {!Element}
 */
SuggestionPicker.prototype._createActionEntryElement = function(title, actionName) {
    var entryElement = createElement("li", SuggestionPicker.ListEntryClass);
    entryElement.tabIndex = 0;
    entryElement.dataset.action = actionName;
    var content = createElement("span", "content");
    entryElement.appendChild(content);
    var titleElement = createElement("span", "title", title);
    content.appendChild(titleElement);
    entryElement.addEventListener("mouseover", this._handleEntryMouseOver.bind(this), false);
    return entryElement;
};

/**
* @return {!number}
*/
SuggestionPicker.prototype._measureMaxContentWidth = function() {
    // To measure the required width, we first set the class to "measuring-width" which
    // left aligns all the content including label.
    this._containerElement.classList.add("measuring-width");
    var maxContentWidth = 0;
    var contentElements = this._containerElement.getElementsByClassName("content");
    for (var i=0; i < contentElements.length; ++i) {
        maxContentWidth = Math.max(maxContentWidth, contentElements[i].offsetWidth);
    }
    this._containerElement.classList.remove("measuring-width");
    return maxContentWidth;
};

SuggestionPicker.prototype._fixWindowSize = function() {
    var ListBorder = 2;
    var desiredWindowWidth = this._measureMaxContentWidth() + ListBorder;
    if (typeof this._config.inputWidth === "number")
        desiredWindowWidth = Math.max(this._config.inputWidth, desiredWindowWidth);
    var totalHeight = ListBorder;
    var maxHeight = 0;
    var entryCount = 0;
    for (var i = 0; i < this._containerElement.childNodes.length; ++i) {
        var node = this._containerElement.childNodes[i];
        if (node.classList.contains(SuggestionPicker.ListEntryClass))
            entryCount++;
        totalHeight += node.offsetHeight;
        if (maxHeight === 0 && entryCount == SuggestionPicker.NumberOfVisibleEntries)
            maxHeight = totalHeight;
    }
    var desiredWindowHeight = totalHeight;
    if (maxHeight !== 0 && totalHeight > maxHeight) {
        this._containerElement.style.maxHeight = (maxHeight - ListBorder) + "px";
        desiredWindowWidth += getScrollbarWidth();
        desiredWindowHeight = maxHeight;
        this._containerElement.style.overflowY = "scroll";
    }

    var windowRect = adjustWindowRect(desiredWindowWidth, desiredWindowHeight, desiredWindowWidth, 0);
    this._containerElement.style.height = (windowRect.height - ListBorder) + "px";
    setWindowRect(windowRect);
};

SuggestionPicker.prototype._layout = function() {
    if (this._config.isRTL)
        this._element.classList.add("rtl");
    if (this._config.isLocaleRTL)
        this._element.classList.add("locale-rtl");
    this._containerElement = createElement("ul", "suggestion-list");
    this._containerElement.addEventListener("click", this._handleEntryClick.bind(this), false);
    for (var i = 0; i < this._config.suggestionValues.length; ++i) {
        this._containerElement.appendChild(this._createSuggestionEntryElement(this._config.localizedSuggestionValues[i], this._config.suggestionLabels[i], this._config.suggestionValues[i]));
    }
    if (this._config.showOtherDateEntry) {
        // Add separator
        var separator = createElement("div", "separator");
        this._containerElement.appendChild(separator);

        // Add "Other..." entry
        var otherEntry = this._createActionEntryElement(this._config.otherDateLabel, SuggestionPicker.ActionNames.OpenCalendarPicker);
        this._containerElement.appendChild(otherEntry);
    }
    this._element.appendChild(this._containerElement);
};

/**
 * @param {!Element} entry
 */
SuggestionPicker.prototype.selectEntry = function(entry) {
    if (typeof entry.dataset.value !== "undefined") {
        this.submitValue(entry.dataset.value);
    } else if (entry.dataset.action === SuggestionPicker.ActionNames.OpenCalendarPicker) {
        window.addEventListener("didHide", SuggestionPicker._handleWindowDidHide, false);
        hideWindow();
    }
};

SuggestionPicker._handleWindowDidHide = function() {
    openCalendarPicker();
    window.removeEventListener("didHide", SuggestionPicker._handleWindowDidHide);
};

/**
 * @param {!Event} event
 */
SuggestionPicker.prototype._handleEntryClick = function(event) {
    var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass);
    if (!entry)
        return;
    this.selectEntry(entry);
    event.preventDefault();
};

/**
 * @return {?Element}
 */
SuggestionPicker.prototype._findFirstVisibleEntry = function() {
    var scrollTop = this._containerElement.scrollTop;
    var childNodes = this._containerElement.childNodes;
    for (var i = 0; i < childNodes.length; ++i) {
        var node = childNodes[i];
        if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass))
            continue;
        if (node.offsetTop + node.offsetHeight - scrollTop > SuggestionPicker.VisibleEntryThresholdHeight)
            return node;
    }
    return null;
};

/**
 * @return {?Element}
 */
SuggestionPicker.prototype._findLastVisibleEntry = function() {
    var scrollBottom = this._containerElement.scrollTop + this._containerElement.offsetHeight;
    var childNodes = this._containerElement.childNodes;
    for (var i = childNodes.length - 1; i >= 0; --i){
        var node = childNodes[i];
        if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass))
            continue;
        if (scrollBottom - node.offsetTop > SuggestionPicker.VisibleEntryThresholdHeight)
            return node;
    }
    return null;
};

/**
 * @param {!Event} event
 */
SuggestionPicker.prototype._handleBodyKeyDown = function(event) {
    var eventHandled = false;
    var key = event.keyIdentifier;
    if (key === "U+001B") { // ESC
        this.handleCancel();
        eventHandled = true;
    } else if (key == "Up") {
        if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) {
            for (var node = document.activeElement.previousElementSibling; node; node = node.previousElementSibling) {
                if (node.classList.contains(SuggestionPicker.ListEntryClass)) {
                    this._isFocusByMouse = false;
                    node.focus();
                    break;
                }
            }
        } else {
            this._element.querySelector("." + SuggestionPicker.ListEntryClass + ":last-child").focus();
        }
        eventHandled = true;
    } else if (key == "Down") {
        if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) {
            for (var node = document.activeElement.nextElementSibling; node; node = node.nextElementSibling) {
                if (node.classList.contains(SuggestionPicker.ListEntryClass)) {
                    this._isFocusByMouse = false;
                    node.focus();
                    break;
                }
            }
        } else {
            this._element.querySelector("." + SuggestionPicker.ListEntryClass + ":first-child").focus();
        }
        eventHandled = true;
    } else if (key === "Enter") {
        this.selectEntry(document.activeElement);
        eventHandled = true;
    } else if (key === "PageUp") {
        this._containerElement.scrollTop -= this._containerElement.clientHeight;
        // Scrolling causes mouseover event to be called and that tries to move the focus too.
        // To prevent flickering we won't focus if the current focus was caused by the mouse.
        if (!this._isFocusByMouse)
            this._findFirstVisibleEntry().focus();
        eventHandled = true;
    } else if (key === "PageDown") {
        this._containerElement.scrollTop += this._containerElement.clientHeight;
        if (!this._isFocusByMouse)
            this._findLastVisibleEntry().focus();
        eventHandled = true;
    }
    if (eventHandled)
        event.preventDefault();
};

/**
 * @param {!Event} event
 */
SuggestionPicker.prototype._handleEntryMouseOver = function(event) {
    var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass);
    if (!entry)
        return;
    this._isFocusByMouse = true;
    entry.focus();
    event.preventDefault();
};

/**
 * @param {!Event} event
 */
SuggestionPicker.prototype._handleMouseOut = function(event) {
    if (!document.activeElement.classList.contains(SuggestionPicker.ListEntryClass))
        return;
    this._isFocusByMouse = false;
    document.activeElement.blur();
    event.preventDefault();
};
