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 changeOpacE(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},
    this.Pre = function(){
      if(!this.el.style.opacity) changeOpacE(this.el,0);
    },
    this.Run = function(t,tt){
      var opac = Math.round(Math.min(this.el.style.opacity*100+tt*(this.max-this.min)/this.speed,this.max));
      changeOpacE(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) changeOpacE(this.el,100);
    },
    this.Run = function(t,tt){
      var opac = Math.round(Math.max(this.el.style.opacity*100-tt*(this.max-this.min)/this.speed,this.min));
      changeOpacE(this.el, opac);
      if(opac <= this.min) this.finished = true;
    }
  }
};