<?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>
