function TabControl(node) {
  this.base = MoreMotionObject;
  this.base(node);
  this.isTabControl = true;
  this.getTabPanel = function(name) {
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabPanel");
    if (node) {
      node = OMgr.findChildNode(this.node.parentNode,null,"mo:name",name);
      if (node) return OMgr.getObject(node);
    }
    return null;
  };
  this.getTabPanels = function() {
    var panels = new Array();
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabPanelContainer",4);
    if (node) this._collectPanels(panels, node);
    else {
      node = OMgr.findChildNode(this.node,null,"mo:type","TabPanel");
      if (node) this._collectPanels(panels, node.parentNode.parentNode);
    }
    return panels;
  };
  this._collectPanels = function(panels, parentNode) {
    for (var i = 0; i < parentNode.childNodes.length; i++) {
      var node = parentNode.childNodes[i];
      if (node.nodeType == 1) {
        var attr = OMgr.getAttribute(node,"mo:type");
        if (attr) {
          if (attr == "TabPanel") {
            panels[panels.length] = OMgr.getObject(node);
          }
        } else if (node.hasChildNodes) {
          this._collectPanels(panels, node);
        }
      }
    }
  };
  this.getTabButtons = function() {
    var buttons = new Array();
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabButtonContainer");
    if (node) {
      this._collectButtons(buttons, node);
    }
    return buttons;
  };
  this._collectButtons = function(buttons, parentNode) {
    for (var i = 0; i < parentNode.childNodes.length; i++) {
      var node = parentNode.childNodes[i];
      if (node.nodeType == 1) {
        var attr = OMgr.getAttribute(node,"mo:type");
        if (attr) {
          if (attr.startsWith("TabButton")) {
            buttons[buttons.length] = OMgr.getObject(node);
          }
        } else if (node.hasChildNodes) {
          this._collectButtons(buttons, node);
        }
      }
    }
  };
  this.getSelectedTabName = function() {
    var buttons = this.getTabButtons();
    for (var i = 0; i < buttons.length; i++) {
      var button = buttons[i];
      if (button.boolProp("isSelected")) {
        return button.name;
      }
    }
    return null;
  };
  this.getParentTabControl = function() {
    var node = OMgr.findParentNode(this.node,"mo:type","TabControl");
    if (node) {
      return OMgr.getObject(node);
    }
    return null;
  };
  this.getTabButton = function(name) {
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabButtonContainer");
    if (node) {
      node = OMgr.findChildNode(this.node,null,"mo:name",name);
      if (node) return OMgr.getObject(node);
    }
    return null;
  };
  this.switchTo = function(tabName, recursive) {
    if (recursive) {
      var node = OMgr.findParentNode(this.node,"mo:type","TabPanel");
      if (node) {
        var panel = OMgr.getObject(node);
        node = OMgr.findParentNode(node,"mo:type","TabControl");
        OMgr.getObject(node).switchTo(panel.name,true);
      }
    }
    var panels = this.getTabPanels();
    for (var i = 0; i < panels.length; i++) {
      var panel = panels[i];
      var div = panel.node.nodeName.toUpperCase() == "DIV" ? panel.node : panel.node.parentNode;
      if (panel.name == tabName) {
        div.style.display = "block";
      } else {
        div.style.display = "none";
      }
    }
    var buttons = this.getTabButtons();
    for (var i = 0; i < buttons.length; i++) {
      var button = buttons[i];
      if (button.name == tabName) {
        button.select();
      } else {
        button.deselect();
      }
    }
    if (this.props && this.props.onTabSelectHandler) {
      var handler = new EventHandler(this.props.onTabSelectHandler, "onTabSelectHandler");
      return handler.run(this);
    }
  };
  this.setEvent = function(button, eventName, jsCode) {
    var s = "";
    eval("var event = button.node." + eventName);
    if (event) {
      s = event + "";
      s = s.after("{",s);
      s = s.beforeLast("}",s);
      if (s.indexOf(jsCode) > -1) return;
    }
    eval ("button.node." + eventName + " = function() { " + jsCode + s + " }");
  };
  this.setEvents = function() {
    var buttons = this.getTabButtons();
    for (var i = 0; i < buttons.length; i++) {
      var b = buttons[i];
      this.setEvent(b,"onmouseover","TabMgr.mouseOver(this);");
      this.setEvent(b,"onmouseout","TabMgr.mouseOut(this);");
      this.setEvent(b,"onmousedown","TabMgr.mouseDown(this);");
      this.setEvent(b,"onmouseup","TabMgr.mouseUp(this);");
    }
  };
  this.init = function() {
    this.setEvents();
    this.switchTo(this.props.initialTab);
  };
};
function TabPanel(node) {
  this.base = MoreMotionObject;
  this.base(node);
  this.isTabPanel = true;
};
function TabButton(node) {
  this.base = MoreMotionObject;
  this.base(node);
  this.isTabButton = true;
  this.select = function() {};
  this.deselect = function() {};
  this.setCaption = function(caption) {};
  this.mouseOver = function() {};
  this.mouseOut = function() {};
  this.mouseDown = function() {};
  this.mouseUp = function() {};
  this.getTabControl = function() {
    if (!this._tabControl) {
      var node = OMgr.findParentNode(this.node,"mo:type","TabControl");
      if (node) {
        this._tabControl = OMgr.getObject(node);
      }
    }
    return this._tabControl;
  };
};
function TabButtonFlex(node) {
  this.base = TabButton;
  this.base(node);
  this.isTabButtonFlex = true;
  this.setClass = function(classSuffix) {
    var classPrefix = this.getTabControl().props.classPrefix;
    if (classSuffix == "mt") {
      classSuffix = this.boolProp("isSelected") ? "s" : "n";
    }
    var buf = "";
    var classNames = this.node.className.split(' ');
    for (var i = 0; i < classNames.length; i++) {
      var cls = classNames[i];
      if (!cls.startsWith(classPrefix) ) {
        if (buf == "") buf = cls; else buf += " " + cls;
      }
    }
    this.node.className = buf + " " + classPrefix + "_" + classSuffix;
  };
  this.mouseOver = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.setClass("mo");
    }
  };
  this.mouseDown = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.setClass("md");
    }
  };
  this.mouseOut = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.setClass("mt");
    }
  };
  this.mouseUp = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.getTabControl().switchTo(this.name);
    }
  };
  this.select = function() {
    this.setClass("s");
    this.props.isSelected = true;
    this.saveProps();
  };
  this.deselect = function() {
    if(!this.boolProp("isDisabled")) this.setClass("n");
    this.props.isSelected = false;
    this.saveProps();
  };
  this.init = function() {
    this.node.style.cursor = "pointer";
    if(!this.boolProp("isDisabled")) this.setClass("n");
    this.setDisabled(this.props.isDisabled);
  };
};
function TabControlFlex(node) {
  this.props = null;
  this.base = TabControl;
  this.base(node);
  this.isTabControlFlex = true;
  this.init = function() {
    this.setEvents();
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabPanel");
    if (node) {
      this.setClass(node.parentNode.parentNode,this.props.classPrefix + "_ta");
    }
    var node = OMgr.findChildNode(this.node,null,"mo:type","TabButtonContainer");
    this.setClass(node,this.props.classPrefix + "_ba");
    this.switchTo(this.props.initialTab);
  };
  this.setClass = function(node, className) {
    node.className = node.className + " " + className;
  };
};
function TabButtonAnimated(node) {
  this.props = null;
  this.base = TabButton;
  this.base(node);
  this.isTabButtonAnimated = true;
  this.img = this.node;
  this.setDisabled = function(value) {
    if (value) {
      this.props.isDisabled = true;
      this.img.src = this.props.disabledSource;
      this.img.style.cursor = "default";
      this.savedOnclick = this.img.onclick;
      this.img.onclick = "";
    } else {
      this.props.isDisabled = false;
      this.img.src = this.props.normalSource;
      this.img.style.cursor = "pointer";
      if (!this.img.onclick || this.img.onclick == "") {
        this.img.onclick = this.savedOnclick || "";
      }
    }
  };
  this.setSources = function() {
    this.mouseOverImage = new Image();
    this.mouseOverImage.src = this.props.mouseOverSource;
    this.mouseDownImage = new Image();
    this.mouseDownImage.src = this.props.mouseDownSource;
    this.selectedImage = new Image();
    this.selectedImage.src = this.props.selectedSource;
    this.disabledImage = new Image();
    this.disabledImage.src = this.props.disabledSource;
  };
  this.select = function() {
    this.img.src = this.props.selectedSource;
    this.props.isSelected = true;
    this.saveProps();
  };
  this.deselect = function() {
    if(!this.boolProp("isDisabled")) this.img.src = this.props.normalSource;
    this.props.isSelected = false;
    this.saveProps();
  };
  this.mouseOver = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.img.src = this.props.mouseOverSource;
    }
  };
  this.mouseDown = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.img.src = this.props.mouseDownSource;
    }
  };
  this.mouseOut = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.img.src = this.props.normalSource;
    }
  };
  this.mouseUp = function() {
    if (!this.boolProp("isDisabled") && !this.boolProp("isSelected")) {
      this.getTabControl().switchTo(this.name);
    }
  };
  this.init = function() {
    this.img.style.cursor = "pointer";
    this.setSources();
    this.setDisabled(this.props.isDisabled);
  };
};
function TabManager() {
  this.current = null;
  this.getButton = function(node) {
    if (!this.current || this.current != node) {
      this.current = OMgr.getObject(node);
    }
    return this.current;
  };
  this.mouseOver = function(node) {
    var b = this.getButton(node);
    if (b) b.mouseOver();
  };
  this.mouseOut = function(node) {
    var b = this.getButton(node);
    if (b) b.mouseOut();
  };
  this.mouseDown = function(node) {
    var b = this.getButton(node);
    if (b) b.mouseDown();
  };
  this.mouseUp = function(node) {
    var b = this.getButton(node);
    if (b) b.mouseUp();;
  };
  this.getTabControl = function(name, node) {
    if (!node) node = document.body;
    var node = OMgr.findChildNode(node,"type:TabControl","mo:name",name);
    if (node) {
      return OMgr.getObject(node);
    }
    return null;
  };
  this.focusEnclosingTab = function(node) {
    var node = OMgr.findParentNode(node,"mo:type","TabPanel");
    if (node) {
      var panel = OMgr.getObject(node);
      node = OMgr.findParentNode(node,"mo:type","TabControl");
      OMgr.getObject(node).switchTo(panel.name,true);
    }
  };
  this.switchTo = function(tcName,tabName,node) {
    var tc = this.getTabControl(tcName,node);
    if (tc) tc.switchTo(tabName);
  };
};
var TabMgr = new TabManager();
