var Preloader = {
  images         : [],
  priorityImages : [],
  finished       : false,
  callbacks      : [],
  loadedImages   : [],
  imagesLoaded   : 0,

  add: function(src, id, priority) {
    if (priority) {
      this.priorityImages.push({ id : id, src : src });
    } else {
      this.images.push({ id : id, src : src });
    }
  },

  onFinish: function(callback) {
    this.callbacks.push(callback);
  },

  load: function() {
    var self = this;

    self.loadImages(self.priorityImages, function() {
      self.fireLoaded(self.priorityImages);
      self.fireFinish();
      self.loadImages(self.images, function() {
        self.finished = true;
        self.fireLoaded(self.images);
      });
    });
  },

  loadImages: function(images, callback) {
    var length = images.length;

    for (var i = 0; i < length; i++) {
      var index = this.loadedImages.length;

      this.loadedImages[index] = new Image();
      this.loadedImages[index].onload = function() {
        Preloader.checkFinished.apply(Preloader, [images, callback]);
      };
      this.loadedImages[index].src = images[i].src;
    }

    Preloader.checkFinished.apply(Preloader, [images, callback]);
  },

  checkFinished: function(images, callback) {
    this.imagesLoaded++;

    if (this.imagesLoaded >= images.length) {
      this.imagesLoaded = 0;

      callback();
    }
  },

  fireLoaded: function(images) {
    var length = images.length;

    for (var i = 0; i < length; i++ ){
      var image   = images[i];
      var element = document.getElementById(image.id);

      if (element) {
        element.src = image.src;
      }
    }
  },

  fireFinish: function() {
    for (var i = 0; i < this.callbacks.length; i++) {
      this.callbacks[i]();
    }
  }
};

