<?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="tabcontrol" extends="xul:box">
    <content orient="vertical"/>
    <!-- pass-through implementation -->
    <implementation>
      <property name="selectedTab">
        <setter>
        <![CDATA[
          if (!val)
            throw Components.results.NS_ERROR_NULL_POINTER;
          var tabbox = this.getElementsByTagNameNS(
							"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
							"tabbox");
          tabbox = tabbox.length ? tabbox[0] : null;
          if (tabbox)
            tabbox.selectedTab = val;
          return val;
        ]]>
        </setter>
        <getter>
        <![CDATA[
          var tabbox = this.getElementsByTagNameNS(
							"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
							"tabbox");
          tabbox = tabbox.length ? tabbox[0] : null;
          return tabbox ? tabbox.selectedTab : null;
        ]]>
        </getter>
      </property>
    </implementation>
    <handlers>
    <handler event="keypress" keycode="vk_tab" modifiers="control">
      <![CDATA[
       var tabbox = this.getElementsByTagNameNS(
                                                "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                "tabbox");
       tabbox = tabbox.length ? tabbox[0] : null;
       if (tabbox)
         tabbox.advanceSelectedTab(1);
       ]]>
    </handler>
    <handler event="keypress" keycode="vk_tab" modifiers="control,shift">
      <![CDATA[
       var tabbox = this.getElementsByTagNameNS(
                                                "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                "tabbox");
       tabbox = tabbox.length ? tabbox[0] : null;
       if (tabbox)
         tabbox.advanceSelectedTab(-1);
       ]]>
    </handler>
    </handlers>
  </binding>

  <binding id="tabbox" extends="xul:box">
    <implementation>
      <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 tabpanel = this.parentNode.getElementsByTagNameNS(
                               "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                               "tabpanel");
          tabpanel = tabpanel.length ? tabpanel[0] : null;
          if (tabpanel)
            tabpanel.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>
	  <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>
    </implementation>
  </binding>
  
  <binding id="tabpanel" extends="xul:deck">
    <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" extends="xul:button">
    <content>
      <xul:box class="tab-box" flex="1" autostretch="never" orient="horizontal">
        <xul:image class="tab-image" inherits="src"/>
        <xul:text class="tab-text" inherits="value,accesskey,crop,disabled"/>
      </xul:box>
    </content>
    <implementation>
      <property name="value">
        <getter>
          return this.getAttribute("value");
        </getter>
        <setter>  
          this.setAttribute("value", val);
          return val;
        </setter>
      </property>
      <property name="tabbox" 
                onget="return this.getAttribute('tabbox');"
                onset="this.setAttribute('tabbox', 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 tabbox = this.parentNode;
        do {
          if (tabbox.localName == "tabbox")
            break;
          tabbox = tabbox.parentNode;
        } while(tabbox.localName != "tabcontrol");
        tabbox.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>

