/*************************************************\
  Generalized Block Marquee menu engine v1.0
  
  REQUIRES PROTOTYPE AND GSSI PROTOTYPE EXTENSION
\*************************************************/

var BlockMarquee = Class.create();

Object.extend( BlockMarquee, {
	// Static methods/properties
	MouseX : 0,
	MouseY : 0

});

Event.observeDOMReady( function() { Event.observe( document.body, 'mousemove', function (e) { BlockMarquee.MouseX = Event.pointerX(e); BlockMarquee.MouseY = Event.pointerY(e); } ) } );

BlockMarquee.prototype = {
	// Instance methods/properties
	
	initialize: function( targetelement, contentURL, options ) {
		this.options = $H({ spacing: 4, xspeed: 2, frametime: 20, maxmousespeed: 20, mousecontrol:true, deadzone:0.25 }).merge( $H(options) );
		
		this.xoffset = 0;
				
		this.elementname = targetelement;
		var newmarquee = this;
		this.request = this.request || new Ajax.Request(contentURL, {
			method: 'get',
			onSuccess: function (transport) {
				newmarquee.content = Ajax.stripOuterTags(transport.responseText);
				Event.observeDOMReady( function() { newmarquee.setup( ) } );
			},
			onFailure: function(transport) {
				alert("Could not load the block marquee content - the response was " + transport.status + " " + transport.statusText );
			}
		});	

	},
	
	setup: function( ) {
		var m = this;
		this.element = $(this.elementname);

		this.hotspot = this.element.absolutePosition();
		this.hotspot.width = this.element.offsetWidth;
		this.hotspot.height = this.element.offsetHeight;
		this.hotspot.right = this.hotspot.width + this.hotspot.left;
		this.hotspot.bottom = this.hotspot.top + this.hotspot.height;

		this.hotspot.zonewidth = ((this.hotspot.width - (this.hotspot.width * this.options.deadzone)) / 2);
		this.hotspot.leftzone = this.hotspot.left + this.hotspot.zonewidth;
		this.hotspot.rightzone = this.hotspot.right - this.hotspot.zonewidth;

		this.element.style.overflow = "hidden";
		if ( this.element.style.position != "absolute" ) { this.element.style.position = "relative" };
		this.element.innerHTML = this.content;

		this.blocks = new Array();
		this.blockxoffsets = new Array();
		this.blockwidths = new Array();
		var removednodes = new Array();
		
		// Marquee content must be at the top level divs and only divs. Collect divs and destroy everything else
		var nc = this.element.childNodes.length;
		var node;
		for( var i=0; i<nc; i++ ) {
			node = this.element.childNodes[i];
			if( node.nodeName.toUpperCase() == 'DIV' ) {
				node = $(node);
				this.blocks.push( node );
				this.blockxoffsets.push(0);
				this.blockwidths.push( node.offsetWidth );
			} else {
				removednodes.push( this.element.childNodes[i] );
			}
		}	
		for( i=0; i<removednodes.length; i++ ) {
			this.element.removeChild( removednodes[i] );
		}
		
		var currblock;
		this.contentwidth = 0;
		for( var i=0; i<this.blocks.length; i++	) {
			currblock = this.blocks[i];
			this.blockxoffsets[i] = this.contentwidth;
			this.contentwidth += currblock.offsetWidth + this.options.spacing;
			currblock.style.position = "absolute";
		}
		this.contentwidth  = this.contentwidth;
		
		this.start();
	},
	
	refresh: function( ) {
		var b;
		for( var i=0; i<this.blocks.length; i++	) {
			b = this.blocks[i];
			b.style.left = "" + ((( this.blockxoffsets[i] + this.xoffset + this.blockwidths[i] ) % this.contentwidth ) - this.blockwidths[i] ) + "px";			
		}
	},

	renderFrame: function( ) {
		var mo = this._mouseover();
		if (mo) { 
			var relative = 0;
			if (mo == 'L') {
				relative = -(1 - ((BlockMarquee.MouseX - this.hotspot.left) / this.hotspot.zonewidth));
			} else if (mo == 'R') {
				relative = (1 - ((this.hotspot.right - BlockMarquee.MouseX) / this.hotspot.zonewidth));
			} else {
				return;
			}

			this.xoffset += relative * this.options.maxmousespeed;
		} else {
			this.xoffset += this.options.xspeed;
		}
		if ( this.xoffset > this.contentwidth ) { this.xoffset -= this.contentwidth };
		if ( this.xoffset < 0 ) { this.xoffset += this.contentwidth };
		this.refresh();
	},
	
	start: function () {
		var m = this;
		if (! this._frametimer ) {
			this._frametimer = setInterval( function(){ m.renderFrame(); }, this.options.frametime );
		};
	},
	
	stop: function() {
		if (this._frametimer) {
			clearInterval( this._frametimer );
		}
		this._frametimer = null;
	},
	
	_mouseover: function () {
		if (! this.options.mousecontrol ) { return false; };
		if ( BlockMarquee.MouseX < this.hotspot.left ) { return false; }
		if ( BlockMarquee.MouseX > this.hotspot.right ) { return false; }
		if ( BlockMarquee.MouseY < this.hotspot.top ) { return false; }
		if ( BlockMarquee.MouseY > this.hotspot.bottom ) { return false; }
		if ( BlockMarquee.MouseX < this.hotspot.leftzone ) { return 'L'; }
		if ( BlockMarquee.MouseX > this.hotspot.rightzone ) { return 'R'; }
		return 'M';
	}
	
};	