<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl"
          xmlns:xbl="http://www.mozilla.org/xbl"
          xmlns:math="http://www.w3.org/1998/Math/MathML"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
          xmlns:mEdit="http://abacus.mozdev.org/namespaces/MathML-Editor/"
>

  <binding id="mEdit:integerControl">
    <content>
      <xul:hbox>
        <xul:textbox anonId="textbox" value="0" xbl:inherits="value,size=size,maxlength=size"/>
        <xul:vbox>
          <xul:scrollbarbutton type="increment" onclick="event.target.boundParent.increment();" anonId="incrementButton"/>
          <xul:scrollbarbutton type="decrement" onclick="event.target.boundParent.decrement();" anonId="decrementButton"/>
        </xul:vbox>
      </xul:hbox>
    </content>
    <implementation>
      <field name="textbox"         readonly="true">document.getAnonymousElementByAttribute(this, "anonId", "textbox")</field>
      <field name="incrementButton" readonly="true">document.getAnonymousElementByAttribute(this, "anonId", "incrementButton")</field>
      <field name="decrementButton" readonly="true">document.getAnonymousElementByAttribute(this, "anonId", "decrementButton")</field>
      <field name="size"            readonly="true">this.getAttribute("size") * 1</field>
      <field name="minValue"        readonly="true">this.hasAttribute("minvalue") ? this.getAttribute("minvalue") * 1 : 0</field>
      <field name="maxValue"        readonly="true">this.hasAttribute("maxvalue") ? this.getAttribute("maxvalue") * 1 : Math.pow(10, this.size)</field>
      <property name="value">
        <getter>return this.textbox.value * 1;</getter>
        <setter><![CDATA[
          if ((isNaN(val))||(Math.floor(val) != val)||(val < this.minValue)||(val >= this.maxValue)) {
            this.invalid = true;
          } else {
            this.invalid = false;
            this.textbox.value = val;
            this.updateDisableds();
          }
          return val;
        ]]></setter>
      </property>
      <field name="mInvalid">false</field>
      <property name="invalid">
        <getter>return this.mInvalid;</getter>
        <setter>
          if (val) {
            this.setAttribute("invalid", "true");
          } else {
            this.removeAttribute("invalid");
          }
          this.mInvalid = val;
          return val;
        </setter>
      </property>
      <field name="mDecrementDisabled">false</field>
      <property name="decrementDisabled">
        <getter>return this.mDecrementDisabled</getter>
        <setter>
          if (val) {
            this.decrementButton.setAttribute("disabled", "true");
          } else {
            this.decrementButton.removeAttribute("disabled");
          }
          this.mDecrementDisabled = val;
          return val;
        </setter>
      </property>
      
      <field name="mIncrementDisabled">false</field>
      <property name="incrementDisabled">
        <getter>return this.mIncrementDisabled</getter>
        <setter>
          if (val) {
            this.incrementButton.setAttribute("disabled", "true");
          } else {
            this.incrementButton.removeAttribute("disabled");
          }
          this.mIncrementDisabled = val;
          return val;
        </setter>
      </property>      
      <method name="updateDisableds">
        <body><![CDATA[
          var val = this.value;
          this.decrementDisabled = (val <= this.minValue);
          this.incrementDisabled = (val >= this.maxValue);
        ]]></body>
      </method>
      <method name="increment">
        <body>this.value += 1;</body>
      </method>
      <method name="decrement">
        <body>this.value -= 1;</body>
      </method>
      <constructor><![CDATA[
        this.incrementButton.boundParent = this;
        this.decrementButton.boundParent = this;
        this.updateDisableds();
        var val = this.value;
        if ((isNaN(val))||(Math.floor(val) != val)||(val < this.minValue)||(val >= this.maxValue)) {
          this.invalid = true;
        }
      ]]></constructor>
    </implementation>
    <handlers>
      <handler event="input" action="this.value = event.target.value;"/>
      <handler event="keypress" phase="capturing"><![CDATA[
        // If we have a one-character counter (0-9), then we should accept any single digit entered for the value.
        if ((this.size == 1)&&(event.charCode >= 48)&&(event.charCode < 58)) {
          this.value = event.charCode - 48;
        }
        if ((event.charCode == 43)&&(!this.incrementDisabled)&&(!this.invalid)) { // +
          this.increment();
        }
        if ((event.charCode == 45)&&(!this.decrementDisabled)&&(!this.invalid)) { // -
          this.decrement();
        }
      ]]></handler>
    </handlers>
  </binding>
</bindings>
