var Runners = [];
var Runner;

function RunEffect(el, effect, obj){
  //if(IE) return true;
  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);
  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;
  el.effect.last = Number(new Date());
  el.effect.start = Number(new Date());
  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++){
    el = Runners[i];
    el.effect.Run(t-el.effect.start, t-el.effect.last);
    el.effect.last = t;
    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+")";
}

var Effects = {
  "fadeIn": function(){
    this.conf = {"min": 0, "max": 100, "bgimg": null},
    this.Pre = function(){
      if(!this.el.style.opacity) changeOpac(this.el,0);
      if(this.bgimg !== null) this.el.style.backgroundImage = 'url("/images/'+this.bgimg+'")';
    },
    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;
    }
  },
  "move": function(){
    this.conf = {"to": 0, "f":function(r){return r}},
    this.Pre = function(){
      this.left = parseInt(this.el.style.left,10)?parseInt(this.el.style.left,10):0;
    },
    this.Run = function(t,tt){
      var ratio = Math.min(t/this.speed,1);
      var left = this.left+this.f(ratio)*(this.to-this.left);
      this.el.style.left = parseInt(left,10)+'px';
      if(ratio >= 1) this.finished = true;
    }
  }
};
