/*
  WhyBlack RunEffect library
  Copyright 2009 Jakub Caban WhyBlack
  Licence: Commercial. Modifications and redistribution of core library (not including Effects library) not allowed. Redistribution of Effects library not allowed. Modifications of Effects library only allowed on pages shiped by Whyblack.
*/

/* CORE LIBRARY */

var Runners = [];
var Runner;
var IE, IE6;

function RunEffect(el, effect, obj){
  if(!Effects[effect]) return;
  if(typeof(el) !== "object"){
    if(el[0] == "#"){
      if(!(el = document.getElementById(el.substring(1,el.length)))) return;
    }else return;
  }
  if(typeof(obj) !== "object") obj = {};
  el.effect = new Effects[effect];
  el.effect.el = el;
  LoadConf(el.effect,obj,'speed',1000);
  LoadConf(el.effect,obj,'callback',null);
  LoadConf(el.effect,obj,'stepcall',null);
  if(typeof(el.effect.conf) === 'object')
    for(var i in el.effect.conf) LoadConf(el.effect,obj,i,el.effect.conf[i]);
  
  if(typeof(el.effect.Pre) === "function") el.effect.Pre();
  
  el.finished = false;
  var time = Number(new Date());
  if(obj.delay) time += obj.delay;
  el.effect.last = time;
  el.effect.start = time;
  AddRunner(el);
}

function AddRunner(el){
  for(var i=0; i<Runners.length; i++) if(Runners[i] === el) RemoveRunner(el);
  Runners.push(el);
  if(Runners.length == 1) Runner = setInterval(function(){RunEffects()},10);
}
function RemoveRunner(el){
  for(var i=0; i<Runners.length; i++)
    if(Runners[i] === el){
      Runners.splice(i,1);
      break;
    }
  if(!Runners.length) clearInterval(Runner);
}

function RunEffects(){
  var el;
  var t = Number(new Date());
  for(var i=0;i<Runners.length; i++){
    if(t >= Runners[i].effect.start){
      el = Runners[i];
      el.effect.Run(t-el.effect.start, t-el.effect.last);
      el.effect.last = t;
      if(typeof(el.effect.stepcall) === "function"){
	el.effect.stepcall(el, Math.min(el.effect.speed, t-el.effect.start));
      }
      StopEffect(el, false);
    }
  }
}

function StopEffect(el){
  if(el.effect.finished){
    RemoveRunner(el);
    if(typeof(el.effect.Post) === "function") el.effect.Post();
    if(el.effect.callback) var callback = el.effect.callback;
    el.effect = undefined;
    if(typeof(callback) == 'function') callback(el);
  }
}

function LoadConf(el, conf, key, val){
  if(typeof(conf[key]) !== 'undefined') el[key] = conf[key];
  else el[key] = val;
}

function changeOpac(obj,opacity){
  if(!obj || !obj.style) return;
  obj.style.opacity=(opacity/100);
  obj.style.MozOpacity=(opacity/100);
  obj.style.KhtmlOpacity=(opacity/100);
  obj.style.filter="alpha(opacity="+opacity+")";
}

/* EFFECTS LIBRARY */

var Effects = {
  "fadeIn": function(){
    this.conf = {"min": 0, "max": 100},
    this.Pre = function(){
      if(!this.el.style.opacity) changeOpac(this.el,0);
    },
    this.Run = function(t,tt){
      var opac = parseInt(Math.min(this.el.style.opacity*100+tt*(this.max-this.min)/this.speed,this.max),10);
      changeOpac(this.el, opac);
      if(opac >= this.max) this.finished = true;
    }
  },
  "fadeOut": function(){
    this.conf = {"min": 0, "max": 100},
    this.Pre = function(){
      if(!this.el.style.opacity) changeOpac(this.el,100);
    },
    this.Run = function(t,tt){
      var opac = parseInt(Math.max(this.el.style.opacity*100-tt*(this.max-this.min)/this.speed,this.min),10);
      changeOpac(this.el, opac);
      if(opac <= this.min) this.finished = true;
    }
  },
  "slideIn": function(){
    this.conf = {"min": 0, "max": 100, "measure": '%', "prop": 'width'},
    this.Pre = function(){
      if(!this.el.style[this.prop]) this.el.style[this.prop] = this.min+this.measure;
    },
    this.Run = function(t,tt){
      var wid = parseInt(this.el.style[this.prop],10);
      wid = Math.round(Math.min(wid+tt*(this.max-this.min)/this.speed,this.max));
      this.el.style[this.prop] = wid+this.measure;
      if(wid >= this.max) this.finished = true;
    }
  },
  "slideOut": function(){
    this.conf = {"min": 0, "max": 100, "measure": '%', "prop": 'width'},
    this.Pre = function(){
      if(!this.el.style[this.prop]) this.el.style[this.prop] = this.max+this.measure;
    },
    this.Run = function(t,tt){
      var wid = parseInt(this.el.style[this.prop],10);
      wid = Math.round(Math.max(wid-tt*(this.max-this.min)/this.speed,this.min));
      this.el.style[this.prop] = wid+this.measure;
      if(wid <= this.min) this.finished = true;
    },
    this.Post = function(){
      this.el.style[this.prop] = null;
    }
  },
  "titIn": function(){
    this.conf = {"min": 0, "max": 158, "from": [255, 255, 255], "to": [255, 255, 255]},
    this.Pre = function(){
      if(!this.el.style.width) this.el.style.width = '158px';
      if(!this.el.style.color) this.el.style.color = "rgb( "+this.from[0]+", "+this.from[1]+", "+this.from[2]+" )";
    },
    this.Run = function(t,tt){
      var wid = parseInt(this.el.style.width,10);
      wid = Math.round(Math.max(wid-tt*(this.max-this.min)/this.speed,this.min));
      
      var col = this.el.style.color.replace(/rgb\(|\)| /g,'').split(',');
      for(var i=0; i<3; i++){
	col[i] = Math.round(Math.min(parseInt(col[i],10)+tt*(this.to[i]-this.from[i])/this.speed,this.to[i]));
      }
      
      this.el.style.width = wid+'px';
      this.el.style.color = "rgb( "+col[0]+", "+col[1]+", "+col[2]+" )";
      if(wid <= this.min) this.finished = true;
    }
  },
  "titOut": function(){
    this.conf = {"min": 0, "max": 158, "from": [255, 255, 255], "to": [255, 255, 255]},
    this.Pre = function(){
      if(!this.el.style.width) this.el.style.width = '0px';
      if(!this.el.style.color) this.el.style.color = "rgb( "+this.to[0]+", "+this.to[1]+", "+this.to[2]+" )";
    },
    this.Run = function(t,tt){
      var wid = parseInt(this.el.style.width,10);
      wid = Math.round(Math.min(wid+tt*(this.max-this.min)/this.speed,this.max));
      
      var col = this.el.style.color.replace(/rgb\(|\)| /g,'').split(',');
      for(var i=0; i<3; i++){
	col[i] = Math.round(Math.max(parseInt(col[i],10)-tt*(this.to[i]-this.from[i])/this.speed,this.from[i]));
      }
      
      this.el.style.width = wid+'px';
//       this.el.style.color = "rgb( "+col[0]+", "+col[1]+", "+col[2]+" )";
      if(wid >= this.max) this.finished = true;
    },
    this.Post = function(){
      this.el.style.color = "rgb( "+this.from[0]+", "+this.from[1]+", "+this.from[2]+" )";
    }
  },
  "move": function(){
    this.conf = {"f": function(r){return 0.5-Math.cos(Math.PI*r)/2}, "from": null, "to": 0},
    this.Pre = function(){
      if(this.from === null) this.from = parseInt(this.el.style.left,10);
    },
    this.Run = function(t,tt){
      var ratio = this.f(Math.min(1,t/this.speed));
      this.el.style.left = Math.round(this.from+(this.to-this.from)*ratio)+'px';
      if(ratio >= 1) this.finished = true;
    }
  }
};
