/** 
  IAFx v 0.1
  Utility objects to handle script life cycle (loading, image preloading, init and so on)
  
  (c) 2006 Giorgio Maone - g.maone@informaction.com
  License: GNU
*/


var LifeCycle = {
  handlers: [],
  installed: false,
  triggered: false,
  runOnLoad: function(handler) {
    this.install();
    this.handlers[this.handlers.length] = handler;
  },
  install: function() {
    if(this.installed) return;
    this.installed = true;
    
    /* for Mozilla/Opera9 */
    if (document.addEventListener) {
      document.addEventListener("DOMContentLoaded", LifeCycle.onload, false);
    }
    
    /* for Internet Explorer */
    /*@cc_on @*/
    /*@if (@_win32)
      document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
      var script = document.getElementById("__ie_onload");
      script.onreadystatechange = function() {
        if (this.readyState == "complete") {
          LifeCycle.onload(); // call the onload handler
        }
      };
    /*@end @*/

    /* for Safari */
    if (/WebKit/i.test(navigator.userAgent)) { // sniff
      this.timer = setInterval(function() {
        if (/loaded|complete/.test(document.readyState)) {
          LifeCycle.onload(); // call the onload handler
        }
      }, 10);
    }
    
    if(window.onload) {
      this.runOnload(window.onload);
    }
    /* for other browsers */
    window.onload = LifeCycle.onload;
  },
  
  
  onload: function() {
    LifeCycle.callHandlers();
  },
  
  callHandlers: function(ev) {
    if(this.triggered) return;
    this.triggered = true;
    if (this.timer) {
      clearInterval(this.timer);
      this.timer = null;
    }

    for(var j = 0; j < this.handlers.length; j++) {
      try {
        this.handlers[j]();
      } catch(e) {}
    }
  }
};

function IAPreloader(callback, progress) {
  this.callback = callback;
  this.progress = arguments.length > 1 ? (progress || null) : IAPreloader.defaultProgress;
  this.images = [];
  var self = this;
  LifeCycle.runOnLoad(function() {
    self.domOnLoad();
  });
}

IAPreloader.prototype = {
  images: null,
  ready: false,
  readyCount: 0,
  callbackCalled: false,
  callback: null,
  add: function(src) {
    
    var image = new Image();
    this.images[this.images.length] = image;
    image._src = src;
    image._preloader = this;
    image.onload = this.imageOnload;
    return image;
  },
  chainCallback: function(callback, insertBefore) {
    if(!this.callback) {
      this.callback = callback; 
    } else {
      var currentCallback = this.callback;
      this.callback = 
        insertBefore ? function() { callback(); currentCallback(); }
               :  function() { currentCallback(); callback(); };
    }
  },
  start: function() {
    for(var j = this.images.length; j-- > 0;) {
      this.images[j].src = this.images[j]._src;
    }
  },
  imageOnload: function() {
    this._preloaded = true;
    this._preloader.checkAll();
  },
  domOnLoad: function() {
    this.domLoaded = true;
    if(this.callbackCalled || !(this.ready && this.callback)) return;
    this.callback();
    this.callbackCalled = true;
  },
  
  checkAll: function() {
    this.readyCount++;
    
    for(var j = this.images.length; j-- > 0;) {
      if(!this.images[j]._preloaded) break;
    }
    if(j < 0 && this.callback) {
      if(this.progress) this.progress.hide();
      this.ready = true;
      if(this.domLoaded && !this.callbackCalled) this.callback();
    } else {
      if(this.progress) this.progress.show(this.readyCount / this.images.length);
    }
  }
}

IAPreloader.defaultProgress = {
  show: function(percent, label) {
    var p = document.getElementById("progress");
    if(!p) return;
    p.style.display = "block";
    var pb = document.getElementById("progress-bar");
    if(!pb) return;
    if(!label) label = "Loading...";
    label = Math.ceil(percent * 100) + "% " + label;
    IAFlashes.setOpacity(p, Math.floor(Math.sin(percent * Math.PI) * 100));
    pb.innerHTML = label;
    document.getElementById("progress-label").innerHTML = label;
    pb.style.clip = "rect(0px " + (p.offsetWidth * percent) + "px 20px 0px)"; 
  },
  hide: function() {
    var p = document.getElementById("progress");
    if(p) p.style.display = "none";
  }
};

var IAFlashes = {
  flashes: {},
  startFlash: function(id) { this.flashes[id] = 0; this.doFlash(); },
  stopFlash: function(id) { if(id in this.flashes) delete this.flashes[id]; },
  isFlashing: function(id) { return (id in this.flashes); },
  doFlash: function() {
    var el, lum;
    for(var id in IAFlashes.flashes) {
      IAFlashes.flashes[id] = (IAFlashes.flashes[id] + 1) % 20;
      el = document.getElementById(id);
      if(!el) continue;
      IAFlashes.setOpacity(el, Math.floor(Math.sin(IAFlashes.flashes[id] * Math.PI / 20) * 100));
      el.style.visibility = "visible";
    }
    if(id) {
      window.setTimeout(IAFlashes.doFlash, 100); 
    }
  },
  setOpacity: function(el, o) {
    el.style.opacity = o / 100;
    el.style.filter = "alpha(opacity="+ o +")";
  }
};



