var marqueeId = '';

function wmxMarquee()
{
	//Private variables
	var _marquee = null;
	var _marqueeSlides = new Array();  // marqueeSlides must be an Array containing only elements of type wmxMarqueeSlide
	var _marqueeSlideContainer = null;
	var _currentIndex = 0;
	var _transitionType = 
		{
			Fade: 		1,
			SlideDown: 	2,
			SlideUp: 	3,
			SlideLeft: 	4,
			SlideRight: 5
		};
	var _transition = 
		{
			time: 	1,
			scale: 	0.25,
			type: 	_transitionType.Fade,
			mode: 	'relative',
			func: 	function(){},
			fps:	20 // Defaults to 100 but 20 is good enough for the human eye and avoids unnecessary CPU usage.
		};
	var _delay =
		{
			executer: null,
			counter: 	0,
			paused: 	false
		};

	//Public properties	
	this.transitionTime = 1; // 1 (0.25s) --- 8 (2s)
	this.transitionTypeId = 1; // 1 - Fade, 2 - T->C, 3 - B->C, 4 - R->C, 5 - L->C
	this.delayTime = 8; // 1 (0.5s) --- 20 (10s)
	this.delayTimeScale = 0.5;
	this.height = null;
	this.width = null;
	this.name = '';

	this.initialize = function()
	{
		$$('.marqueeSlide' + this.name).each(function(slide)
		{
			_marqueeSlides.push(new wmxMarqueeSlide(slide));
		});

		this.initializeMarquee();

		_marqueeSlideContainer = $("MarqueeSlideContainer" + this.name);

		this.initializeTransition();

		this.initializeEvents();

		if (_marqueeSlides.size() > 0)
		{
			this.start();
		}
	};

	this.initializeMarquee = function()
	{
		if(!_marquee) _marquee = $("Marquee" + this.name);
		if(marqueeId == '') marqueeId = _marquee.id;

		_marqueeSlides.each(function(s){
			s.dimensions = {width: s.element.getWidth(), height: s.element.getHeight()};
		});

		var maxHeight = _marqueeSlides.max(function(slide) { return slide.dimensions.height; });
		var maxWidth = _marqueeSlides.max(function(slide) { return slide.dimensions.width; });
		this.height = _marquee.getHeight();
		this.width = _marquee.getWidth();
		this.height = (maxHeight > this.height) ? maxHeight : this.height;
		_marquee.setStyle({ height: this.height + 'px'});

		if (_marqueeSlides.size() > 0)
		{
			_marqueeSlides[0].element.setStyle({ top: ((this.height - _marqueeSlides[0].dimensions.height) * 0.5) + 'px' });
		}
	};

	this.initializeTransition = function()
	{
		_delay.counter = this.delayTime;
		_transition.time = this.transitionTime;

		switch (this.transitionTypeId)
		{
			case 2:	// Top to Center
				_marqueeSlides.each(function(slide)
					{
						slide.startPos.y = -slide.dimensions.height;
						slide.offset.y = (this.height - slide.dimensions.height)/2;
					}, this);
				_transition.mode = 'absolute';
				_transition.type = _transitionType.SlideDown;
				_transition.func = this.moveToCenter.bind(this);
				break;
			case 3:	// Bottom to Center
				_marqueeSlides.each(function(slide)
					{
						slide.startPos.y = this.height;
						slide.offset.y = (this.height - slide.dimensions.height)/2;
					}, this);
				_transition.mode = 'absolute';
				_transition.type = _transitionType.SlideUp;
				_transition.func = this.moveToCenter.bind(this);
				break;
			case 4:	// Right to Center
				_marqueeSlides.each(function(slide)
					{
						slide.startPos.y = (this.height - slide.dimensions.height)/2;
						slide.startPos.x = this.width;
						slide.offset.x = -this.width;
					}, this);
				_transition.type = _transitionType.SlideLeft;
				_transition.func = this.moveToCenter.bind(this);
				break;
			case 5:	// Left to Center
				_marqueeSlides.each(function(slide)
					{
						slide.startPos.y = (this.height - slide.dimensions.height)/2;
						slide.startPos.x = -this.width;
						slide.offset.x = this.width;
					}, this);
				_transition.type = _transitionType.SlideRight;
				_transition.func = this.moveToCenter.bind(this);
				break;
			case 1:	// Fade
			default:
				_marqueeSlides.each(function(slide)
					{
						slide.startPos.y = (this.height - slide.dimensions.height)/2;
						slide.resetPosition();
					}, this);
				_transition.type = _transitionType.Fade;
				_transition.func = this.Fade.bind(this);
				break;
		}
	};

	this.initializeEvents = function()
	{
		if(Prototype.Browser.IE)
		{
			_marqueeSlideContainer.observe('mouseenter', function(e){this.pause();}.bind(this));
			_marqueeSlideContainer.observe('mouseleave', function(e){this.start();}.bind(this));
		}
		else
		{
			_marqueeSlideContainer.observe('mouseover', function(e){this.pause();}.bind(this));
			_marqueeSlideContainer.observe('mouseout', function(e){this.start();}.bind(this));
		}
	};

	this.Fade = function(previousMarqueeSlide, marqueeSlide)
	{
		Effect.Fade(previousMarqueeSlide.element,
		{
			duration: this.getSeconds(_transition.time, _transition.scale) / 2,
			fps: _transition.fps,
			queue:
			{
				position: 'end',
				scope: this.name
			},
			afterFinish: function(effect)
			{
				Effect.Appear(marqueeSlide.element,
				{
					duration: this.getSeconds(_transition.time, _transition.scale) / 2,
					fps: _transition.fps,
					queue:
					{
						position: 'end',
						scope: this.name
					}
				})
			}.bind(this)
		});
	};

	this.moveToCenter = function(previousMarqueeSlide, marqueeSlide)
	{
		marqueeSlide.resetPosition();
		
		if(_marqueeSlides.size() > 1)
			previousMarqueeSlide.element.hide();
			
		marqueeSlide.element.show();
		
		new Effect.Move(marqueeSlide.element,
			{
				x: marqueeSlide.offset.x,
				y: marqueeSlide.offset.y,
				mode: _transition.mode,
				duration: this.getSeconds(_transition.time, _transition.scale),
				fps: _transition.fps,
				queue:
				{
					position: 'end',
					scope: this.name
				}
			});
	};

	this.getSeconds = function(time, scale)
	{
		return (time * scale);
	};

	this.currentSlide = function()
	{
		return _marqueeSlides[_currentIndex];
	}
	
	this.nextSlide = function()
	{
		_currentIndex++;
		_currentIndex = (_currentIndex < _marqueeSlides.size()) ? _currentIndex : 0;
		return _marqueeSlides[_currentIndex];
	};

	this.start = function()
	{
	  if (cmxbrowser.supportsDOM)
		{
			if(_delay.executer == null)
					_delay.executer = new PeriodicalExecuter(this.delayStep.bind(this), this.delayTimeScale);
		}
	};

	this.delayStep = function()
	{
		if (Effect.Queues.get(this.name).size() == 0)
		{
			_delay.counter--;
		}

		if(_delay.counter < 0)
		{
			_delay.counter = this.delayTime;
			_transition.func(this.currentSlide(), this.nextSlide());
		}
	}

	this.pause = function()
	{
		if (_delay.executer != null)
		{
			_delay.executer.stop();
			_delay.executer = null;
		}
	};
}

function wmxMarqueeSlide(slide)
{
	this.element = slide;
	this.startPos = { x: 0, y: 0 };
	this.offset = { x: 0, y: 0 };

	this.resetPosition = function()
	{
		this.element.setStyle({left: this.startPos.x + 'px', top: this.startPos.y + 'px'});
	};
}

