<?xml version="1.0"?>

# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
# 
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
# 
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
# 
# The Original Code is Mozilla.org Code.
# 
# The Initial Developer of the Original Code is.
# Portions created by the Initial Developer are Copyright (C) 2001
# the Initial Developer. All Rights Reserved.
# 
# Contributor(s):
#   Ben Goodger <ben@bengoodger.com> (v2.0) 
#   Blake Ross <blakeross@telocity.com>
# 
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
# 
# ***** END LICENSE BLOCK *****


<!DOCTYPE window [
  <!ENTITY % downloadDTD SYSTEM "chrome://mozapps/locale/downloads/downloads.dtd" >
  %downloadDTD;
  <!ENTITY % browserDTD  SYSTEM "chrome://browser/locale/browser.dtd" >
  %browserDTD;
]>

<bindings id="downloadBindings"
          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"
          xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

  <binding id="download-base">
    <resources>
      <stylesheet src="chrome://mozapps/skin/downloads/downloads.css"/>
    </resources>
    <implementation>
      <method name="fireEvent">
        <parameter name="aEventType"/>
        <body>
        <![CDATA[
          var e = document.createEvent("Events");
          e.initEvent("download-" + aEventType, false, true);
          
          this.dispatchEvent(e);
        ]]>
        </body>
      </method>
      <property name="paused">
        <getter>
        <![CDATA[
          return parseInt(this.getAttribute("state")) == Components.interfaces.nsIDownloadManager.DOWNLOAD_PAUSED;
        ]]>
        </getter>
      </property>
      <property name="openable">
        <getter>
        <![CDATA[
          return parseInt(this.getAttribute("state")) == Components.interfaces.nsIDownloadManager.DOWNLOAD_FINISHED;
        ]]>
        </getter>
      </property>
      <property name="inProgress">
        <getter>
        <![CDATA[
          var state = parseInt(this.getAttribute("state"));
          const dl = Components.interfaces.nsIDownloadManager;
          const xpi = Components.interfaces.nsIXPInstallManagerUI;
          return state == dl.DOWNLOAD_NOTSTARTED || 
                 state == dl.DOWNLOAD_DOWNLOADING || 
                 state == dl.DOWNLOAD_PAUSED ||
                 state == xpi.INSTALL_DOWNLOADING ||
                 state == xpi.INSTALL_INSTALLING;
        ]]>
        </getter>
      </property>
      <property name="removable">
        <getter>
        <![CDATA[
          var state = parseInt(this.getAttribute("state"));
          const dl = Components.interfaces.nsIDownloadManager;
          const xpi = Components.interfaces.nsIXPInstallManagerUI;
          return state == dl.DOWNLOAD_FINISHED || 
                 state == dl.DOWNLOAD_CANCELED || 
                 state == dl.DOWNLOAD_FAILED ||
                 state == xpi.INSTALL_FINISHED;
        ]]>
        </getter>
      </property>
      <property name="canceledOrFailed">
        <getter>
        <![CDATA[
          var state = parseInt(this.getAttribute("state"));
          var dl = Components.interfaces.nsIDownloadManager;
          return state == dl.DOWNLOAD_CANCELED || state == dl.DOWNLOAD_FAILED;
        ]]>
        </getter>
      </property>
      
      <method name="pauseResume">
        <body>
        <![CDATA[
          // Do nothing.
        ]]>
        </body>
      </method>
    </implementation>
  </binding>
  
  <binding id="download-starting" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
#ifdef XP_WIN
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&starting.label;"/>
        </xul:vbox>
        <xul:vbox pack="start">
          <xul:label value="&cmd.cancel.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('cancel');"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="download-downloading" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1" class="downloadContentBox" xbl:inherits="animated,animated-temp">
#ifdef XP_WIN
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox flex="1">
          <xul:hbox flex="1">
            <xul:vbox flex="1">
              <xul:label xbl:inherits="value=target" crop="center"/>
              <xul:progressmeter mode="normal" value="0" flex="1"
                                xbl:inherits="value=progress,mode=progressmode"/>
            </xul:vbox>
            <xul:vbox pack="start">
              <xul:label value="&cmd.cancel.label;" class="link"
                        onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.fireEvent('cancel');"/>          
            </xul:vbox>
          </xul:hbox>                              
          <xul:hbox align="center">
            <xul:label value="&cmd.pause.label;" class="link"
                       onclick="this.parentNode.parentNode.parentNode.parentNode.fireEvent('pause');"/>
            <xul:label xbl:inherits="value=status" flex="1" crop="right"/>
          </xul:hbox>                            
        </xul:vbox>
      </xul:hbox>
    </content>
    <implementation>
    
      <!-- ANIMATE: Type Icon -->    
      <property name="_ati_kTimeout" onget="return 50;"/>
      <property name="_ati_kUpperBounds" onget="return 90;"/>
      <property name="_ati_kLowerBounds" onget="return 30;"/>
      <property name="_ati_kIncrement" onget="return 5;"/>
      <field name="_atiStep">0</field>
      <field name="_atiIsIncrementing">true</field>
      <field name="_atiInterval">-1</field>
      
      <method name="_atiTimerCallback">
        <parameter name="aDownload"/>
        <parameter name="aIcon"/>
        <body>
        <![CDATA[
          if (aDownload.getAttribute("state") != "0") {
            clearInterval(aDownload._atiInterval)
            return;
          }
            
          if (aDownload._atiIsIncrementing)
            aDownload._atiStep += aDownload._ati_kIncrement;
          else
            aDownload._atiStep -= aDownload._ati_kIncrement;

          if (aDownload._atiStep == aDownload._ati_kUpperBounds) 
            aDownload._atiIsIncrementing = false;
          else if (aDownload._atiStep  == aDownload._ati_kLowerBounds)
            aDownload._atiIsIncrementing = true;

          aIcon.setAttribute("style", "-moz-opacity: 0." + aDownload._atiStep );
        ]]>
        </body>
      </method>
      <method name="_animateIcon">
        <body>
        <![CDATA[
          this._atiStep = this._ati_kLowerBounds;
          this._atiIsIncrementing = true;

          var icon = document.getAnonymousElementByAttribute(this, "class", "downloadTypeIcon");
          this._atiInterval = setInterval(this._atiTimerCallback, this._ati_kTimeout, this, icon);
        ]]>
        </body>
      </method>
      
      <!-- ANIMATE: Download -->
      <property name="_adl_kTimeout" onget="return 50;"/>
      <property name="_adl_kUpperBounds" onget="return 1.00;"/>
      <property name="_adl_kLowerBounds" onget="return 0.00;"/>
      <property name="_adl_kIncrement" onget="return 0.05;"/>
      <field name="_adlStep">0</field>
      
      <method name="_adlTimerCallback">
        <parameter name="aDownload"/>
        <parameter name="aContent"/>
        <body>
        <![CDATA[
          if (aDownload.getAttribute("state") != "0" || 
              aDownload._adlStep > aDownload._adl_kUpperBounds) {
            aDownload.fireEvent('animated');
            return;
          }

          // Don't even bother if we're going away. 
          if (!aContent.ownerDocument)
            return;
            
          aDownload._adlStep += aDownload._adl_kIncrement;
          aContent.setAttribute("style", "-moz-opacity: " + aDownload._adlStep + "!important;");
          
          setTimeout(aDownload._adlTimerCallback, aDownload._adl_kTimeout, aDownload, aContent);
        ]]>
        </body>
      </method>
      <method name="_animateDownload">
        <body>
        <![CDATA[
          this._adlStep = this._adl_kLowerBounds;

          var box = document.getAnonymousElementByAttribute(this, "class", "downloadContentBox");
          setTimeout(this._adlTimerCallback, this._adl_kTimeout, this, box);
        ]]>
        </body>
      </method>
      
      <method name="_shouldDownloadAnimate">
        <body>
        <![CDATA[
          return this.getAttribute("animated") != "true";
        ]]>
        </body>
      </method>
      
      <method name="pauseResume">
        <body>
        <![CDATA[
          this.fireEvent("pause");
        ]]>
        </body>
      </method>
      
      <constructor>
      <![CDATA[
        // this._animateIcon();
        if (this._shouldDownloadAnimate())
          this._animateDownload();
      ]]>
      </constructor>
    </implementation>
  </binding>
  
  <binding id="download-paused" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
#ifdef XP_WIN
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox flex="1">
          <xul:hbox flex="1">
            <xul:vbox flex="1">
              <xul:label xbl:inherits="value=target" crop="center"/>
              <xul:progressmeter mode="normal" value="0" flex="1"
                                xbl:inherits="value=progress,mode=progressmode"/>
            </xul:vbox>
            <xul:vbox pack="start">
              <xul:label value="&cmd.cancel.label;" class="link"
                        onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.fireEvent('cancel');"/>          
            </xul:vbox>
          </xul:hbox>                              
          <xul:hbox align="center">
            <xul:label value="&cmd.resume.label;" class="link"
                       onclick="this.parentNode.parentNode.parentNode.parentNode.fireEvent('resume');"/>
            <xul:label xbl:inherits="value=status" flex="1" crop="right"/>
          </xul:hbox>                            
        </xul:vbox>
      </xul:hbox>
    </content>
    <implementation>
      <method name="pauseResume">
        <body>
        <![CDATA[
          this.fireEvent("resume");
        ]]>
        </body>
      </method>
    </implementation>
  </binding>
  
  <binding id="download-done" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
#ifdef XP_WIN
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&done.label;"/>
        </xul:vbox>
        <xul:vbox pack="start">
          <xul:label value="&cmd.open.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('open');"/>
          <xul:label value="&cmd.remove.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('remove');"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="download-canceled" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
#ifdef XP_WIN
        <xul:vbox pack="start"> 
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&canceled.label;"/>
        </xul:vbox>
        <xul:vbox pack="start">
          <xul:label value="&cmd.retry.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('retry');"/>
          <xul:label value="&cmd.remove.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('remove');"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="download-failed" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
#ifdef XP_WIN
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
#endif
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&failed.label;"/>
        </xul:vbox>
        <xul:vbox pack="start">
          <xul:label value="&cmd.retry.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('retry');"/>
          <xul:label value="&cmd.remove.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('remove');"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="install-downloading" extends="chrome://mozapps/content/downloads/download.xml#download-downloading">
    <content>
      <xul:hbox flex="1" class="downloadContentBox" xbl:inherits="animated,animated-temp">
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
        <xul:vbox flex="1">
          <xul:hbox flex="1">
            <xul:vbox flex="1">
              <xul:label xbl:inherits="value=target" crop="center"/>
              <xul:progressmeter mode="normal" value="0" flex="1"
                                xbl:inherits="value=progress,mode=progressmode"/>
            </xul:vbox>
          </xul:hbox>                              
          <xul:hbox align="center">
            <xul:label xbl:inherits="value=status" flex="1" crop="right"/>
          </xul:hbox>                            
        </xul:vbox>
      </xul:hbox>
    </content>
  </binding>
  
  <binding id="install-installing" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&installing.label;"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="install-done" extends="chrome://mozapps/content/downloads/download.xml#download-base">
    <content>
      <xul:hbox flex="1">
        <xul:vbox pack="start">
          <xul:image class="downloadTypeIcon" validate="always" style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;" xbl:inherits="src=image"/>
        </xul:vbox>
        <xul:vbox pack="start" flex="1">
          <xul:label xbl:inherits="value=target" crop="center"/>
          <xul:label value="&done.label;"/>
        </xul:vbox>
        <xul:vbox pack="start">
          <xul:label value="&cmd.remove.label;" class="link" 
                     onclick="this.parentNode.parentNode.parentNode.fireEvent('remove');"/>
        </xul:vbox>
      </xul:hbox>
    </content>  
  </binding>
  
  <binding id="download-view">
    <implementation>
      <field name="_selected">null</field>
      <property name="selected">
        <setter>
        <![CDATA[
          if (this._selected)
            this._selected.removeAttribute("selected");
          this._selected = val;
          if (this._selected)
            this._selected.setAttribute("selected", "true");
        ]]>
        </setter>
        <getter>
        <![CDATA[
          return this._selected;
        ]]>
        </getter>
      </property>
      
      <method name="selectionForward">
        <parameter name="aEvent"/>
        <body>
        <![CDATA[
          if (this.selected) {
            if (this.selected.nextSibling &&
                this.selected.nextSibling.localName == "download")
              this.selected = this.selected.nextSibling;
          }
          else {
            if (this.hasChildNodes())
              this.selected = this.firstChild.nextSibling;
          }
        ]]>
        </body>
      </method>

      <method name="selectionBackward">
        <parameter name="aEvent"/>
        <body>
        <![CDATA[
          if (this.selected) {
            if (this.selected.previousSibling && 
                this.selected.previousSibling.localName == "download")
              this.selected = this.selected.previousSibling;
          }
          else {
            if (this.hasChildNodes())
              this.selected = this.lastChild;
          }
        ]]>
        </body>
      </method>
    </implementation>
    <handlers>
      <handler event="click">
      <![CDATA[
        if (event.ctrlKey) {
          this.selected = null;
          return;
        }
        
        this.selected = event.target;
      ]]>
      </handler>
      <handler event="keypress" keycode="vk_enter" action="if (this.selected) this.selected.fireEvent('open');"/>
      <handler event="keypress" keycode="vk_return" action="if (this.selected) this.selected.fireEvent('open');"/>
      <handler event="keypress" keycode="vk_up" action="this.selectionBackward(event);"/>
      <handler event="keypress" keycode="vk_left" action="this.selectionBackward(event);"/>
      <handler event="keypress" keycode="vk_down" action="this.selectionForward(event);"/>
      <handler event="keypress" keycode="vk_right" action="this.selectionForward(event);"/>
      <handler event="keypress" keycode="vk_up" modifiers="meta" action="this.selected = null"/>
      <handler event="keypress" keycode="vk_down" modifiers="meta" action="this.selected = null"/>
      <handler event="keypress" keycode="vk_left" modifiers="meta" action="this.selected = null"/>
      <handler event="keypress" keycode="vk_right" modifiers="meta" action="this.selected = null"/>
      <handler event="keypress" keycode="vk_delete" action="if (this.selected) this.selected.fireEvent('remove');"/>
      <handler event="keypress" key=" " action="if (this.selected) { this.selected.pauseResume(); }"/>
      <handler event="keypress" key="&newNavigatorCmd.key;" modifiers="control" action="parent.window.open('');"/>
    </handlers>
  </binding>
  
</bindings>
