/* Copyright 2016 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 or at
 * https://developers.google.com/open-source/licenses/bsd
 */

/**
 * @fileoverview This file represents a standalone, reusable drop down menu
 * widget that can be attached to any element on a given page. It supports
 * multiple instances of the widget on a page. It has no dependencies. Usage
 * is as simple as creating a new Menu object and supplying it with a target
 * element.
 */

/**
 * The entry point and constructor for the Menu object. Creating
 * a valid instance of this object will insert a drop down menu
 * near the element supplied as the target, attach all the necessary
 * events and insert the necessary elements on the page.
 *
 * @param {Element} target the target element on the page to which
 *     the drop down menu will be placed near.
 * @param {Function=} opt_onShow function to execute every time the
 *     menu is made visible, most likely through a click on the target.
 * @constructor
 */
var Menu = function(target, opt_onShow) {
  this.iid = Menu.instance.length;
  Menu.instance[this.iid] = this;
  this.target = target;
  this.onShow = opt_onShow || null;

  // An optional trigger element on the page that can be used to trigger
  // the drop-down. Currently hard-coded to be the same as the target element.
  this.trigger = target;
  this.items = [];
  this.onOpenEvents = [];
  this.menu = this.createElement('div', 'menuDiv instance' + this.iid);
  this.targetId = this.target.getAttribute('id');
  let menuId = (this.targetId != null) ?
    'menuDiv-' + this.targetId : 'menuDiv-instance' + this.iid;
  this.menu.setAttribute('id', menuId);
  this.menu.role = 'listbox';
  this.hide();
  this.addCategory('default');
  this.addEvent(this.trigger, 'click', this.toggle.bind(this));
  this.addEvent(window, 'resize', this.adjustSizeAndLocation.bind(this));

  // Hide the menu if a user clicks outside the menu widget
  this.addEvent(document, 'click', this.hide.bind(this));
  this.addEvent(this.menu, 'click', this.stopPropagation());
  this.addEvent(this.trigger, 'click', this.stopPropagation());
};

// A reference to the element or node that the drop down
// will appear next to
Menu.prototype.target = null;

// Element ID of the target. ID will be assigned to the newly created
// menu div based on the target ID. A default ID will be
// assigned If there is no ID on the target.
Menu.prototype.targetId = null;

/**
 * A reference to the element or node that will trigger
 * the drop down to appear. If not specified, this value
 * will be the same as <Menu Instance>.target
 * @type {Element}
 */
Menu.prototype.trigger = null;

// A reference to the event type that will "open" the
// menu div. By default this is the (on)click method.
Menu.prototype.triggerType = null;

// A reference to the element that will appear when the
// trigger is clicked.
Menu.prototype.menu = null;

/**
 * Function to execute every time the menu is made shown.
 * @type {Function}
 */
Menu.prototype.onShow = null;

// A list of category divs. By default these categories
// are set to display none until at least one element
// is placed within them.
Menu.prototype.categories = null;

// An id used to track timed intervals
Menu.prototype.thread = -1;

// The static instance id (iid) denoting which menu in the
// list of Menu.instance items is this instantiated object.
Menu.prototype.iid = -1;

// A counter to indicate the number of items added with
// addItem(). After 5 items, a height is set on the menu
// and a scroll bar will appear.
Menu.prototype.items = null;

// A flag to detect whether or not a scroll bar has been added
Menu.prototype.scrolls = false;

// onOpen event handlers; each function in this list will
// be executed and passed the executing instance as a
// parameter before the menu is to be displayed.
Menu.prototype.onOpenEvents = null;

/**
 * An extended short-cut for document.createElement(); this
 * method allows the creation of an element, the assignment
 * of one or more class names and the ability to set the
 * content of the created element all with one function call.
 * @param {string} element name of the element to create. Examples would
 *     be 'div' or 'a'.
 * @param {string} opt_className an optional string to assign to the
 *     newly created element's className property.
 * @param {string|Element} opt_content either a snippet of HTML or a HTML
 *     element that is to be appended to the newly created element.
 * @return {Element} a reference to the newly created element.
 */
Menu.prototype.createElement = function(element, opt_className, opt_content) {
  let div = document.createElement(element);
  div.className = opt_className;
  if (opt_content) {
    this.append(opt_content, div);
  }
  return div;
};

/**
 * Uses a fairly browser agnostic approach to applying a callback to
 * an element on the page.
 *
 * @param {Element|EventTarget} element a reference to an element on the page to
 *     which to attach and event.
 * @param {string} eventType a browser compatible event type as a string
 *     without the sometimes assumed on- prefix. Examples: 'click',
 *     'mousedown', 'mouseover', etc...
 * @param {Function} callback a function reference to invoke when the
 *     the event occurs.
 */
Menu.prototype.addEvent = function(element, eventType, callback) {
  if (element.addEventListener) {
    element.addEventListener(eventType, callback, false);
  } else {
    try {
      element.attachEvent('on' + eventType, callback);
    } catch (e) {
      element['on' + eventType] = callback;
    }
  }
};

/**
 * Similar to addEvent, this provides a specialied handler for onOpen
 * events that apply to this instance of the Menu class. The supplied
 * callbacks are appended to an internal array and called in order
 * every time the menu is opened. The array can be accessed via
 * menuInstance.onOpenEvents.
 */
Menu.prototype.addOnOpen = function(eventCallback) {
  let eventIndex = this.onOpenEvents.length;
  this.onOpenEvents.push(eventCallback);
  return eventIndex;
};

/**
 * This method will create a div with the classes .menuCategory and the
 * name of the category as supplied in the first parameter. It then, if
 * a title is supplied, creates a title div and appends it as well. The
 * optional title is styled with the .categoryTitle and category name
 * class.
 *
 * Categories are stored within the menu object instance for programmatic
 * manipulation in the array, menuInstance.categories. Note also that this
 * array is doubly linked insofar as that the category div can be accessed
 * via it's index in the array as well as by instance.categories[category]
 * where category is the string name supplied when creating the category.
 *
 * @param {string} category the string name used to create the category;
 *     used as both a class name and a key into the internal array. It
 *     must be a valid JavaScript variable name.
 * @param {string|Element} opt_title this optional field is used to visibly
 *     denote the category title. It can be either HTML or an element.
 * @return {Element} the newly created div.
 */
Menu.prototype.addCategory = function(category, opt_title) {
  this.categories = this.categories || [];
  let categoryDiv = this.createElement('div', 'menuCategory ' + category);
  categoryDiv._categoryName = category;
  if (opt_title) {
    let categoryTitle = this.createElement('b', 'categoryTitle ' +
          category, opt_title);
    categoryTitle.style.display = 'block';
    this.append(categoryTitle);
    categoryDiv._categoryTitle = categoryTitle;
  }
  this.append(categoryDiv);
  this.categories[this.categories.length] = this.categories[category] =
      categoryDiv;

  return categoryDiv;
};

/**
 * This method removes the contents of a given category but does not
 * remove the category itself.
 */
Menu.prototype.emptyCategory = function(category) {
  if (!this.categories[category]) {
    return;
  }
  let div = this.categories[category];
  for (let i = div.childNodes.length - 1; i >= 0; i--) {
    div.removeChild(div.childNodes[i]);
  }
};

/**
 * This function is the most drastic of the cleansing functions; it removes
 * all categories and all menu items and all HTML snippets that have been
 * added to this instance of the Menu class.
 */
Menu.prototype.clear = function() {
  for (var i = 0; i < this.categories.length; i++) {
    // Prevent memory leaks
    this.categories[this.categories[i]._categoryName] = null;
  }
  this.items.splice(0, this.items.length);
  this.categories.splice(0, this.categories.length);
  this.categories = [];
  this.items = [];
  for (var i = this.menu.childNodes.length - 1; i >= 0; i--) {
    this.menu.removeChild(this.menu.childNodes[i]);
  }
};

/**
 * Passed an instance of a menu item, it will be removed from the menu
 * object, including any residual array links and possible memory leaks.
 * @param {Element} item a reference to the menu item to remove.
 * @return {Element} returns the item removed.
 */
Menu.prototype.removeItem = function(item) {
  let result = null;
  for (let i = 0; i < this.items.length; i++) {
    if (this.items[i] == item) {
      result = this.items[i];
      this.items.splice(i, 1);
    }
    // Renumber
    this.items[i].item._index = i;
  }
  return result;
};

/**
 * Removes a category from the menu element and all of its children thus
 * allowing the Element to be collected by the browsers VM.
 * @param {string} category the name of the category to retrieve and remove.
 */
Menu.prototype.removeCategory = function(category) {
  let div = this.categories[category];
  if (!div || !div.parentNode) {
    return;
  }
  if (div._categoryTitle) {
    div._categoryTitle.parentNode.removeChild(div._categoryTitle);
  }
  div.parentNode.removeChild(div);
  for (var i = 0; i < this.categories.length; i++) {
    if (this.categories[i] === div) {
      this.categories[this.categories[i]._categoryName] = null;
      this.categories.splice(i, 1);
      return;
    }
  }
  for (var i = 0; i < div.childNodes.length; i++) {
    if (div.childNodes[i]._index) {
      this.items.splice(div.childNodes[i]._index, 1);
    } else {
      this.removeItem(div.childNodes[i]);
    }
  }
};

/**
 * This heart of the menu population scheme, the addItem function creates
 * a combination of elements that visually form up a menu item. If no
 * category is supplied, the default category is used. The menu item is
 * an <a> tag with the class .menuItem. The menu item is directly styled
 * as a block element. Other than that, all styling should be done via a
 * external CSS definition.
 *
 * @param {string|Element} html_or_element a string of HTML text or a
 *     HTML element denoting the contents of the menu item.
 * @param {string} opt_href the href of the menu item link. This is
 *     the most direct way of defining the menu items function.
 *     [Default: '#'].
 * @param {string} opt_category the category string name of the category
 *     to append the menu item to. If the category doesn't exist, one will
 *     be created. [Default: 'default'].
 * @param {string} opt_title used when creating a new category and is
 *     otherwise ignored completely. It is also ignored when supplied if
 *     the named category already exists.
 * @return {Element} returns the element that was created.
 */
Menu.prototype.addItem = function(html_or_element, opt_href, opt_category,
  opt_title) {
  let category = opt_category ? (this.categories[opt_category] ||
                                 this.addCategory(opt_category, opt_title)) :
    this.categories['default'];
  let menuHref = (opt_href == undefined ? '#' : opt_href);
  let menuItem = undefined;
  if (menuHref) {
    menuItem = this.createElement('a', 'menuItem', html_or_element);
  } else {
    menuItem = this.createElement('span', 'menuText', html_or_element);
  }
  let itemText = typeof html_or_element == 'string' ? html_or_element :
    html_or_element.textContent || 'ERROR';

  menuItem.style.display = 'block';
  if (menuHref) {
    menuItem.setAttribute('href', menuHref);
  }
  menuItem._index = this.items.length;
  menuItem.role = 'option';
  this.append(menuItem, category);
  this.items[this.items.length] = {item: menuItem, text: itemText};

  return menuItem;
};

/**
 * Adds a visual HTML separator to the menu, optionally creating a
 * category as per addItem(). See above.
 * @param {string} opt_category the category string name of the category
 *     to append the menu item to. If the category doesn't exist, one will
 *     be created. [Default: 'default'].
 * @param {string} opt_title used when creating a new category and is
 *     otherwise ignored completely. It is also ignored when supplied if
 *     the named category already exists.
 */
Menu.prototype.addSeparator = function(opt_category, opt_title) {
  let category = opt_category ? (this.categories[opt_category] ||
                                 this.addCategory(opt_category, opt_title)) :
    this.categories['default'];
  let hr = this.createElement('hr', 'menuSeparator');
  this.append(hr, category);
};

/**
 * This method performs all the dirty work of positioning the menu. It is
 * responsible for dynamic sizing, insertion and deletion of scroll bars
 * and calculation of offscreen width considerations.
 */
Menu.prototype.adjustSizeAndLocation = function() {
  let style = this.menu.style;
  style.position = 'absolute';

  let firstCategory = null;
  for (let i = 0; i < this.categories.length; i++) {
    this.categories[i].className = this.categories[i].className.
      replace(/ first/, '');
    if (this.categories[i].childNodes.length == 0) {
      this.categories[i].style.display = 'none';
    } else {
      this.categories[i].style.display = '';
      if (!firstCategory) {
        firstCategory = this.categories[i];
        firstCategory.className += ' first';
      }
    }
  }

  let alreadyVisible = style.display != 'none' &&
      style.visibility != 'hidden';
  let docElemWidth = document.documentElement.clientWidth;
  let docElemHeight = document.documentElement.clientHeight;
  let pageSize = {
    w: (window.innerWidth || docElemWidth && docElemWidth > 0 ?
      docElemWidth : document.body.clientWidth) || 1,
    h: (window.innerHeight || docElemHeight && docElemHeight > 0 ?
      docElemHeight : document.body.clientHeight) || 1,
  };
  let targetPos = this.find(this.target);
  let targetSize = {w: this.target.offsetWidth,
    h: this.target.offsetHeight};
  let menuSize = {w: this.menu.offsetWidth, h: this.menu.offsetHeight};

  if (!alreadyVisible) {
    let oldVisibility = style.visibility;
    let oldDisplay = style.display;
    style.visibility = 'hidden';
    style.display = '';
    style.height = '';
    style.width = '';
    menuSize = {w: this.menu.offsetWidth, h: this.menu.offsetHeight};
    style.display = oldDisplay;
    style.visibility = oldVisibility;
  }

  let addScroll = (this.menu.offsetHeight / pageSize.h) > 0.8;
  if (addScroll) {
    menuSize.h = parseInt((pageSize.h * 0.8), 10);
    style.height = menuSize.h + 'px';
    style.overflowX = 'hidden';
    style.overflowY = 'auto';
  } else {
    style.height = style.overflowY = style.overflowX = '';
  }

  style.top = (targetPos.y + targetSize.h) + 'px';
  style.left = targetPos.x + 'px';

  if (menuSize.w < 175) {
    style.width = '175px';
  }

  if (addScroll) {
    style.width = parseInt(style.width, 10) + 13 + 'px';
  }

  if ((targetPos.x + menuSize.w) > pageSize.w) {
    style.left = targetPos.x - (menuSize.w - targetSize.w) + 'px';
  }
};


/**
 * This function is used heavily, internally. It appends text
 * or the supplied element via appendChild(). If
 * the opt_target variable is present, the supplied element will be
 * the container rather than the menu div for this instance.
 *
 * @param {string|Element} text_or_element the html or element to insert
 *     into opt_target.
 * @param {Element} opt_target the target element it should be appended to.
 *
 */
Menu.prototype.append = function(text_or_element, opt_target) {
  let element = opt_target || this.menu;
  if (typeof opt_target == 'string' && this.categories[opt_target]) {
    element = this.categories[opt_target];
  }
  if (typeof text_or_element == 'string') {
    element.textContent += text_or_element;
  } else {
    element.appendChild(text_or_element);
  }
};

/**
 * Displays the menu (such as upon mouseover).
 */
Menu.prototype.over = function() {
  if (this.menu.style.display != 'none') {
    this.show();
  }
  if (this.thread != -1) {
    clearTimeout(this.thread);
    this.thread = -1;
  }
};

/**
 * Hides the menu (such as upon mouseout).
 */
Menu.prototype.out = function() {
  if (this.thread != -1) {
    clearTimeout(this.thread);
    this.thread = -1;
  }
  this.thread = setTimeout(this.hide.bind(this), 400);
};

/**
 * Stops event propagation.
 */
Menu.prototype.stopPropagation = function() {
  return (function(e) {
    if (!e) {
      e = window.event;
    }
    e.cancelBubble = true;
    if (e.stopPropagation) {
      e.stopPropagation();
    }
  });
};

/**
 * Toggles the menu between hide/show.
 */
Menu.prototype.toggle = function(event) {
  event.preventDefault();
  if (this.menu.style.display == 'none') {
    this.show();
  } else {
    this.hide();
  }
};

/**
 * Makes the menu visible, then calls the user-supplied onShow callback.
 */
Menu.prototype.show = function() {
  if (this.menu.style.display != '') {
    for (var i = 0; i < this.onOpenEvents.length; i++) {
      this.onOpenEvents[i].call(null, this);
    }

    // Invisibly show it first
    this.menu.style.visibility = 'hidden';
    this.menu.style.display = '';
    this.adjustSizeAndLocation();
    if (this.trigger.nodeName && this.trigger.nodeName == 'A') {
      this.trigger.blur();
    }
    this.menu.style.visibility = 'visible';

    // Hide other menus
    for (var i = 0; i < Menu.instance.length; i++) {
      let menuInstance = Menu.instance[i];
      if (menuInstance != this) {
        menuInstance.hide();
      }
    }

    if (this.onShow) {
      this.onShow();
    }
  }
};

/**
 * Makes the menu invisible.
 */
Menu.prototype.hide = function() {
  this.menu.style.display = 'none';
};

Menu.prototype.find = function(element) {
  let curleft = 0, curtop = 0;
  if (element.offsetParent) {
    do {
      curleft += element.offsetLeft;
      curtop += element.offsetTop;
    }
    while ((element = element.offsetParent) && (element.style &&
          element.style.position != 'relative' &&
          element.style.position != 'absolute'));
  }
  return {x: curleft, y: curtop};
};

/**
 * A static array of object instances for global reference.
 * @type {Array.<Menu>}
 */
Menu.instance = [];
