﻿function Preloader(am_options) {

 var o_self = this;
 var $o_preloader;
 var h_interval;
 var i_loop = 0;
 var am_positionTypeMemory = {};
 var i_startTime;

 var am_defaultOptions = {
  showSpeed: 'fast',
  hideSpeed: 1000,
  stepSpeed: 250,
  callbackOnInit: null,
  callbackOnStart: null,
  callbackOnShow: null,
  callbackOnStep: null,
  callbackOnStop: null,
  callbackOnHide: null,
  stopCondition: null,
  loopCounter: null,
  mode: 'flash'
 };

 am_options = $.extend({}, am_defaultOptions, am_options);

 this.setPreloader = function(m_preloader) {
  $o_preloader = $(m_preloader);
 };

 this.getPreloader = function() {
  return $o_preloader;
 };

 this.getStartTime = function() {
  return i_startTime;
 };

 this.start = function() {
  clear();

  if (!$o_preloader || $o_preloader.length == 0) $o_preloader = $('<div class="preloader"></div>').appendTo(document.body);

  if (am_options.callbackOnStart && $.isFunction(am_options.callbackOnStart)) am_options.callbackOnStart(o_self);

  i_loop = 0;
  h_interval = setInterval(step, am_options.stepSpeed);
  i_startTime = new Date().getTime();

  $o_preloader
   .show()
   .animate({opacity: 1}, am_options.showSpeed, function() {
    if (am_options.callbackOnShow && $.isFunction(am_options.callbackOnShow)) am_options.callbackOnShow();
   });
 };

 this.stop = function() {
  clear();

  if (am_options.callbackOnStop && $.isFunction(am_options.callbackOnStop)) am_options.callbackOnStop(o_self);
 };

 function step() {
  if (am_options.loopCounter && $.isFunction(am_options.loopCounter)) {
   if (am_options.loopCounter(o_self)) i_loop++;
  } else i_loop++;

  if (am_options.callbackOnStep && $.isFunction(am_options.callbackOnStep)) am_options.callbackOnStep(o_self);

  if (i_loop > 0 && am_options.stopCondition(o_self)) o_self.stop();
 }

 function clear() {
  clearInterval(h_interval);

  $o_preloader.fadeOut(am_options.hideSpeed, function() {
   if (am_options.callbackOnHide && $.isFunction(am_options.callbackOnHide)) am_options.callbackOnHide(o_self);
  });
 }

 function init() {
  if (am_options.mode && preloaderModes[am_options.mode]) am_options = $.extend({}, am_options, preloaderModes[am_options.mode]);

  if (am_options.callbackOnInit && $.isFunction(am_options.callbackOnInit)) am_options.callbackOnInit(o_self);

  if (!am_options.stopCondition || !$.isFunction(am_options.stopCondition)) am_options.stopCondition = function(o_self) {};
 }

 init();

 return this;

};

var preloaderModes = {

 'flash': {
  callbackOnInit: function(o_preloader) {
   o_preloader.setPreloader(
    $('<div class="preloader preloader-flash"></div>')
	 .css({opacity: 0})
	 .hide()
	 .appendTo($('#body'))
   );
  },
  callbackOnStart: function(o_preloader) {
   o_preloader.getPreloader().html($.flash.create({
    swf: $.GLOBALS.DIR_HTML + 'images/preloader.swf',
	width: 150,
    height: 150,
	params: {
     bgcolor: '#000000',
     loop: false,
     menu: false,
//     wmode: 'opaque'
     wmode: 'transparent'
	}
   }));
  },
  loopCounter: function(o_preloader) {
   return ((new Date().getTime()) - o_preloader.getStartTime()) > 3000;
  }
 }

};