<?xml version="1.0"?>

<bindings id="tabBindings"
          xmlns="http://www.mozilla.org/xbl"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

  <binding id="tab-base">
    <resources>
      <stylesheet src="chrome://global/skin/tabbox.css"/>
    </resources>
  </binding>

  <binding id="tabbox" display="xul:box"
           extends="chrome://global/content/bindings/tabbox.xml#tab-base">
    <content orient="vertical"/>

    <implementation>
      <property name="selectedTab">
        <setter>
        <![CDATA[
          if (!val)
            throw Components.results.NS_ERROR_NULL_POINTER;
          var tabs = this.getElementsByTagNameNS(
              "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
              "tabs");
          tabs = tabs.length ? tabs[0] : null;
          if (tabs)
            tabs.selectedTab = val;
          return val;
        ]]>
        </setter>
        
        <getter>
        <![CDATA[
          var tabs = this.getElementsByTagNameNS(
              "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
              "tabs");
          tabs = tabs.length ? tabs[0] : null;
          return tabs ? tabs.selectedTab : null;
        ]]>
        </getter>
      </property>
    </implementation>
    
    <handlers>
      <handler event="keypress" keycode="vk_tab" modifiers="control">
        <![CDATA[
         var tabs = this.getElementsByTagNameNS(
                                                  "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                  "tabs");
         tabs = tabs.length ? tabs[0] : null;
         if (tabs)
           tabs.advanceSelectedTab(1);
         ]]>
      </handler>
      
      <handler event="keypress" keycode="vk_tab" modifiers="control,shift">
        <![CDATA[
         var tabs = this.getElementsByTagNameNS(
                                                  "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                  "tabs");
         tabs = tabs.length ? tabs[0] : null;
         if (tabs)
           tabs.advanceSelectedTab(-1);
         ]]>
      </handler>
    </handlers>
  </binding>

  <binding id="tabs" display="xul:box"
           extends="chrome://global/content/bindings/tabbox.xml#tab-base">
    <implementation>
      <constructor>
      <![CDATA[
        // first and last tabs need to be able to have unique styles
        // and also need to select first tab on startup.
        var tabs = this.getElementsByTagNameNS(
                      "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                      "tab");
        if (tabs.length) {
          if (tabs.length > 1) {
          tabs[0].setAttribute("first-tab", "true");
          tabs[tabs.length - 1].setAttribute("last-tab", "true");
          }
          else if (tabs.length == 1)
          tabs[0].setAttribute("first-tab", "true");
        }
        this.selectedTab = tabs[0];
        var o = this.getAttribute("orient");
        if (!o)
          this.setAttribute("orient", "horizontal");
      ]]>
      </constructor>
      
      <property name="selectedTab">
        <getter>
        <![CDATA[
          for (var i = 0; i < this.childNodes.length; i++) {
            if (this.childNodes[i].selected)
              return this.childNodes[i];
          }
          // throw an exception when no tab is selected (we shouldn't get here)
          throw Components.results.NS_ERROR_FAILURE;
        ]]>
        </getter>
        <setter>
        <![CDATA[
          if (!val)
            throw Components.results.NS_ERROR_NULL_POINTER;
          if (!val.selected)
            val.selected = true;
          var selectedIndex = 0;
          for (var i = 0; i < this.childNodes.length; i++) {
            if (this.childNodes[i].selected) {
              if (this.childNodes[i] != val)
                this.childNodes[i].selected = false;
              else 
                selectedIndex = i;
            }
          }
          var tabpanels = this.parentNode.getElementsByTagNameNS(
                               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                               "tabpanels");
          tabpanels = tabpanels.length ? tabpanels[0] : null;
          if (tabpanels)
            tabpanels.index = selectedIndex;
          return val;
        ]]>
        </setter>
      </property>
    
      <method name="advanceSelectedTab">
        <parameter name="aDir"/>
        <body>
        <![CDATA[
          var next = this.selectedTab[aDir == -1 ? "previousSibling" : "nextSibling"];
          if (next && !next.getAttribute("hidden")) {
            this.selectedTab = next;
            next.focus();
          }
        ]]>
        </body>
      </method>
    </implementation>
  </binding>
  
  <binding id="tabpanels" display="xul:deck"
           extends="chrome://global/content/bindings/tabbox.xml#tab-base">
    <implementation>
      <!-- should be defined on deck! -->
      <property name="index"
                onget="return this.getAttribute('index');"
                onset="this.setAttribute('index',val); return val;"/>
    </implementation>
  </binding>

  <binding id="tab" display="xul:button"
           extends="chrome://global/content/bindings/tabbox.xml#tab-base">
    <content>
      <xul:hbox class="tab-box" flex="1" align="center">
        <xul:image class="tab-image" inherits="src"/>
        <xul:text class="tab-text" inherits="value=label,accesskey,crop,disabled"/>
      </xul:hbox>
    </content>
    
    <implementation>
      <property name="label">
        <getter>
          return this.getAttribute("label");
        </getter>
        <setter>  
          this.setAttribute("label", val);
          return val;
        </setter>
      </property>

      <property name="tabs" 
                onget="return this.getAttribute('tabs');"
                onset="this.setAttribute('tabs', val); return val;"/>

      <!-- XXX -->                
      <property name="selected">
        <getter>
          return this.getAttribute("selected") == "true" ? true : false;
        </getter>
        <setter>
          this.setAttribute("selected",val);
          if (this.previousSibling) 
            this.previousSibling.setAttribute("beforeselected",val);
          if (this.nextSibling)
            this.nextSibling.setAttribute("afterselected",val);
          return val;
        </setter>
      </property>
    </implementation>
    
    <handlers>
      <handler event="click" button="0">
      <![CDATA[
        var tabs = this.parentNode;
        do {
          if (tabs.localName == "tabs")
            break;
          tabs = tabs.parentNode;
        } while(tabs.localName != "tabbox");
        tabs.selectedTab = this;
        if (!this.selected) this.selected = true;
      ]]>
      </handler>
      
      <handler event="keypress" keycode="vk_left">
      <![CDATA[
        this.parentNode.advanceSelectedTab(-1);
      ]]>
      </handler>
      
      <handler event="keypress" keycode="vk_right">
      <![CDATA[
        this.parentNode.advanceSelectedTab(1);
      ]]>
      </handler>
      
      <handler event="keypress" keycode="vk_up">
      <![CDATA[
        this.parentNode.advanceSelectedTab(-1);
      ]]>
      </handler>
      
      <handler event="keypress" keycode="vk_down">
      <![CDATA[
        this.parentNode.advanceSelectedTab(1);
      ]]>
      </handler>
    </handlers>
  </binding>
  
</bindings>

