﻿// © 2007-2008, Applied Geographics, Inc.  All rights reserved.

/// <reference name="AppGeo.Web.Extensions.js" assembly="AppGeo.Web" />

// Define our namespaces
Type.registerNamespace("Ag");
Type.registerNamespace("Ag.UI");

// Ag.UI.ToolMenuEventArgs (class)
Ag.UI.ToolMenuEventArgs = function(itemId) {
  /// <param name="itemId" type="String">The ID of the item that triggered this event</param>
  var e = Function._validateParams(arguments, [
    { name: "itemId", type: String }
  ]);
  if (e) throw e;

  Ag.UI.ToolMenuEventArgs.initializeBase(this);
  this.itemId = itemId;
}

Ag.UI.ToolMenuEventArgs.prototype = {

  // Public properties

  get_itemId: function() {
    /// <value type="String">The id of the clicked menu item, you can also use the public field itemId</value>
    return this.itemId;
  }
}

Ag.UI.ToolMenuEventArgs.registerClass("Ag.UI.ToolMenuEventArgs", Sys.EventArgs);

// Ag.UI.ToolMenu (component)
Ag.UI.ToolMenu = function() {
  /// <summary>Constructor</summary>
  /// <remarks>
  /// This is just a component, no UI element.
  /// </remarks>
  Ag.UI.ToolMenu.initializeBase(this);

  this._itemIds = [];
  this._disabledIds = [];
  this._selectedIndex = -1;
  this._hoverCssClass = "";
  this._selectedCssClass = "";
  this._disabledCssClass = "";

  this._clickHandler = Function.createDelegate(this, this._item_click);
  this._mouseoutHandler = Function.createDelegate(this, this._item_mouseout);
  this._mouseoverHandler = Function.createDelegate(this, this._item_mouseover);
}

Ag.UI.ToolMenu.prototype = {

  // Life Cycle

  dispose: function() {
    /// <summary>Dispose this control</summary>
    this.clear();

    Ag.UI.ToolMenu.callBaseMethod(this, "dispose");
  },

  // Public Methods

  addItem: function(itemId) {
    /// <summary>Adds the item to the tool menu</summary>
    /// <param name="itemId" type="String">The element id of the item to add to the tool menu</param>
    var element = $get(itemId);

    if (element != null) {
      switch (Sys.Browser.agent) {
        case Sys.Browser.InternetExplorer:
          element.unselectable = "on";
          break;

        case Sys.Browser.Firefox:
          element.style.MozUserSelect = "none";
          break;
      }

      $addHandler(element, "click", this._clickHandler);
      $addHandler(element, "mouseout", this._mouseoutHandler);
      $addHandler(element, "mouseover", this._mouseoverHandler);

      Array.add(this._itemIds, itemId);
      if (this._itemIds.length - 1 == this._selectedIndex)
        this.setSelected($get(this._itemIds[length - 1]), true);
    }
  },

  addItems: function(itemIds) {
    /// <summary>Add an array of item ids</summary>
    /// <param name="itemIds" type="Array" elementType="String">An array of item ids</param>
    for (var i = 0; i < itemIds.length; i++)
      this.addItem(itemIds[i]);
  },

  clear: function() {
    /// <summary>Remove all items from the ToolMenu</summary>
    for (var i = 0; i < this._itemIds.length; i++) {
      var element = $get(this._itemIds[i]);
      if (element != null) {
        $clearHandlers(element);
        $(element).removeClass(this._hoverCssClass + " " + this._selectedCssClass + " " + this._disabledCssClass);
      }
    }

    this._itemIds = [];
    this._disabledIds = [];
    this._selectedIndex = -1;
  },

  getEnabled: function(itemId) {
    /// <summary>Return if the given item is enabled</summary>
    return !Array.contains(this._disabledIds, itemId);
  },

  getItemId: function(index) {
    /// <summary>Gets the id of an item at the requested index</summary>
    /// <param name="index" type="Number">The index to retrieve</param>
    if (index >= 0 && index < this._itemIds.length)
      return this._itemIds[index];
    else
      return "";
  },

  indexOf: function(itemId) {
    /// <summary>Get the index of the item</summary>
    /// <param name="itemId" type="String">The item id to look up</param>
    /// <returns>The index of the item with the given id or -1 if the item is not found</returns>
    return Array.indexOf(this._itemIds, itemId);
  },

  setEnabled: function(itemId, enabled) {
    /// <summary>Enable or disable an item, disabling clears item selection if that item was selected</summary>
    /// <param name="itemId" type="String">The ID of the item to modify</param>
    /// <param name="enabled" type="Boolean">true to enable, false to disable</param>
    if (enabled && !this.getEnabled(itemId)) {
      $("#" + itemId).removeClass(this._disabledCssClass);
      Array.remove(this._disabledIds, itemId);
    } else if (!enabled && this.getEnabled(itemId)) {
      var index = this.indexOf(itemId);
      if (index < 0)
        return;

      if (index == this._selectedIndex)
        this.set_selectedIndex(-1);

      $("#" + itemId).addClass(this._disabledCssClass);
      Array.add(this._disabledIds, itemId);
    }
  },

  // Public Properties

  get_count: function() {
    return this._itemIds.length;
  },

  get_disabledCssClass: function() {
    /// <value type="String">Disabled CSS class</value>
    return this._disabledCssClass;
  },

  set_disabledCssClass: function(value) {
    var i;
    if (this._disabledCssClass.length > 0) {
      for (i = 0; i < this._disabledIds.length; i++)
        $("#" + this._disabledIds[i]).removeClass(this._disabledCssClass);
    }

    this._disabledCssClass = String.isNullOrEmpty(value) ? "" : value;

    if (this._disabledCssClass.length > 0) {
      for (i = 0; i < this._disabledIds.length; i++)
        $("#" + this._disabledIds[i]).addClass(this._disabledCssClass);
    }
  },

  get_disabledIds: function() {
    /// <value type="Array" elementType="String">Gets or sets which items are disabled</value>
    return Array.clone(this._disabledIds);
  },

  set_disabledIds: function(value) {
    var e = Function._validateParams(arguments, [
      { name: "value", type: Array, elementType: String }
    ]);
    if (e) throw e;

    var i;
    for (i = 0; i < this._disabledIds.length; i++)
      this.setEnabled(this._disabledIds[i], true);
    this._disabledIds = [];

    for (i = 0; i < value.length; i++)
      this.setEnabled(value[i], false);
  },

  get_hoverCssClass: function() {
    /// <value type="String">Hover CSS class</value>
    return this._hoverCssClass;
  },

  set_hoverCssClass: function(value) {
    this._hoverCssClass = String.isNullOrEmpty(value) ? "" : value;
  },

  get_itemIds: function() {
    /// <value type="Array" elementType="String">Gets or sets the item IDs for this ToolMenu, setting will clear current item list</value>
    return Array.clone(this._itemIds);
  },

  set_itemIds: function(value) {
    var e = Function._validateParams(arguments, [
      { name: "value", type: Array, elementType: String }
    ]);
    if (e) throw e;

    this.clear();
    for (var i = 0; i < value.length; i++)
      this.addItem(value[i]);
  },

  get_selectedCssClass: function() {
    /// <value type="String">Hover CSS class</value>
    return this._selectedCssClass;
  },

  set_selectedCssClass: function(value) {
    if (this._selectedCssClass.length > 0 && this._selectedIndex >= 0)
      $("#" + this._itemIds[this._selectedIndex]).removeClass(this._selectedCssClass);

    this._selectedCssClass = String.isNullOrEmpty(value) ? "" : value;

    if (this._selectedCssClass.length > 0 && this._selectedIndex >= 0)
      $("#" + this._itemIds[this._selectedIndex]).addClass(this._selectedCssClass);
  },

  get_selectedIndex: function() {
    /// <value type="Number">Gets or sets the selected index</value>
    /// <remarks>
    /// This is the only way to mark an item as selected.
    /// You can now pass -1 into the set method to de-select all tools.
    /// </remarks>
    return this._selectedIndex;
  },

  set_selectedIndex: function(index) {
    if (index >= -1 && index < this._itemIds.length) {
      if (this._selectedIndex !== index) {
        if (this._selectedIndex >= 0 && this._selectedIndex < this._itemIds.length)
          this.setSelected($get(this._itemIds[this._selectedIndex]), false);

        if (index >= 0 && index < this._itemIds.length)
          this.setSelected($get(this._itemIds[index]), true);

        this._selectedIndex = index;
        this.raisePropertyChanged("selectedIndex");
      }
    }
  },

  get_selectedId: function() {
    /// <value type="String">Get or set the selected id</value>
    if (this._selectedIndex >= 0 && this._selectedIndex < this._itemIds.length) {
      return this._itemIds[this._selectedIndex];
    } else {
      return "";
    }
  },

  set_selectedId: function(value) {
    var index = this.indexOf(value);
    this.set_selectedIndex(index);
  },

  // Public Events

  add_menuItemClick: function(handler) {
    /// <summary>Occurs whenever a menu item is clicked (just before selectedIndexChanged if a non-selected item is clicked)</summary>
    this.get_events().addHandler("menuItemClick", handler);
  },

  remove_menuItemClick: function(handler) {
    this.get_events().removeHandler("menuItemClick", handler);
  },

  add_selectedIndexChanged: function(handler) {
    /// <summary>Occurs when the selection from the tool menu changes</summary>
    this.get_events().addHandler("selectedIndexChanged", handler);
  },

  remove_selectedIndexChanged: function(handler) {
    this.get_events().removeHandler("selectedIndexChanged", handler);
  },

  // Protected Methods

  setSelected: function(element, selected) {
    /// <summary>Select or deselect the item</summary>
    /// <param name="element" type="Sys.UI.DomElement" domElement="true">The element to change</param>
    /// <param name="selected" type="Boolean">The new status</param>
    /// <remarks>
    /// We remove the hover from an item being selected.
    /// You can override this method to tailor the selected element to your needs.
    /// </remarks>
    if (element && this._selectedCssClass) {
      var jel = $(element);
      if (selected) {
        if (this._hoverCssClass)
          jel.removeClass(this._hoverCssClass);

        jel.addClass(this._selectedCssClass);
      } else {
        jel.removeClass(this._selectedCssClass);
      }
    }
  },

  // Private Methods

  _clearHandlers: function() {
    /// <summary>Clear handlers for all items in tool menu</summary>
    for (var i = 0; i < this._itemIds.length; i++) {
      var element = $get(this._itemIds[i]);
      if (element != null)
        $clearHandlers(element);
    }
  },

  _onMenuItemClick: function(itemId) {
    /// <summary>Raises the menuItemClick event</summary>
    var handler = this.get_events().getHandler("menuItemClick");

    if (handler !== null)
      handler(this, new Ag.UI.ToolMenuEventArgs(itemId));
  },

  _onSelectedIndexChanged: function() {
    /// <summary>Raises the selectedIndexChanged event</summary>
    /// <remarks>
    /// This allows you to provide a custom handler for the event.
    /// </remarks>
    var handler = this.get_events().getHandler("selectedIndexChanged");

    if (handler !== null)
      handler(this, Sys.EventArgs.Empty);
  },

  // Private DOM Events

  _item_click: function(e) {
    for (var i = 0; i < this._itemIds.length; i++) {
      var item = $get(this._itemIds[i]);
      if (AjaxControlToolkit.DomUtility.isDescendantOrSelf(item, e.target) && this.getEnabled(item.id)) {
        this._onMenuItemClick(item.id);
        this.set_selectedIndex(i);
        this._onSelectedIndexChanged();
        break;
      }
    }
  },

  _item_mouseout: function(e) {
    if (this._hoverCssClass != "") {
      for (var i = 0; i < this._itemIds.length; i++) {
        var item = $get(this._itemIds[i]);
        if (AjaxControlToolkit.DomUtility.isDescendantOrSelf(item, e.target)) {
          Sys.UI.DomElement.removeCssClass(item, this._hoverCssClass);
          break;
        }
      }
    }
  },

  _item_mouseover: function(e) {
    if (this._hoverCssClass != "") {
      var selectedId = this.get_selectedId();
      for (var i = 0; i < this._itemIds.length; i++) {
        var item = $get(this._itemIds[i]);
        if (AjaxControlToolkit.DomUtility.isDescendantOrSelf(item, e.target)) {
          if (item.id != selectedId && this.getEnabled(item.id))
            Sys.UI.DomElement.addCssClass(item, this._hoverCssClass);
          break;
        }
      }
    }
  }
}

Ag.UI.ToolMenu.registerClass("Ag.UI.ToolMenu", Sys.Component);
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();