var Scroller = new Class({
	offsetX: 0,
	oldOffsetX: 0,
	initialize: function(element, options) {
		this.setOptions({
			width: null,
			height: null,
			delay: 5,
			initialDelay: 1500,
			step: 1,
			direction: 'left',
			mouseOverPause: true,
			containerEl: $('container') ? $('container') : $E('body')		
		}, options);
		this.timer = null;
		this.marqueeEl = element;	    	    
		this.init( );
	},
	init: function( ) { 
		if(this.options.replaceMarqueeTags) {
			this.options.replaceMarqueeTags = false;
			this.replacedMarquees = [];
			var mqs = $ES('marquee');
			var cl;
			mqs.each(function(el) {
				cl = new Element("div");
				cl.className = el.className;
				cl.setStyles(el.getStyles( ));
				cl.setProperties(el.getProperties( ));
				cl.setHTML(el.innerHTML);
				el.replaceWith(cl);
				this.replacedMarquees[this.replacedMarquees.length] = 
					new Scroller(cl, this.options);
			}.bind(this));
		}

		if(this.marqueeEl) {
			var sizes = this.marqueeEl.getSize( );
			var pos = this.marqueeEl.getPosition( );

			this.origPos = pos;

			if(!this.options.height) {
				this.options.height = sizes.size.y;
			}

			if(!this.options.width) {
				this.options.width = sizes.size.x;
			}

			this.width = this.options.width;
			this.height = this.options.height;

			this.minX = -this.options.width;
			this.maxX = this.options.width;

			this.holderEl = new Element("div");
			this.holderEl.setStyle("position", "absolute");
			this.holderEl.setStyle("width", this.width);

			this.holderEl.setStyle("overflow", "hidden");
			this.holderEl.setStyle("z-index", 9999);
			this.marqueeEl.setStyle("position", "relative");

			this.marqueeEl.remove( );
			this.holderEl.adopt(this.marqueeEl);

			this.holderEl.injectTop($E('body'));

			this.updateMarqueePos( );

			if(this.options.direction == 'right') {
				this.d = 'r';
				this.left = -this.width - 1;
				this.inc = -this.options.step;
			} else {
				this.d = 'l';
				this.left = this.width + 1;
				this.inc = this.options.step;
			}

			this.origWidth = this.width;
			this.origLeft = this.holderEl.getStyle("left").toInt( );
			this.marqueeEl.setStyle("left", this.left);
			this.delay = this.options.delay;
			this.status = 'init';
		}
	
	},
	updateMarqueePos: function( ) {
		if(this.options.containerEl) {
			var pos = this.origPos;

			var cpos = this.options.containerEl.getPosition( );

			if(this.oldCpos) {
				if( this.oldCpos.x != cpos.x ||
				    this.oldCpos.y != cpos.y  ) {
					pos.x += (cpos.x - this.oldCpos.x);
					pos.y += (cpos.y - this.oldCpos.y);
				}
			}
	
			this.oldCpos = cpos;

			if(this.offsetX) {

				this.holderEl.setStyle(
					"width", this.origWidth - this.offsetX
				);
								
			}

			this.holderEl.setStyle("left", pos.x + this.offsetX);
			this.holderEl.setStyle("top", pos.y);			
		}
	},
	updateContentHTML: function(html, width) {
		var left = this.left;

		this.marqueeEl.setHTML(html);
		var newWidth = width;

		this.width = newWidth;
		this.minX = -newWidth;

	},
	start: function( ) {
		if(this.status == 'init') {
			this.status = 'running';
			this.timer = this.update.delay(
				this.options.initialDelay, this
			);    

			if(this.options.mouseOverPause) {
				this.holderEl.addEvent("mouseenter", function(e) {
					this.pauseMarquee( );
					e.stopPropagation( );
				}.bind(this));
				this.holderEl.addEvent("mouseleave", function(e) {
					this.unpauseMarquee( );
					e.stopPropagation( );
				}.bind(this));
			}

			if(this.replacedMarquees) {
				this.replacedMarquees.each(function(el) {
					el.start( );
				});
			}
		}
	},
	stop: function( ) {
		this.status = 'init';
		$clear(this.timer);
		this.holderEl.removeEvents("mouseenter");
		this.holderEl.removeEvents("mouseleave");
	},
	pauseMarquee: function( ) {
		this.status = 'paused';
		$clear(this.timer);
	},
	unpauseMarquee: function( ) {
		if(this.status == 'paused') {
			this.status = 'running';
			this.timer = this.update.delay(
				this.delay, this
			);    
		}
	},
	update: function( ) {
		this.updateMarqueePos( );

		if(this.status == 'running') {
			this.left -= this.inc;

			if(this.d == 'l') {
				if(this.left < this.minX)
					this.left = this.width + 1;
			} else {
				if(this.left > this.maxX) this.left = -this.width - 1;
			}

			this.marqueeEl.setStyle("left", this.left);
			this.timer = this.update.delay(this.delay, this);    
		}
		
	}
});
Scroller.implement(new Options);
