// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// How long to wait to open submenu when mouse hovers.
var SUBMENU_OPEN_DELAY_MS = 200;
// How long to wait to close submenu when mouse left.
var SUBMENU_CLOSE_DELAY_MS = 500;
// Scroll repeat interval.
var SCROLL_INTERVAL_MS = 20;
// Scrolling amount in pixel.
var SCROLL_TICK_PX = 4;
// Regular expression to match/find mnemonic key.
var MNEMONIC_REGEXP = /([^&]*)&(.)(.*)/;

var localStrings = new LocalStrings();

/**
 * Sends 'activate' WebUI message.
 * @param {number} index The index of menu item to activate in menu model.
 * @param {string} mode The activation mode, one of 'close_and_activate', or
 *    'activate_no_close'.
 * TODO(oshima): change these string to enum numbers once it becomes possible
 * to pass number to C++.
 */
function sendActivate(index, mode) {
  chrome.send('activate', [String(index), mode]);
}

/**
 * MenuItem class.
 */
var MenuItem = cr.ui.define('div');

MenuItem.prototype = {
  __proto__: HTMLDivElement.prototype,

  /**
   * Decorates the menu item element.
   */
  decorate: function() {
    this.className = 'menu-item';
  },

  /**
   * Initialize the MenuItem.
   * @param {Menu} menu A {@code Menu} object to which this menu item
   *    will be added to.
   * @param {Object} attrs JSON object that represents this menu items
   *    properties.  This is created from menu model in C code.  See
   *    chromeos/views/native_menu_webui.cc.
   * @param {Object} model The model object.
   */
  init: function(menu, attrs, model) {
    // The left icon's width. 0 if no icon.
    var leftIconWidth = model.maxIconWidth;
    this.menu_ = menu;
    this.attrs = attrs;
    var attrs = this.attrs;
    if (attrs.type == 'separator') {
      this.className = 'separator';
    } else if (attrs.type == 'command' ||
               attrs.type == 'submenu' ||
               attrs.type == 'check' ||
               attrs.type == 'radio') {
      this.initMenuItem_();
      this.initPadding_(leftIconWidth);
    } else {
      // This should not happend.
      this.classList.add('disabled');
      this.textContent = 'unknown';
    }

    menu.appendChild(this);
    if (!attrs.visible) {
      this.classList.add('hidden');
    }
  },

  /**
   * Changes the selection state of the menu item.
   * @param {boolean} selected True to set the selection, or false
   *     otherwise.
   */
  set selected(selected) {
    if (selected) {
      this.classList.add('selected');
      this.menu_.selectedItem = this;
    } else {
      this.classList.remove('selected');
    }
  },

  /**
   * Activate the menu item.
   */
  activate: function() {
    if (this.attrs.type == 'submenu') {
      this.menu_.openSubmenu(this);
    } else if (this.attrs.type != 'separator' &&
               this.className.indexOf('selected') >= 0) {
      sendActivate(this.menu_.getMenuItemIndexOf(this),
                   'close_and_activate');
    }
  },

  /**
   * Sends open_submenu WebUI message.
   */
  sendOpenSubmenuCommand: function() {
    chrome.send('open_submenu',
                [String(this.menu_.getMenuItemIndexOf(this)),
                 String(this.getBoundingClientRect().top)]);
  },

  /**
   * Internal method to initiailze the MenuItem.
   * @private
   */
  initMenuItem_: function() {
    var attrs = this.attrs;
    this.className = 'menu-item ' + attrs.type;
    this.menu_.addHandlers(this, this);
    var label = document.createElement('div');

    label.className = 'menu-label';
    this.menu_.addLabelTo(this, attrs.label, label,
                          true /* enable mnemonic */);

    if (attrs.font) {
      label.style.font = attrs.font;
    }
    this.appendChild(label);


    if (attrs.accel) {
      var accel = document.createElement('div');
      accel.className = 'accelerator';
      accel.textContent = attrs.accel;
      accel.style.font = attrs.font;
      this.appendChild(accel);
    }

    if (attrs.type == 'submenu') {
      // This overrides left-icon's position, but it's OK as submenu
      // shoudln't have left-icon.
      this.classList.add('right-icon');
      this.style.backgroundImage = 'url(' + this.menu_.config_.arrowUrl + ')';
    }
  },

  initPadding_: function(leftIconWidth) {
    if (leftIconWidth <= 0) {
      this.classList.add('no-icon');
      return;
    }
    this.classList.add('left-icon');

    var url;
    var attrs = this.attrs;
    if (attrs.type == 'radio') {
      url = attrs.checked ?
          this.menu_.config_.radioOnUrl :
          this.menu_.config_.radioOffUrl;
    } else if (attrs.icon) {
      url = attrs.icon;
    } else if (attrs.type == 'check' && attrs.checked) {
      url = this.menu_.config_.checkUrl;
    }
    if (url) {
      this.style.backgroundImage = 'url(' + url + ')';
    }
    // TODO(oshima): figure out how to update left padding in rule.
    // 4 is the padding on left side of icon.
    var padding =
        4 + leftIconWidth + this.menu_.config_.icon_to_label_padding;
    this.style.WebkitPaddingStart = padding + 'px';
  },
};

/**
 * Menu class.
 */
var Menu = cr.ui.define('div');

Menu.prototype = {
  __proto__: HTMLDivElement.prototype,

  /**
   * Configuration object.
   * @type {Object}
   */
  config_: null,

  /**
   * Currently selected menu item.
   * @type {MenuItem}
   */
  current_: null,

  /**
   * Timers for opening/closing submenu.
   * @type {number}
   */
  openSubmenuTimer_: 0,
  closeSubmenuTimer_: 0,

  /**
   * Auto scroll timer.
   * @type {number}
   */
  scrollTimer_: 0,

  /**
   * Pointer to a submenu currently shown, if any.
   * @type {MenuItem}
   */
  submenuShown_: null,

  /**
   * True if this menu is root.
   * @type {boolean}
   */
  isRoot_: false,

  /**
   * Total hight of scroll buttons. Used to adjust the height of
   * viewport in order to show scroll bottons without scrollbar.
   * @type {number}
   */
  buttonHeight_: 0,

  /**
   * True to enable scroll button.
   * @type {boolean}
   */
  scrollEnabled: false,

  /**
   * Decorates the menu element.
   */
  decorate: function() {
    this.id = 'viewport';
  },

  /**
   * Initialize the menu.
   * @param {Object} config Configuration parameters in JSON format.
   *  See chromeos/views/native_menu_webui.cc for details.
   */
  init: function(config) {
    // List of menu items
    this.items_ = [];
    // Map from mnemonic character to item to activate
    this.mnemonics_ = {};

    this.config_ = config;
    this.addEventListener('mouseout', this.onMouseout_.bind(this));

    document.addEventListener('keydown', this.onKeydown_.bind(this));
    document.addEventListener('keypress', this.onKeypress_.bind(this));
    document.addEventListener('mousewheel', this.onMouseWheel_.bind(this));
    window.addEventListener('resize', this.onResize_.bind(this));

    // Setup scroll events.
    var up = $('scroll-up');
    var down = $('scroll-down');
    up.addEventListener('mouseout', this.stopScroll_.bind(this));
    down.addEventListener('mouseout', this.stopScroll_.bind(this));
    var menu = this;
    up.addEventListener('mouseover',
                        function() {
                          menu.autoScroll_(-SCROLL_TICK_PX);
                        });
    down.addEventListener('mouseover',
                          function() {
                            menu.autoScroll_(SCROLL_TICK_PX);
                          });

    this.buttonHeight_ =
        up.getBoundingClientRect().height +
        down.getBoundingClientRect().height;
  },

  /**
   * Adds a label to {@code targetDiv}. A label may contain
   * mnemonic key, preceded by '&'.
   * @param {MenuItem} item The menu item to be activated by mnemonic
   *    key.
   * @param {string} label The label string to be added to
   *    {@code targetDiv}.
   * @param {HTMLElement} div The div element the label is added to.
   * @param {boolean} enableMnemonic True to enable mnemonic, or false
   *    to not to interprete mnemonic key. The function removes '&'
   *    from the label in both cases.
   */
  addLabelTo: function(item, label, targetDiv, enableMnemonic) {
    var mnemonic = MNEMONIC_REGEXP.exec(label);
    if (mnemonic && enableMnemonic) {
      var c = mnemonic[2].toLowerCase();
      this.mnemonics_[c] = item;
    }
    if (!mnemonic) {
      targetDiv.textContent = label;
    } else if (enableMnemonic) {
      targetDiv.appendChild(document.createTextNode(mnemonic[1]));
      targetDiv.appendChild(document.createElement('span'));
      targetDiv.appendChild(document.createTextNode(mnemonic[3]));
      targetDiv.childNodes[1].className = 'mnemonic';
      targetDiv.childNodes[1].textContent = mnemonic[2];
    } else {
      targetDiv.textContent = mnemonic.splice(1, 3).join('');
    }
  },

  /**
   * @return {number} The index of the {@code item}.
   */
  getMenuItemIndexOf: function(item) {
    return this.items_.indexOf(item);
  },

  /**
   * A template method to create an item object. It can be a subclass
   * of MenuItem, or any HTMLElement that implements {@code init},
   * {@code activate} methods as well as {@code selected} attribute.
   * @param {Object} attrs The menu item's properties passed from C++.
   * @return {MenuItem} The created menu item.
   */
  createMenuItem: function(attrs) {
    return new MenuItem();
  },

  /**
   * Update and display the new model.
   */
  updateModel: function(model) {
    this.isRoot = model.isRoot;
    this.current_ = null;
    this.items_ = [];
    this.mnemonics_ = {};
    this.innerHTML = '';  // remove menu items

    for (var i = 0; i < model.items.length; i++) {
      var attrs = model.items[i];
      var item = this.createMenuItem(attrs);
      item.init(this, attrs, model);
      this.items_.push(item);
    }
    this.onResize_();
  },

  /**
   * Highlights the currently selected item, or
   * select the 1st selectable item if none is selected.
   */
  showSelection: function() {
    if (this.current_) {
      this.current_.selected = true;
    } else {
      this.findNextEnabled_(1).selected = true;
    }
  },

  /**
   * Add event handlers for the item.
   */
  addHandlers: function(item, target) {
    var menu = this;
    target.addEventListener('mouseover', function(event) {
      menu.onMouseover_(event, item);
    });
    if (item.attrs.enabled) {
      target.addEventListener('mouseup', function(event) {
        menu.onClick_(event, item);
      });
    } else {
      target.classList.add('disabled');
    }
  },

  /**
   * Set the selected item. This controls timers to open/close submenus.
   * 1) If the selected menu is submenu, and that submenu is not yet opeend,
   *    start timer to open. This will not cancel close timer, so
   *    if there is a submenu opened, it will be closed before new submenu is
   *    open.
   * 2) If the selected menu is submenu, and that submenu is already opened,
   *    cancel both open/close timer.
   * 3) If the selected menu is not submenu, cancel all timers and start
   *    timer to close submenu.
   * This prevents from opening/closing menus while you're actively
   * navigating menus. To open submenu, you need to wait a bit, or click
   * submenu.
   *
   * @param {MenuItem} item The selected item.
   */
  set selectedItem(item) {
    if (this.current_ != item) {
      if (this.current_ != null)
        this.current_.selected = false;
      this.current_ = item;
      this.makeSelectedItemVisible_();
    }

    var menu = this;
    if (item.attrs.type == 'submenu') {
      if (this.submenuShown_ != item) {
        this.openSubmenuTimer_ =
            setTimeout(
                function() {
                  menu.openSubmenu(item);
                },
                SUBMENU_OPEN_DELAY_MS);
      } else {
        this.cancelSubmenuTimer_();
      }
    } else if (this.submenuShown_) {
      this.cancelSubmenuTimer_();
      this.closeSubmenuTimer_ =
          setTimeout(
              function() {
                menu.closeSubmenu_(item);
              },
              SUBMENU_CLOSE_DELAY_MS);
    }
  },

  /**
   * Open submenu {@code item}. It does nothing if the submenu is
   * already opened.
   * @param {MenuItem} item The submenu item to open.
   */
  openSubmenu: function(item) {
    this.cancelSubmenuTimer_();
    if (this.submenuShown_ != item) {
      this.submenuShown_ = item;
      item.sendOpenSubmenuCommand();
    }
  },

  /**
   * Handle keyboard navigation and activation.
   * @private
   */
  onKeydown_: function(event) {
    switch (event.keyIdentifier) {
      case 'Left':
        this.moveToParent_();
        break;
      case 'Right':
        this.moveToSubmenu_();
        break;
      case 'Up':
        this.classList.add('mnemonic-enabled');
        this.findNextEnabled_(-1).selected = true;
      break;
      case 'Down':
        this.classList.add('mnemonic-enabled');
        this.findNextEnabled_(1).selected = true;
        break;
      case 'U+0009':  // tab
         break;
      case 'U+001B':  // escape
        chrome.send('close_all');
        break;
      case 'Enter':
      case 'U+0020':  // space
        if (this.current_) {
          this.current_.activate();
        }
        break;
    }
  },

  /**
   * Handle mnemonic keys.
   * @private
   */
  onKeypress_: function(event) {
    // Handles mnemonic.
    var c = String.fromCharCode(event.keyCode);
    var item = this.mnemonics_[c.toLowerCase()];
    if (item) {
      item.selected = true;
      item.activate();
    }
  },

  // Mouse Event handlers
  onClick_: function(event, item) {
    item.activate();
  },

  onMouseover_: function(event, item) {
    this.cancelSubmenuTimer_();
    // Ignore false mouseover event at (0,0) which is
    // emitted when opening submenu.
    if (item.attrs.enabled && event.clientX != 0 && event.clientY != 0) {
      item.selected = true;
    }
  },

  onMouseout_: function(event) {
    if (this.current_) {
      this.current_.selected = false;
    }
  },

  onResize_: function() {
    var up = $('scroll-up');
    var down = $('scroll-down');
    // this needs to be < 2 as empty page has height of 1.
    if (window.innerHeight < 2) {
      // menu window is not visible yet. just hide buttons.
      up.classList.add('hidden');
      down.classList.add('hidden');
      return;
    }
    // Do not use screen width to determin if we need scroll buttons
    // as the max renderer hight can be shorter than actual screen size.
    // TODO(oshima): Fix this when we implement transparent renderer.
    if (this.scrollHeight > window.innerHeight && this.scrollEnabled) {
      this.style.height = (window.innerHeight - this.buttonHeight_) + 'px';
      up.classList.remove('hidden');
      down.classList.remove('hidden');
    } else {
      this.style.height = '';
      up.classList.add('hidden');
      down.classList.add('hidden');
    }
  },

  onMouseWheel_: function(event) {
    var delta = event.wheelDelta / 5;
    this.scrollTop -= delta;
  },

  /**
   * Closes the submenu.
   * a submenu.
   * @private
   */
  closeSubmenu_: function(item) {
    this.submenuShown_ = null;
    this.cancelSubmenuTimer_();
    chrome.send('close_submenu');
  },

  /**
   * Move the selection to parent menu if the current menu is
   * a submenu.
   * @private
   */
  moveToParent_: function() {
    if (!this.isRoot) {
      if (this.current_) {
        this.current_.selected = false;
      }
      chrome.send('move_to_parent');
    }
  },

  /**
   * Move the selection to submenu if the currently selected
   * menu is a submenu.
   * @private
   */
  moveToSubmenu_: function() {
    var current = this.current_;
    if (current && current.attrs.type == 'submenu') {
      this.openSubmenu(current);
      chrome.send('move_to_submenu');
    }
  },

  /**
   * Finds the next selectable item. If nothing is selected, the first
   * selectable item will be chosen. Returns null if nothing is selectable.
   * @param {number} incr Specifies the direction to search, 1 to
   *     downwards and -1 for upwards.
   * @private
   * @return {MenuItem} The next selectable item.
   */
  findNextEnabled_: function(incr) {
    var len = this.items_.length;
    var index;
    if (this.current_) {
      index = this.getMenuItemIndexOf(this.current_);
    } else {
      index = incr > 0 ? -1 : len;
    }
    for (var i = 0; i < len; i++) {
      index = (index + incr + len) % len;
      var item = this.items_[index];
      if (item.attrs.enabled && item.attrs.type != 'separator' &&
          !item.classList.contains('hidden'))
        return item;
    }
    return null;
  },

  /**
   * Cancels timers to open/close submenus.
   * @private
   */
  cancelSubmenuTimer_: function() {
    clearTimeout(this.openSubmenuTimer_);
    this.openSubmenuTimer_ = 0;
    clearTimeout(this.closeSubmenuTimer_);
    this.closeSubmenuTimer_ = 0;
  },

  /**
   * Starts auto scroll.
   * @param {number} tick The number of pixels to scroll.
   * @private
   */
  autoScroll_: function(tick) {
    var previous = this.scrollTop;
    this.scrollTop += tick;
    var menu = this;
    this.scrollTimer_ = setTimeout(
        function() {
          menu.autoScroll_(tick);
        },
        SCROLL_INTERVAL_MS);
  },

  /**
   * Stops auto scroll.
   * @private
   */
  stopScroll_: function() {
    clearTimeout(this.scrollTimer_);
    this.scrollTimer_ = 0;
  },

  /**
   * Scrolls the viewport to make the selected item visible.
   * @private
   */
  makeSelectedItemVisible_: function() {
    this.current_.scrollIntoViewIfNeeded(false);
  },
};

/**
 * functions to be called from C++.
 * @param {Object} config The viewport configuration.
 */
function init(config) {
  $('viewport').init(config);
}

function selectItem() {
  $('viewport').showSelection();
}

function updateModel(model) {
  $('viewport').updateModel(model);
}

function modelUpdated() {
  chrome.send('model_updated');
}

function enableScroll(enabled) {
  $('viewport').scrollEnabled = enabled;
}
