//
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2009
// http://flock.com
//
// This file may be used under the terms of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// 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.
//
// END FLOCK GPL
//

// JMC - Need to save a queue of faders so we can clean up if the doc is going away while we're still working.
// TODO XXX

var gDomFx = {
  allFaders: [],
  fadeOut: function fadeOut(aElm, aListener) {
    var fader = new DomFader(aElm, aListener);
    fader.start();
    return fader;
  },

  fadeIn: function fadeIn(aElm, aListener) {
    var fader = new DomFader(aElm, aListener);
    fader.start(true);
    this.allFaders.push(fader);
    return fader;
  },

  collapse: function collapse(aElm, aListener, aOrientation, aSize) {
    var collapser = new DomCollapser(aElm, aListener, aOrientation, aSize);
    collapser.start();
    return collapser;
  },

  pulse: function pulse(aElm, aListener) {
    dump("JMC: Creating pulser on object " + aElm.id  + "...\n");
    var pulser = new DomPulser(aElm, aListener);
    dump("JMC: Starting pulser...\n");
    pulser.start();
    return pulser;
  },
  
  uninit: function uninit() {
    for (x in this.allFaders) {
      this.allFaders[x].cancel();
    }
  }
}

var DomFader = function df(aElm, aListener) {
  this._element = aElm;
  this._listener = aListener;
  this._opacity = null;
  this._endOpacity = null;
  this._timer = Components.classes["@mozilla.org/timer;1"]
                          .createInstance(Components.interfaces.nsITimer);
  this._done = false;
  this._dir = null;
}

DomFader.prototype = {
  start: function dfS(aShouldFadeIn) {
    if (aShouldFadeIn) {
      this._opacity = 0.0;
      this._dir = 1;
      this._endOpacity = 1.0;
    } else {
      this._opacity = 1.0;
      this._endOpacity = 0;
      this._dir = -1;
    }
    this._timer.initWithCallback(this, 35, 
                          Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  },

  notify: function dfRefresh() {
    this._opacity = this._opacity + (this._dir* 0.1);
    this._opacity.toFixed(4);
    var str = '-moz-opacity: ' + this._opacity + ';';
    //dump(str + '\n\n');
    if (this._element) this._element.setAttribute('style', str);
    if (!this._element || Math.abs(this._opacity - this._endOpacity)< 0.11) {
      this._timer.cancel();
      this.finish();
    }
  },

  finish: function dfF() {
    this._opacity = this._endOpacity;
    this._element.setAttribute('style', '-moz-opacity: ' + this._opacity + ';');
    var inst = this;
    var finishTimerFunc = {
      notify: function notify(aTimer) {
        //dump("\nReleasing fader ");
        var i = gDomFx.allFaders.indexOf(inst);
        if (i > -1) {
          gDomFx.allFaders.splice(i, 1);
        }
        inst.onComplete();
      }
    }
    this._timer.initWithCallback(finishTimerFunc, 200, 
                                 Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  },
  
  onComplete: function dfO() {
    if (this._listener) {
      this._listener.onComplete(this._element);
      this._listener = null;
    }
  },
  
  cancel: function dfCancel() {
    this._timer.cancel();
    this._opacity = this._endOpacity;
    if (this._element) {
      this._element.setAttribute('style', '-moz-opacity: ' + this._opacity + ';');
    }
    this.onComplete();
  }
}

var DomPulser = function dp(aElm, aListener) {
  this._element = aElm;
  this._innerButton = aElm.ownerDocument.getAnonymousElementByAttribute(aElm, "anonid", "button");
  this._innerElement = aElm.ownerDocument.getAnonymousElementByAttribute(this._innerButton, "anonid", "effects-image");
  this._listener = aListener;
  this._opacity = 1.0;
  this._scale = 1.0;
  this._max_scale = 1.5;
  this._timer = Components.classes["@mozilla.org/timer;1"]
                          .createInstance(Components.interfaces.nsITimer);
  this._stage = 0;
  if (this._innerElement) {
    this._stage = 1;
    this._original_rect = this._innerElement.style.MozImageRegion;
    dump ("JMC: " + this._original_rect + "\n");
  } else {
    dump ("JMC: Uh-oh... didn't get the inner element...\n");
  }
}

DomPulser.prototype = {
  start: function dpS(aElm) {
    this._innerElement.hidden = false;
    this._innerElement.setAttribute('hidden', false);
    this._timer.initWithCallback(this, 35, 
                          Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  },

  notify: function dpRefresh() {
    if (this._stage == 0) {
      this._timer.cancel()
      this.finish();
      return;
    }

    switch (this._stage) {
      case 1:
        this._scale = this._scale + 0.05;
        this._scale.toFixed(4);
        var str = "-moz-image-region: rect('";
        break;
      case 2:
        this._opacity = this._opacity - 0.1;
        this._opacity.toFixed(4);
        var str = '-moz-opacity: ' + this._opacity + ';';
        dump(str + '\n\n');
        this._innerElement.setAttribute('style', str);
        if (this._opacity < 0.11 || this._scale > this._max_scale) {
          this._stage = 0;
        }
    }
  },

  finish: function dpF() {
    var inst = this;
    this._opacity = 0.0;
    this._element.setAttribute('style', '-moz-opacity: ' + this._opacity + ';');
    var finishTimerFunc = {
      notify: function notify(aTimer) {
        inst._listener.onComplete(inst._element);
      }
    }
    this._timer.initWithCallback(finishTimerFunc, 200, 
                          Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  }
}

var DomCollapser = function dc(aElm, aListener, aOrient, aSize) {
  this._element = aElm;
  this._listener = aListener;
  this._orient = aOrient;
  this._size = parseInt(aSize);
  this._timer = Components.classes["@mozilla.org/timer;1"]
                          .createInstance(Components.interfaces.nsITimer);
  this._step = 0.1 * this._size;
}

DomCollapser.prototype = {
  start: function dcS(aElm) {
    this._timer.initWithCallback(this, 10, 
                          Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  },

  notify: function dcRefresh() {
    this._step = this._size * 0.1;
    this._size = this._size - this._step;
    this._element.removeAttribute('width');
    var str = 'width: ' + this._size + 'px;';
    //dump('str is ' + this._size + '\n\n\n');
    this._element.setAttribute('style', str);
    if (this._size < 1) {
      this._timer.cancel()
      this._timer = null;
      this.finish();
    }
  },

  finish: function dcF() {
    this._listener.onComplete(this._element);
  }
}
