<?xml version="1.0"?>

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

  <binding id="toolbar-base">
    <resources>
      <stylesheet src="chrome://global/skin/toolbar.css"/>
    </resources>
    <implementation implements="nsIAccessibleProvider">
      <property name="accessible">
        <getter>
          <![CDATA[
            var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
            if (this.localName == "toolbarseparator")
              return accService.createXULToolbarSeparatorAccessible(this);
            else
              return accService.createXULToolbarAccessible(this);
          ]]>
        </getter>
      </property>
    </implementation>
  </binding>
  
  <binding id="toolbox" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">  
    <implementation>
      <field name="palette">
        null
      </field>

      <field name="toolbarset">
        null
      </field>
      
      <field name="customToolbarCount">
        0
      </field>
      
      <constructor>
        <![CDATA[
          // Look to see if there is a toolbarset.
          this.toolbarset = this.firstChild;
          while (this.toolbarset && this.toolbarset.localName != "toolbarset")
            this.toolbarset = toolbarset.nextSibling;
          
          if (this.toolbarset) {
            // Create each toolbar described by the toolbarset.
            var index = 0;
            while (toolbarset.hasAttribute("toolbar"+(++index))) {
              var toolbarInfo = toolbarset.getAttribute("toolbar"+index);
              var infoSplit = toolbarInfo.split(":");
              this.appendCustomToolbar(infoSplit[0], infoSplit[1]);
            }
          }
        ]]>
      </constructor>
      
      <method name="appendCustomToolbar">
        <parameter name="aName"/>
        <parameter name="aCurrentSet"/>
        <body>
          <![CDATA[            
            var toolbar = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                  "toolbar");
            toolbar.id = "__customToolbar_" + aName.replace(" ", "_");
            toolbar.setAttribute("customizable", "true");
            toolbar.setAttribute("customindex", ++this.customToolbarCount);
            toolbar.setAttribute("toolbarname", aName);
            toolbar.setAttribute("currentset", aCurrentSet);
            toolbar.setAttribute("mode", this.getAttribute("mode"));
            toolbar.setAttribute("iconsize", this.getAttribute("iconsize"));
            toolbar.setAttribute("context", this.toolbarset.getAttribute("context"));
            toolbar.setAttribute("class", "chromeclass-toolbar");
            
            this.insertBefore(toolbar, this.toolbarset);
            return toolbar;
          ]]>
        </body>
      </method>
    </implementation>
  </binding>
  
  <binding id="toolbar" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">
    <implementation>
      <field name="firstPermanentChild">
        null
      </field>
      <field name="lastPermanentChild">
        null
      </field>
      
      <property name="toolbarName"
                onget="return this.getAttribute('toolbarname');"
                onset="this.setAttribute('toolbarname', val); return val;"/>
      
      <constructor>
        <![CDATA[
          this.firstPermanentChild = this.firstChild;
          this.lastPermanentChild = this.lastChild;
          
          // Searching for the toolbox palette in the toolbar binding because
          // toolbars are constructed first.
          var toolbox = this.parentNode;
          
          if (!toolbox.palette) {
            // Look to see if there is a toolbarpalette.
            var node = toolbox.firstChild;
            while (node) {
              if (node.localName == "toolbarpalette")
                break;
              node = node.nextSibling;
            }
            
            if (!node)
              return;

            // Hold on to the palette but remove it from the document.
            toolbox.palette = node;       
            toolbox.removeChild(node);
          }
          
          // Build up our contents from the palette.
          var currentSet = this.getAttribute("currentset");
          if (!currentSet)
            currentSet = this.getAttribute("defaultset");
          if (currentSet)
            this.currentSet = currentSet;
        ]]>
      </constructor>

      <property name="currentSet">
        <getter>
          <![CDATA[
            var node = this.firstChild;
            var currentSet = "";
            while (node) {
              if (node.id &&
                  node.localName == "toolbaritem" || 
                  node.localName == "toolbarbutton" ||
                  node.localName == "toolbarseparator" ||
                  node.localName == "toolbarspring" ||
                  node.localName == "toolbarspacer")
              {
                if (currentSet)
                  currentSet += ",";

                if (node.localName == "toolbarseparator")
                  currentSet += "separator";
                else if (node.localName == "toolbarspring")
                  currentSet += "spring";
                else if (node.localName == "toolbarspacer")
                  currentSet += "spacer";
                else
                  currentSet += node.id;
              }
              node = node.nextSibling;
            }
            
            return currentSet ? currentSet : "__empty";
          ]]>
        </getter>
        
        <setter>
          <![CDATA[
            // Remove all items before the first permanent child and after the last permanent child.
            while (this.lastChild) {
              if (this.lastChild == this.lastPermanentChild ||
                  (this.lastChild.localName == "toolbarpaletteitem" &&
                  this.lastChild.firstChild == this.lastPermanentChild))
                break;
              this.removeChild(this.lastChild);
            }

            while (this.firstChild) {
              if (this.firstChild == this.firstPermanentChild ||
                  (this.firstChild.localName == "toolbarpaletteitem" &&
                  this.firstChild.firstChild == this.firstPermanentChild))
                break;
              this.removeChild(this.firstChild);
            }

            var firstChildID = this.firstPermanentChild ? this.firstPermanentChild.id : "";
            var lastChildID = this.lastPermanentChild ? this.lastPermanentChild.id : "";

            if (val == "__empty")
              return;

            if (val) {
              var itemIds = val.split(",");
              var before = true;
              for (var i = 0; i < itemIds.length; i++) {
                if (itemIds[i] == firstChildID || itemIds[i] == lastChildID)
                  before = false;
                else
                  this.insertItem(itemIds[i], null, null, before);
              }
            }
          ]]>
        </setter>
      </property>
      
      <method name="insertItem">
        <parameter name="aId"/>
        <parameter name="aBeforeElt"/>
        <parameter name="aWrapper"/>
        <parameter name="aBeforePermanent"/>
        <body>
          <![CDATA[
            var newItem = null;
            
            // Create special cases of palette items.
            var uniqueId;
            if (aId == "separator") {
              newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                 "toolbarseparator");
              uniqueId = (new Date()).getTime()+this.childNodes.length;
              newItem.id = "separator" + uniqueId;
            } else if (aId == "spring") {
              newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                 "toolbarspring");
              uniqueId = (new Date()).getTime()+this.childNodes.length;
              newItem.flex = 1;
              newItem.id = "spring" + uniqueId;
            } else if (aId == "spacer") {
              newItem = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
                                                 "toolbarspacer");
              uniqueId = (new Date()).getTime()+this.childNodes.length;
              newItem.id = "spacer" + uniqueId;
            } else {
              // Attempt to locate an item with a matching id within palette.
              var paletteItem = this.parentNode.palette.firstChild;
              while (paletteItem) {
                var paletteId = paletteItem.id;
                if (paletteId == aId) {
                  newItem = paletteItem.cloneNode(true);
                  break;
                }
                paletteItem = paletteItem.nextSibling;
              }
            }
            
            if (!newItem)
              return false;

            var insertItem = newItem;
            
            // Wrap the item in another node if so inclined.
            if (aWrapper) {
              aWrapper.appendChild(newItem);
              insertItem = aWrapper;
            }
            
            // Insert the palette item into the toolbar.
            if (aBeforeElt)
              this.insertBefore(insertItem, aBeforeElt);
            else if (aBeforePermanent && this.firstPermanentChild)
                this.insertBefore(insertItem, this.firstPermanentChild);
            else
                this.appendChild(insertItem);
               
            return newItem;
          ]]>
        </body>
      </method>      
    </implementation>
  </binding>

  // for now, empty binding to deal with -moz-binding rules from communicator.css
  // (see bug 227993) we may need that binding one day to propagate
  // the text/icons/both state to other windows. If we don't, this binding
  // should be removed after we stop shipping the seamonkey communicator.css skin files.
  <binding id="toolbar-primary" extends="chrome://global/content/bindings/toolbar.xml#toolbar"/>

  <binding id="menubar" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base" display="xul:menubar">
    <implementation implements="nsIAccessibleProvider">
      <property name="accessible">
        <getter>
          <![CDATA[
            var accService = Components.classes["@mozilla.org/accessibilityService;1"].getService(Components.interfaces.nsIAccessibilityService);
            return accService.createXULMenubarAccessible(this);
          ]]>
        </getter>
       </property>
       <field name="_active">false</field>
       <field name="_statusbar">null</field>
       <field name="_originalStatusText">null</field>
       <property name="statusbar" onget="return this.getAttribute('statusbar');"
                                  onset="return this.setAttribute('statusbar', val)"/>
       <method name="updateStatusText">
          <parameter name="itemText"/>
          <body>
           <![CDATA[
            if (!this._active)
                return;
            var newText = itemText ? itemText : this._originalStatusText;
            if (newText != this._statusbar.label)
                this._statusbar.label = newText;
           ]]>
          </body>
        </method>
    </implementation>
    <handlers>
        <handler event="DOMMenuBarActive">
            if (!this.statusbar) return;
            this._statusbar = document.getElementById(this.statusbar);
            if (!this._statusbar)
                return;
            this._active = true;
            this._originalStatusText = this._statusbar.label;
        </handler>
        <handler event="DOMMenuBarInactive">
          <![CDATA[
            if (!this._active)
                return;
            this._active = false;
            this._statusbar.label = this._originalStatusText;
          ]]>
        </handler>
        <handler event="DOMMenuItemActive">this.updateStatusText(event.target.statusText);</handler>
        <handler event="DOMMenuItemInactive">this.updateStatusText("");</handler>
    </handlers>
  </binding>

  <binding id="toolbardecoration" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base"/>

  <binding id="toolbarpaletteitem" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base" display="xul:button">
    <content>
      <xul:hbox class="toolbarpaletteitem-box" flex="1" xbl:inherits="type,place">
        <children/>
      </xul:hbox>
    </content>
  </binding>
    
  <binding id="toolbarpaletteitem-palette" extends="chrome://global/content/bindings/toolbar.xml#toolbarpaletteitem">
    <content>
      <xul:hbox class="toolbarpaletteitem-box" xbl:inherits="type,place">
        <children/>
      </xul:hbox>
      <xul:label xbl:inherits="value=title"/>
    </content>
  </binding>

</bindings>          

