<?xml version="1.0"?>

<!-- This Source Code is subject to the terms of the Mozilla Public License
   - version 2.0 (the "License"). You can obtain a copy of the License at
   - http://mozilla.org/MPL/2.0/. -->

<bindings id="progressBarBindings"
    xmlns="http://www.mozilla.org/xbl"
    xmlns:xbl="http://www.mozilla.org/xbl"
    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:html="http://www.w3.org/1999/xhtml">
  <binding id="progressBar">
    <content orient="horizontal" pack="center">
      <xul:stack flex="1">
        <html:canvas anonid="canvas" width="1" height="1"/>
        <children/>
      </xul:stack>
    </content>
    <implementation>
      <field name="_gapWidth">5</field>
      <field name="_arrowheadWidth">5</field>
      <field name="_canvas">document.getAnonymousElementByAttribute(this, "anonid", "canvas")</field>

      <constructor>
      <![CDATA[
        // Run _init() after window loads, correct sizes might be unknown during construction
        let me = this;
        let callback = function()
        {
          window.removeEventListener("load", callback, false);
          window.setTimeout(function() me._init(), 0);
        }
        window.addEventListener("load", callback, false);
      ]]>
      </constructor>

      <method name="_init">
        <body>
        <![CDATA[
          let canvas = this._canvas;
          let width = canvas.width = canvas.offsetWidth;
          let height = canvas.height = canvas.offsetHeight;
  
          let context = canvas.getContext("2d");
          context.fillStyle = window.getComputedStyle(this, "").color;
          context.strokeStyle = window.getComputedStyle(this, "").color;
          context.lineWidth = 1;
  
          let panelCount = this.childNodes.length;
          let panelWidth = (width - this._gapWidth * (panelCount - 1) - 1) / panelCount;
          for (let i = 0; i < panelCount; i++)
          {
            context.save();
            context.translate(Math.round(i * (panelWidth + this._gapWidth)) + 0.5, 0.5);
            context.beginPath();
            if (i)
              context.moveTo(-this._arrowheadWidth, 0);
            else
              context.moveTo(0, 0);
            context.lineTo(panelWidth - this._arrowheadWidth, 0);
            context.lineTo(panelWidth, (height - 1) / 2);
            context.lineTo(panelWidth - this._arrowheadWidth, height - 1);
            if (i)
            {
              context.lineTo(-this._arrowheadWidth, height - 1);
              context.lineTo(0, (height - 1) / 2);
              context.lineTo(-this._arrowheadWidth, 0);
            }
            else
            {
              context.lineTo(0, height - 1);
              context.lineTo(0, 0);
            }
            context.stroke();
            context.restore();

            let childLeft = Math.round(i * (panelWidth + this._gapWidth) + 1);
            let childWidth = panelWidth - this._arrowheadWidth - 2;
            let child = this.childNodes[i];
            child.style.marginLeft = childLeft + "px";
            child.style.marginRight = (width - childLeft - childWidth) + "px";
            child.style.width = childWidth + "px";
          }

          // Resize after initialization should be ignored
          canvas.parentNode.removeAttribute("flex");
        ]]>
        </body>
      </method>

      <property name="activeItem">
        <getter>
        <![CDATA[
          for (let i = 0; i < this.childNodes.length; i++)
          {
            let child = this.childNodes[i];
            if (/\bactive\b/.test(child.className))
              return child;
          }
          return null;
        ]]>
        </getter>

        <setter>
        <![CDATA[
          let complete = true;
          for (let i = 0; i < this.childNodes.length; i++)
          {
            let child = this.childNodes[i];
            if (child == val)
              complete = false;

            if (!complete && child.value[0] == "✔")
              child.value = child.value.replace(/^✔\s*/, "");
            else if (complete && child.value[0] != "✔")
              child.value = "✔ " + child.value;

            if (child != val && /\bactive\b/.test(child.className))
              child.className = child.className.replace(/\s*\bactive\b/, "");
            else if (child == val && !/\bactive\b/.test(child.className))
              child.className += " active";
          }
          return null;
        ]]>
        </setter>
      </property>

      <property name="activeItemComplete">
        <getter>
        <![CDATA[
          let activeItem = this.activeItem;
          if (!activeItem)
            return false;
          else
            return activeItem.value[0] == "✔";
        ]]>
        </getter>

        <setter>
        <![CDATA[
          let activeItem = this.activeItem;
          if (!activeItem)
            return;

          if (!val && activeItem.value[0] == "✔")
            activeItem.value = child.value.replace(/^✔\s*/, "");
          else if (val && activeItem.value[0] != "✔")
            activeItem.value = "✔ " + activeItem.value;
        ]]>
        </setter>
      </property>
    </implementation>
  </binding>
</bindings>
