(function($, undefined) {

  var $document = $(document);

  function MultiTopImageSwitcher(e, mti, options) {

    var AnimationSteps = 65;
    var AnimationWidth = 31;

    var self = this;
    var $list = $('<ol class="multi-top-image-switcher"></ol>');
    var current = 0;
    var $items;
    var $addLi;

    function setBackground($elements, step) {
      $elements.css({
        'background-image': 'url('+ options.switcherImage + ')',
        'background-position': -(step * AnimationWidth) + 'px 0px',
        'background-repeat': 'no-repeat'
      });
    }

    function updateAnimation(currentStep) {
      var $item = $items.eq(current);
      var $div = $item.find('div');

      setBackground($div, currentStep);

      if (currentStep == AnimationSteps) {
        $div.hide();
      }
      else if ($div.is(':hidden')) {
        $div.fadeIn('fast');
      }
    }

    function update() {
      $list.empty();

      for (var i = 1; i <= options.items.length; i++) {
        $list.append('<li><div></div><span>'+i+'</span></li>');
      }

      $items = $('li', $list[0]);
      $addLi = $('li.multi-top-image-add', $list[0]);

      $items.find('div, span').css({
        'position': 'absolute',
        'top': '0px',
        'left': '0px',
        'width': '100%',
        'height': '100%'
      });

      var $divs = $items.find('div');
      $divs.css('display', 'none');
      setBackground($items, AnimationSteps - 1);
      setBackground($divs, 0);
    }

    update();

    if (options.items.length <= 1) {
      return;
    }

    $list.appendTo(e);
    $list.bind({
      mouseenter: function () {
        mti.stop();
      },
      mouseleave: function () {
        mti.start();
      }
    });

    $items.live('click', function (event) {
      var $target = $(event.currentTarget);
      var index = $target.index();

      self.stop();

      if (!options.items[current].isEditingBounds) {
        if ($target.is('.multi-top-image-add')) {
          mti.addItem();
        }
        else {
          mti.next(index);
        }
      }

      event.stopPropagation();
    });

    self.options = options;
    self.update = update;

    self.start = function (duration) {
      var currentStep = 0;
      var $span = $items.eq(current).find('span');

      function step() {
        updateAnimation(currentStep);
        currentStep++

        if (currentStep > AnimationSteps) {
          self.stop();
          $span.fadeIn('fast', function() {
            mti.next();
          });
        }
        else {
          self.timer = window.setTimeout(step, (duration / AnimationSteps));
        }
      }

      self.stop();
      $span.fadeOut('fast', step);
    };

    self.stop = function () {
      if (self.timer) {
        window.clearTimeout(self.timer);
        self.timer = null;
      }
    };

    self.show = function () {
      $list.fadeIn();
    }

    self.hide = function () {
      $list.fadeOut();
    }

    self.current = function (newCurrent) {
      if (newCurrent !== undefined) {
        var $old = $items.eq(current);
        $old.removeClass('multi-top-image-current');
        $old.find('div').hide();
        $old.find('span').show();

        current = newCurrent;

        var $new = $items.eq(current);
        $new.addClass('multi-top-image-current');
        updateAnimation(0);
      }

      return current;
    };

    self.item = function (index) {
      return $items.eq(index);
    };
  }

  function MultiTopImage(e, options) {

    var current    = 0;
    var self       = this;
    var timer      = null;
    var parent     = e.parent();

    var elements   = $.map(options.items, format);

	// Here was error (mootools is cause)
    for (var i in elements) {
      //parent.append(elements[i]);
    }

	// My solution (because 'for in' is very vulnerable tool, especially with mootools)
	$.each(elements, function(index, value) { 
		parent.append(value);
	});

    var switcher = new MultiTopImageSwitcher(parent, self, options);
    switcher.current(0);

    function onAddItem() {
      var element = $('<div><a href=""><img alt="" /></a><div class="mtText"></div></div>');
      parent.append(element);
      elements.push(element);
      options.items.push({
        duration: 5000,
        imageHtml: '<a href=""><img alt="" /></a>',
        text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lobortis, diam eget posuere eleifend, velit magna luctus eros, sit amet elementum enim purus nec mauris. Phasellus pretium diam nec ipsum.',
        width: 100,
        height: 50,
        left: 10,
        top: 10
      });
      switcher.update();
      next(elements.length - 1);
    }

    function format(item, index) {
      var result = $('<div>' + item.imageHtml + '<div class="mtText">' + item.text + '</div></div>');

      result.css({
        position: 'absolute',
        visibility: (index == current) ? '' : 'hidden',
        top: 0,
        left: 0
      });

      result.find('.mtText').css({
        width: item.width + 'px',
        heigth: item.height + 'px',
        left: item.left + 'px',
        top: item.top + 'px',
        display: (/\<object/ig).test(item.imageHtml) ? 'none' : 'block'
      });

      return result;
    }

    function next(index, speed) {
      speed = speed || 'fast';

      if (index === undefined) {
        index = current + 1;
      }

      function callback() {
        scheduleNext();
      }

      if (index == current) {
        callback();
        return;
      }

      elements[current].fadeTo(speed, 0.0, function() {
        elements[current].css({
          'visibility': 'hidden',
          'width': '1px',
          'height': '1px'
        });

        current = index % elements.length;

        elements[current].css({
          'visibility': 'visible',
          'width': '',
          'height': ''
        });

        elements[current].fadeTo(speed, 1.0, function() {
          switcher.current(current);
          callback();
        });
      });
    }

    function scheduleNext() {
      if (options.items.length < 2) {
        return;
      }

      switcher.start(options.items[current].duration);
    }

    self.start = function() {
      scheduleNext();
    };

    self.stop = function() {
      switcher.stop();
    };

    self.next = function(index) {
      next(index);
    };

    self.addItem = function() {
      onAddItem();
    }

    self.hideSwitcher = function() {
      switcher.hide();
    }

    self.showSwitcher = function() {
      switcher.show();
    }

    e.remove();
    scheduleNext();
  }

  $.fn.multiTopImage = function() {
    var mti;
    var slice = Array.prototype.slice;

    if (typeof arguments[0] === 'string') {
      mti = this.data('multiTopImage');
      mti[arguments[0]].apply(mti, slice.call(arguments, 1));
    }
    else {
      mti = new MultiTopImage(this, arguments[0]);
      this.data('multiTopImage', mti);
    }

    return this;
  }

})(jQuery);
