<?xml version="1.0"?>
<!--
    ***** BEGIN LICENSE BLOCK *****
    
    Copyright © 2011 Center for History and New Media
                     George Mason University, Fairfax, Virginia, USA
                     http://zotero.org
    
    This file is part of Zotero.
    
    Zotero is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    Zotero is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.
    
    You should have received a copy of the GNU Affero General Public License
    along with Zotero.  If not, see <http://www.gnu.org/licenses/>.
    
    ***** END LICENSE BLOCK *****
-->

<bindings 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">
	
	<binding id="guidancepanel">
		<resources>
			<stylesheet src="chrome://zotero/skin/bindings/guidancepanel.css"/>
		</resources>
		
		<implementation>
			<property name="panel" onget="return document.getAnonymousNodes(this)[0]"/>
			
			<!--
			  @param {Object} [options]
			  @param {String} [options.text] - Text to use in place of firstRunGuidance.<about>
			  @param {DOMElement} [options.forEl] - Anchor node
			  @param {Boolean} [options.force] - Show even if already shown, and don't update
			                                     firstRunGuidanceShown.<about> pref
			-->
			<method name="show">
				<parameter name="options"/>
				<body>
				<![CDATA[
					Components.utils.import("resource://gre/modules/Services.jsm");
					if(!Zotero.Prefs.get("firstRunGuidance")) return;
					
					options = options || {};
					let text = options.text;
					let useLastText = options.useLastText || false;
					let forEl = options.forEl || document.getElementById(this.getAttribute("for"));
					let force = options.force || false;
					
					if (!forEl) return;
					// Don't show two panels at once
					if (Zotero.guidanceBeingShown) {
						return;
					}
					
					var about = this.getAttribute("about");
					var pref = false;
					if (about) {
						pref = "firstRunGuidanceShown." + about;
						let shown = false;
						try {
							shown = Zotero.Prefs.get(pref);
						} catch(e) {};
						if (shown && !force) {
							return;
						}
					}
					
					Zotero.guidanceBeingShown = true;
					
					var x = this.getAttribute("x"),
						y = this.getAttribute("y"),
						position = this.getAttribute("position");
					
					if (!useLastText) {
						if (!text) {
							text = Zotero.getString("firstRunGuidance." + about);
						}
						text = text.split("\n");
						var descriptionNode = this.id('panel-description');
						
						while (descriptionNode.hasChildNodes()) {
							descriptionNode.removeChild(descriptionNode.firstChild);
						}
						
						while(text.length) {
							var textLine = text.shift();
							descriptionNode.appendChild(document.createTextNode(textLine));
							if(text.length) descriptionNode.appendChild(document.createElementNS(
								"http://www.w3.org/1999/xhtml", "br"));
						}
					}
					
					this.setAttribute(
						"onpopuphidden",
						"this.hidden = true; "
							+ "Zotero.guidanceBeingShown = false; "
							+ (this.getAttribute("onpopuphidden") || "")
					);
					
					this._initNavButton('back', options.back);
					this._initNavButton('forward', options.forward);
					
					var self = this;
					var f = function() {
						if (self.hasAttribute("foregroundonly") && Services.ww.activeWindow != window) return;
						
						// Hide panel if content page changes
						if (self.getAttribute('hideonpagechange') == "true") {
							let popupShownListener = function () {
								self.removeEventListener("popupshown", popupShownListener);
								
								let appcontent = document.getElementById('appcontent');
								let pageHideListener = function (event) {
									var doc = event.originalTarget;
									if(!(doc instanceof HTMLDocument)) return;
									
									var rootDoc = doc.defaultView.top.document;
									// Don't hide when frames and special URLs are unloaded
									if (rootDoc != doc || !rootDoc.location.href.startsWith('http')) {
										return;
									}
									appcontent.removeEventListener("pagehide", pageHideListener);
									self.hide();
								};
								appcontent.addEventListener("pagehide", pageHideListener);
							};
							self.addEventListener("popupshown", popupShownListener);
						}
						
						self.hidden = false;
						self.panel.openPopup(forEl, position ? position : "after_start",
							x ? parseInt(x, 10) : 0, y ? parseInt(y, 10) : 0, false, false, null);
						if (pref) {
							Zotero.Prefs.set(pref, true);
						}
					};
					
					if(this.hasAttribute("delay") && !force) {
						window.setTimeout(f, this.getAttribute("delay"));
					} else {
						f();
					}

					if (this.getAttribute("noautohide") == 'true'
							&& !this.hasAttribute('forward')) {
						let listener = function () {
							this.panel.removeEventListener("click", listener);
							this.panel.hidePopup();
						}.bind(this);
						this.panel.addEventListener("click", listener);
					}
				]]>
				</body>
			</method>
			
			<method name="hide">
				<body>
				<![CDATA[
					document.getAnonymousNodes(this)[0].hidePopup();
				]]>
				</body>
			</method>
			
			<method name="_initNavButton">
				<parameter name="dir"/>
				<parameter name="nextID"/>
				<body><![CDATA[
					if (!nextID) {
						nextID = this.getAttribute(dir);
					}
					if (!nextID) {
						return;
					}
					var nextElem = document.getElementById(nextID);
					button = this.id(dir + '-button');
					button.hidden = false;
					var target;
					// If there's a forward action and no back action, the whole panel triggers
					// the forward in noautohide mode
					if (dir == 'forward' && !this.hasAttribute('back')
							&& this.getAttribute('noautohide') == 'true') {
						target = this.panel;
					}
					else {
						target = button;
					}
					var listener = function (event) {
						target.removeEventListener("click", listener);
						this.hide();
						var data = {
							force: true
						};
						// Point the next panel back to this one
						data[dir == 'back' ? 'forward' : 'back'] = this.getAttribute('id');
						// When going backwards, don't regenerate text
						if (dir == 'back') {
							data.useLastText = true;
						}
						nextElem.show(data);
						event.stopPropagation();
					}.bind(this);
					target.addEventListener("click", listener);
				]]></body>
			</method>
			
			<method name="id">
				<parameter name="id"/>
				<body><![CDATA[
					return document.getAnonymousNodes(this)[0].getElementsByAttribute('anonid', id)[0];
				]]></body>
			</method>
		</implementation>
		
		<content>
			<xul:panel type="arrow" align="top" xbl:inherits="noautohide">
				<xul:stack>
					<xul:hbox align="center">
						<xul:image src="chrome://zotero/skin/zotero-new-z-48px.png" style="margin-right: 10px; width: 48px; height: 48px;"/>
						<xul:description anonid="panel-description" flex="1"></xul:description>
					</xul:hbox>
					<xul:hbox anonid="close-button-box">
						<xul:toolbarbutton anonid="close-button" class="close-icon" hidden="true"/>
					</xul:hbox>
					<xul:hbox anonid="nav-buttons">
						<xul:toolbarbutton anonid="back-button" oncommand="hide()" hidden="true"/>
						<xul:toolbarbutton anonid="forward-button" oncommand="hide()" hidden="true"/>
					</xul:hbox>
				</xul:stack>
			</xul:panel>
		</content>
	</binding>
</bindings>
