//@require(browser/compat, dom/base, dom/element, js/core)
var Effect = {}

Effect.Appear = Class.create({
  initialize: function(element) {
    extend(this, {element:$(element),start:0,finish:100});
    this.current = this.start;
    this.fade();
  },
  fade: function() {
    if(this.isFinished())return;
    if(this.timer)clearTimeout(this.timer);
    Element.setOpacity(this.element,this.current,true);this.current += 10;
    this.timer = setTimeout(this.fade.bind(this),50);
  },
  isFinished: function() {
    return this.current > this.finish;
  }
});

Effect.ContentZoom = Class.create({
  initialize: function(element, percent) {
    var o = this.element = $(element);
    if(o.style.fontSize == '')this.sizeEm = 1.0;
    if(o.style.fontSize.indexOf('em') > 0)this.sizeEm = parseFloat(o.style.fontSize);
    if(o.effect_contentzoom)this.sizeEm = o.effect_contentzoom.sizeEm;
    o.effect_contentzoom = this;
    o.style.fontSize = this.sizeEm * (percent/100) +'em';
    if(browser.safari)o.scrollTop -= 1;
  }
});

Effect.Fade = Class.create({
  initialize: function(element) {
    extend(this, {element:$(element),start:100,finish:0});
    this.current = this.start;
    this.fade();
  },
  fade: function() {
    if(this.isFinished()){this.element.style.display = 'none';return;}
    if(this.timer)clearTimeout(this.timer);
    Element.setOpacity(this.element,this.current);this.current -= 10;
    this.timer = setTimeout(this.fade.bind(this),50);
  },
  isFinished: function() {
    return this.current <= this.finish;
  }
});

Effect.Highlight = Class.create({
  initialize: function(element) {
    extend(this, {element:$(element),start:153,finish:255});
    this.current = this.start;
    this.fade();
  },
  fade: function() {
    if(this.isFinished())return;
    if(this.timer)clearTimeout(this.timer);
    this.highlight(this.element,this.current);this.current += 17;
    this.timer = setTimeout(this.fade.bind(this),250);
  },
  isFinished: function() {
    return this.current > this.finish;
  },
  highlight: function(element, current) {
    element.style.backgroundColor = "#ffff" + current.toColorPart();
  }
});
Number.prototype.toColorPart = function(){var d=this.toString(16);return (this<16?'0'+d:d);}

Effect.Puff = Class.create({
  initialize: function(element) {
    var o = this.element = $(element);
    extend(this, {opacity:100,startTop:(o.top||o.offsetTop),startLeft:(o.left||o.offsetLeft)});
    new Effect.Scale(this.element,200,{step:this.fade.bind(this),complete:this.hide.bind(this)});
  },
  fade: function(effect) {
    topd = (((effect.currentScale)*effect.startHeight) - effect.startHeight)/2;
    leftd = (((effect.currentScale)*effect.startWidth) - effect.startWidth)/2;
    this.element.style.position = 'absolute';
    this.element.style.top = this.startTop-topd +'px';
    this.element.style.left = this.startLeft-leftd +'px';
    this.opacity -= 10;
    Element.setOpacity(this.element,this.opacity); 
    if(browser.safari)this.element.innerHTML += ''; //force redraw on safari
  },
  hide: function() {
    this.element.style.display = 'none';
  }
});

Effect.Scale = Class.create({
  initialize: function(element, percent) {
    var o = this.element = $(element);
    extend(this, {
      startScale:  1.0,
      startHeight: o.offsetHeight,
      startWidth:  o.offsetWidth,
      finishScale: (percent/100),
      options: (arguments[2]||{})
    });
    this.currentHeight = this.startHeight;
    this.currentWidth  = this.startWidth;
    if(o.style.fontSize == '')this.sizeEm = 1.0;
    if(o.style.fontSize.indexOf('em') > 0)this.sizeEm = parseFloat(o.style.fontSize);
    if(o.effect_scale){
      var scale = o.effect_scale;clearTimeout(scale.timer);
      this.startScale  = scale.currentScale;
      this.startHeight = scale.startHeight;
      this.startWidth  = scale.startWidth;
      if(scale.sizeEm)this.sizeEm = scale.sizeEm;
    }
    o.effect_scale = this;
    this.currentScale = this.startScale;
    this.factor = this.finishScale - this.startScale;
    this.scale();
  },
  scale: function() {
    if(this.isFinished()){ 
      this.setDimensions(this.element,this.startWidth*this.finishScale,this.startHeight*this.finishScale);
      if(this.sizeEm)this.element.style.fontSize = this.sizeEm*this.finishScale +'em';
      if(this.options.complete)this.options.complete(this);
      return; 
    }
    if(this.timer)clearTimeout(this.timer);
    if(this.options.step)this.options.step(this);
    this.setDimensions(this.element,this.currentWidth,this.currentHeight);
    if(this.sizeEm)this.element.style.fontSize = this.sizeEm*this.currentScale +'em';
    this.currentScale += (this.factor/10);
    this.currentWidth = this.startWidth * this.currentScale;
    this.currentHeight = this.startHeight * this.currentScale;
    this.timer = setTimeout(this.scale.bind(this),50);
  },
  isFinished: function() {
    return (this.factor < 0) ? 
      this.currentScale <= this.finishScale : this.currentScale >= this.finishScale;
  },
  setDimensions: function(element, width, height) {
    element.style.width = width + 'px';
    element.style.height = height + 'px';
  }
});

Effect.Squish = Class.create({
  initialize: function(element) {
    this.element = $(element);
    new Effect.Scale(this.element,1,{complete:this.hide.bind(this)});
  },
  hide: function() {
    this.element.style.display = 'none';
  } 
});