
Type.registerNamespace("SizeXchange.Web.UI.WebControls");

SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer = function()  {
  this._nodes = null;
  this._levels = null;
}
SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer.prototype = {
  addNode: function(node) {},
  clearNodes: function() {},
  addLevel: function(level) {},
  clearLevels: function() {}
}
SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer.registerInterface("SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer");

SizeXchange.Web.UI.WebControls.CategoryTreeLevel = function() {
  this._nameFields = [];
  this._urlFields = [];
  this._showAllFields = [];
  this._nameFormatString = null;
  this._urlFormatString = null;
  this._showAllFormatString = null;
  this._isLink = false;
  this._itemClass = null;
  this._nameClass = null;
  this._subCategoriesClass = null;
  this._showAllImageUrl = null;
  
  this._itemElement = null;
  this._container = null;
}
SizeXchange.Web.UI.WebControls.CategoryTreeLevel.prototype = {
  setProperty: function(propName, value, changedCallback) {
    if (this["_" + propName] != value) {
      var oldValue = this["_" + propName];
      this["_" + propName] = value;
      if (changedCallback) {
        changedCallback.apply(this, [oldValue, value]);
      };
    };
  },
  setFields: function(propName, value, changedCallback)  {
    if (typeof(value) == "string")  {
      value = value.split(",");
    };
    this.setProperty(propName, value, changedCallback);
  },
  set_nameFields: function(value)  {
    this.setFields("nameFields", value);
  },
  set_urlFields: function(value)  {
    this.setFields("urlFields", value);
  },
  set_showAllFields: function(value)  {
    this.setFields("showAllFields", value);
  },
  set_nameFormatString: function(value)  {
    this.setProperty("nameFormatString", value);
  },
  set_urlFormatString: function(value)  {
    this.setProperty("urlFormatString", value);
  },
  set_showAllFormatString: function(value)  {
    this.setProperty("showAllFormatString", value);
  },
  _getValues: function(dataItem, fields)  {
    var values = [];
    for (var i = 0; i < fields.length; i++) {
      Array.add(values, dataItem[fields[i]]);
    }
    return values;
  },
  get_isLink: function()  {
    return this._isLink;
  },
  set_isLink: function(value) {
    this.setProperty("isLink", value);
  },
  get_itemClass: function() {
    return this._itemClass;
  },
  set_itemClass: function(value)  {
    this.setProperty("itemClass", value);
  },
  get_nameClass: function() {
    return this._nameClass;
  },
  set_nameClass: function(value)  {
    this.setProperty("nameClass", value);
  },
  get_subCategoriesClass: function() {
    return this._subCategoriesClass;
  },
  set_subCategoriesClass: function(value)  {
    this.setProperty("subCategoriesClass", value);
  },
  get_showAllImageUrl: function() {
    return this._showAllImageUrl;
  },
  set_showAllImageUrl: function(value)  {
    this.setProperty("showAllImageUrl", value);
  },
  _formatString: function(dataItem, format, fields, defaultString)  {
    if (!format)  {
      return defaultString;
    };
    var args = [format];
    Array.addRange(args, this._getValues(dataItem, fields));
    return String.format.apply(this, args);
  },
  formatName: function(dataItem)  {
    return this._formatString(dataItem, this._nameFormatString, this._nameFields, dataItem["name"]);
  },
  formatUrl: function(dataItem) {
    return this._formatString(dataItem, this._urlFormatString, this._urlFields, "");
  },
  formatShowAll: function(dataItem) {
    return this._formatString(dataItem, this._showAllFormatString, this._showAllFields, "");
  },
  formatItemClass: function(levelIndex)  {
    if (!this.get_itemClass()) return "";
    return String.format(this.get_itemClass(), levelIndex);
  }
}
SizeXchange.Web.UI.WebControls.CategoryTreeLevel.registerClass("SizeXchange.Web.UI.WebControls.CategoryTreeLevel");

SizeXchange.Web.UI.WebControls.CategoryTreeNode = function(owner, dataItem) {
  this._dataItem = dataItem;
  this._nodes = null;
  this._levels = null;
  this._owner = owner;
  this._parentNode = null;
  this._level = (owner ? 0 : -1);
  
  this._container = null;
  this._outerContainer = null;
  
  this._childrenShown = false;
  
  this._nameElement_onclick_delegate = Function.createDelegate(this, this._nameElement_onclick);
}
SizeXchange.Web.UI.WebControls.CategoryTreeNode.prototype = {
  setProperty: function(propName, value, changedCallback) {
    if (this["_" + propName] != value) {
      var oldValue = this["_" + propName];
      this["_" + propName] = value;
      if (changedCallback) {
        changedCallback.apply(this, [oldValue, value]);
      };
    };
  },
  get_dataItem: function() {
    return this._dataItem;
  },
  set_dataItem: function(value)  {
    this.setProperty("dataItem", value);
  },
  addNode: function(node) {
    if (!this._nodes)
      this._nodes = [];
    Array.add(this._nodes, node);
    node.set_parentNode(this);
    this._refreshOwner();
    return node;
  },
  clearNodes: function()  {
    this._nodes = null;
    this._refreshOwner();
  },
  addLevel: function(level) {
    if (!this._levels)
      this._levels = [];
    Array.add(this._levels, level);
    this._refreshOwner();
    return level;
  },
  clearLevels: function() {
    this._levels = null;
    this._refreshOwner();
  },
  get_owner: function() {
    return this._owner;
  },
  _refreshOwner: function() {
    if (this._owner) {
      this._owner.tryRefresh(this);
    };
  },
  _nameElement_onclick: function(e) {
    if (this._owner)  {
      this._raiseEvent("select", e);
    };
  },
  add_Select: function(handler) {
    this.get_events().addHandler('select', handler);
  },
  remove_Select: function(handler) {
    this.get_events().removeHandler('select', handler);
  },
  add_Expand: function(handler) {
    this.get_events().addHandler('expand', handler);
  },
  remove_Expand: function(handler) {
    this.get_events().removeHandler('expand', handler);
  },
  add_Collapse: function(handler) {
    this.get_events().addHandler('collapse', handler);
  },
  remove_Collapse: function(handler) {
    this.get_events().removeHandler('collapse', handler);
  },
  get_parentNode: function()  {
    return this._parentNode;
  },
  set_parentNode: function(value) {
    this.setProperty("parentNode", value, function(oldVal, newVal)  {
      if (newVal) {
        this._level = newVal.get_level() + 1;
      }
      else {
        this._level = (this._owner ? 0 : -1);
      };
    });
  },
  get_level: function() {
    return this._level;
  },
  get_events: function() {
    if (!this._events) {
      this._events = new Sys.EventHandlerList();
    }
    return this._events;
  },
  _ensureContainer: function()  {
    if (!this._container && this._itemElement) {
      this._outerContainer = $j(this._itemElement)
                            .dom("div").attr("class", "subcategories")[0];
      Sys.UI.DomElement.setVisible(this._outerContainer, false);
      this._container = $j(this._outerContainer)
                              .dom("ul")[0];
    };
    return this._container;
  },
  render: function(index, levelIndex, level)  {
    var $ele = $j("body").dom("li").addClass(level.formatItemClass(levelIndex));
    var $name = $ele.dom("div").addClass(level.get_nameClass())
    var $link;
    if (level.get_isLink()) {
      $link = $name.dom("a").attr("href", level.formatUrl(this._dataItem));
    };
    var span = ($link ? $link : $name).dom("span").text(level.formatName(this._dataItem))[0];
    $addHandler(span, "click", this._nameElement_onclick_delegate);
    if (level.get_isLink() && this._nodes && this._nodes.length > 0)  {
      $name.dom("img").attr("src", level.get_showAllImageUrl()).attr("alt", level.formatShowAll(this._dataItem));
    };
    this._itemElement = $ele.remove()[0];
    return this._itemElement;
    //this._itemElement = level.render(this, index, (this._nodes && this._nodes.length > 0));
  },
  _raiseEvent: function(eventName, eventArgs) {
    /// <summary>
    /// Raises an event.
    /// </summary>
    /// <param name="eventName" type="String">The event name.</param>
    /// <param name="eventArgs" type="Sys.EventArgs">The event arguments.</param>
    /// <returns></returns>
    var handler = this.get_events().getHandler(eventName);
    if (handler) {
      if (!eventArgs) {
        eventArgs = Sys.EventArgs.Empty;
      }
      handler(this, eventArgs);
    }
  },
  get_childrenShown: function() {
    return this._childrenShown;
  },
  showChildren: function(showing) {
    if (this._outerContainer) {
      Sys.UI.DomElement.setVisible(this._outerContainer, showing);
      this._childrenShown = showing;
    };
  }
}
SizeXchange.Web.UI.WebControls.CategoryTreeNode.registerClass("SizeXchange.Web.UI.WebControls.CategoryTreeNode", null, SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer);

SizeXchange.Web.UI.WebControls.CategoryTreeView = function(element) {
  SizeXchange.Web.UI.WebControls.CategoryTreeView.initializeBase(this, [element]);

  this._nodes = null;
  this._levels = null;
  this._nodeElements = null;
  this._defaultLevel = new SizeXchange.Web.UI.WebControls.CategoryTreeLevel();
  
  this._updatingItems = false;
  this._requiresRefresh = true;
  this._nodesNeedingRefresh = [];
  
  this._node_onselect_delegate = null;
  this._node_onexpand_delegate = null;
  this._node_oncollapse_delegate = null;
}

SizeXchange.Web.UI.WebControls.CategoryTreeView.prototype = {
  initialize: function()  {
    SizeXchange.Web.UI.WebControls.CategoryTreeView.callBaseMethod(this, 'initialize');
    
    if (!this._nodes)
      this._nodes = [];
      
    if (!this._levels)
      this._levels = [];
      
    this._nodeElements = [];

    this._node_onselect_delegate = Function.createDelegate(this, this._node_onselect);
    this._node_onexpand_delegate = Function.createDelegate(this, this._node_onexpand);
    this._node_oncollapse_delegate = Function.createDelegate(this, this._node_oncollapse);
	  
	  this.refresh();
    
    this._applyHandlers();
  },
  dispose:  function()  {
    //this._clearHandlers();
    SizeXchange.Web.UI.WebControls.CategoryTreeView.callBaseMethod(this, 'dispose');
  },
  _applyHandlers: function()  {
  },
  _clearHandlers: function()  {
    //debugger;
    /*for (var i = 0; i < this._nodeElements.length; i++) {
      $clearHandlers(this._nodeElements[i]);
    }*/
  },
  setProperty: function(propName, value, changedCallback) {
    if (this["_" + propName] != value) {
      var oldValue = this["_" + propName];
      this["_" + propName] = value;
      if (changedCallback) {
        changedCallback.apply(this, [oldValue, value]);
      };
    };
  },
  addNode: function(node) {
    if (!this._nodes)
      this._nodes = [];
    Array.add(this._nodes, node);
    node.set_parentNode(null);
    this.tryRefresh(null);
    return node;
  },
  clearNodes: function()  {
    this._nodes = null;
  },
  addLevel: function(level) {
    if (!this._levels)
      this._levels = [];
    Array.add(this._levels, level);
    return level;
  },
  clearLevels: function() {
    this._levels = null;
  },
  createNode: function(dataItem)  {
    return new SizeXchange.Web.UI.WebControls.CategoryTreeNode(this, dataItem);
  },
  _clearDisplay: function() {
    //debugger;
    /*for (var element in this._nodeElements) {
      
    }
    for (var i = 0; i < this._nodeElements.length; i++) {
      
      for (var j = 0; j < this._itemElements[i].length; j++) {
        $j(this._itemElements[i][j]).remove();
      }
    }*/
    this._nodeElements = [];
  },
  beginUpdateItems: function()  {
    this._updatingItems = true;
  },
  clear: function() {
    this._clearDisplay();
    this._disposeItems();
    this._items = [];
    this._sortedItems = null;
    this._selectedItems = [];
  },
  endUpdateItems: function()  {
    this._updatingItems = false;
    if (this._requiresRefresh && this._isInitialized) {
      this.refresh();
    };
  },
  _findElementForNode: function(node) {
    if (!node) return null;
    var levelIndex = node.get_level();
    var nodeIndex = Array.indexOf((levelIndex > 0 ? node.get_parentNode()._nodes : this._nodes), node)
    return this._nodeElements[levelIndex][nodeIndex];
  },
  _ensureContainer: function()  {
    if (!this._container) {
	    var ele = this.get_element();
	    this._container = $j(ele).parent()
	                                 .dom("ul")[0];
	  };
	  return this._container;
  },
  refresh: function(startNode) {
    //debugger;
    //return;
    var startNodeElement = this._findElementForNode(startNode);
    var eles = this._renderNodes((startNode ? startNode._nodes : this._nodes), null, this._nodeElements);
    if (eles) {
	    var $container;
	    if (!startNodeElement)  {
	      $container = $j(this._ensureContainer());
	    }
	    else  {
	      $container = $j(startNode._ensureContainer());
	    };
	    for (var i = 0; i < eles.length; i++) {
	      $container.append(eles[i]);
	    }
    };
    if (startNode)  {
      Array.remove(this._nodesNeedingRefresh, startNode);
    };
    if (this._nodesNeedingRefresh.length == 0)  {
      this._requiresRefresh = false;
    };
  },
  _renderNodes: function(nodes, parentNode, nodeElements) {
    if (!nodes) return;
    var newElements = [];
    for (var i = 0; i < nodes.length; i++)  {
      var level = this._defaultLevel;
      var levelIndex = nodes[i].get_level();
      if (this._levels.length > levelIndex) {
        level = this._levels[levelIndex];
      };
      var parentNode = nodes[i];
      var levels;
      while (parentNode = parentNode.get_parentNode() && (levels = parentNode._levels))  {
        if (levels && levels.length > (levelIndex - (parentNode.get_level() + 1)))  {
          level = levels[levelIndex - (parentNode.get_level() + 1)];
        }; 
      }
      var nodeElement = nodes[i].render(i, levelIndex, level);
      if (!nodeElements[levelIndex])
        nodeElements[levelIndex] = [];
      nodeElements[levelIndex][i] = nodeElement;
      nodes[i].add_Select(this._node_onselect_delegate);
      Array.add(newElements, nodeElement);
      this.refresh(nodes[i]);
    }
    return newElements;
  },
  tryRefresh: function(startNode)  {
    if (!this._updatingItems) {
      this.refresh(startNode);
    }
    else  {
      Array.add(this._nodesNeedingRefresh, startNode);
    };
  },
  _node_onselect: function(sender, e) {
    if (sender._nodes && sender._nodes.length > 0)  {
	    var parent = sender.get_parentNode();
	    parent = (parent ? parent : this);
	    var state = sender.get_childrenShown();
	    for (var i = 0; i < parent._nodes.length; i++)  {
	      parent._nodes[i].showChildren(false);
	    }
	    if (!state)  {
	      sender.showChildren(true);
	    };
	    e.preventDefault();
	  };
  },
  _node_onexpand: function(sender, e) {
    debugger;
  },
  _node_oncollapse: function(sender, e) {
    debugger;
  },
  get_defaultLevel: function()  {
    return this._defaultLevel;
  },
  set_defaultLevel: function(value) {
    this.setProperty("defaultLevel", value);
  }
}

SizeXchange.Web.UI.WebControls.CategoryTreeView.registerClass("SizeXchange.Web.UI.WebControls.CategoryTreeView", Sys.UI.Control, SizeXchange.Web.UI.WebControls.ICategoryTreeNodeContainer);

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();
