/*

		rolloutGroup.js
		
		Mootools-based class to provide customizable rollout functionality
		
		Written by:		Ken Kolodziej
		Created on:		September 17, 2007

		USAGE:			Instantiate a new RolloutGroup and pass two arrays in the options object (rollout div ids and
						trigger object ids).  The two arrays MUST be synchronized for the rollouts to be effective.
*/

var RolloutGroup = new Class({
	rolloutGroups:[],
	options: {
		divIDs:[],
		triggerObjIDs:[],
		theModes:[],
		triggerEvents:[]
	},
	initialize: function(options){
		this.setOptions(options);
		
		if((this.options.divIDs.length != this.options.triggerObjIDs.length) || (this.options.divIDs.length != this.options.theModes.length))
			throw("Array lengths do not match (" + this.options.divIDs.length + "," + this.options.triggerObjIDs.length + "," + this.options.theModes.length + ")");
		
		// Add new rolloutGroup to array
		this.rolloutGroups[this.rolloutGroups.length] = new Object({rollouts:[]});
		var tempGroup = this.rolloutGroups[this.rolloutGroups.length - 1];
		
		for(var i = 0; i < this.options.divIDs.length; i++) {
			tempGroup.rollouts.push(new RolloutClass({divID:this.options.divIDs[i], triggerObjID:this.options.triggerObjIDs[i], theGroup:tempGroup, groupClass:this, theMode:this.options.theModes[i], triggerEvent:this.options.triggerEvents[i]}));
		}
	},
	closeAll: function(newRollout) {
		// Get rollout group
		var tempGroup = newRollout.options.theGroup;
		
		for(var i = 0; i < tempGroup.rollouts.length; i++) {
			if(tempGroup.rollouts[i].options.divID != newRollout.options.divID)
				tempGroup.rollouts[i].forceClose();
		}
	}
});
RolloutGroup.implement(new Options, new Events);


var RolloutClass = new Class({
	open:false,
	opening:false,
	options: {
		divID:'',
		triggerObjID:'',
		theGroup:null,
		groupClass:null,
		theMode: 'vertical',
		triggerEvent: 'mouseenter',
		triggerEventClose: 'mouseleave'
	},
	initialize: function(options){
		this.setOptions(options);
		this.slider = new Fx.Slide(this.options.divID, { mode:this.options.theMode, onStart: this.hideOverflowElements.bind(this), onComplete: function() { this.showOverflowElements(); if(this.opening) { this.open = true; } else { this.open = false; this.makeInvisible(); } }.bind(this) }).hide();
		this.theDiv = $(this.options.divID);
		this.theParent = this.theDiv.getParent().getParent();	// Have to go up two levels b/c the slider creates a wrapper div
		this.triggerObj = $(this.options.triggerObjID);
		this.iframes = new Array();
		this.overflows = new Array();
		this.makeInvisible();

		switch(this.options.triggerEvent) {
			case 'click':
				this.options.triggerEventClose = 'click';
				break;
			default:
				break;
		}
		
		if(this.options.triggerEvent == 'click'
		   || this.options.triggerEvent == 'mouseenter'
		   || this.options.triggerEvent == 'mouseover') {
			this.triggerObj.addEvent(this.options.triggerEvent, function(e){
				e = new Event(e);
				this.rollout();
				e.stop();
			}.bind(this));
			this.triggerObj.addEvent(this.options.triggerEventClose, function(e){
				e = new Event(e);
				this.close(e);
				e.stop();
			}.bind(this));
		
			//if(this.options.triggerEvent == 'mouseenter') {
				this.theDiv.addEvent('mouseleave', function(e){
					e = new Event(e);
					this.close(e);
					e.stop();
				}.bind(this));
			//}
		}
		else {
			this.triggerObj.addEvent('click', function(e){
				e = new Event(e);
				location.href = this.options.triggerEvent;
				e.stop();
			}.bind(this));
		}
	},
	rollout: function() {
		this.options.groupClass.closeAll(this);
		this.opening = true;
		this.createIFrameLayers();
		this.makeVisible();
		this.slider.slideIn();
	},
	close: function(e) {
		// Only close if mouse is outside the div area
		if(this.open) {
			if(!this.mouseIsInHotZone(e))
				this.forceClose();
		}
	},
	forceClose: function() {
		this.opening = false;
		this.slider.slideOut();
		this.destroyIFrameLayers();
	},
	mouseIsInHotZone: function(e) {
		var coords = this.theDiv.getCoordinates();
		// If mouse cursor is within coordinates of div, return true
		if( ( (e.page.x >= coords.left) && (e.page.x <= coords.left + coords.width) ) && ( (e.page.y >= coords.top) && (e.page.y <= coords.top + coords.height) ) )
			return true;
		else
			return false;
	},
	makeInvisible: function() {
		if(this.theParent) this.theParent.setStyle('visibility', 'hidden');
	},
	makeVisible: function() {
		if(this.theParent) this.theParent.setStyle('visibility', 'visible');
	},
	createIFrameLayers: function() {
		/*var coords = this.theDiv.getCoordinates();
		var newFrame = new Element('iframe', { styles: { 'zIndex':this.theDiv.getStyle("zIndex") - 1, 'top': coords['top'] + 'px', 'left': coords['left'] + 'px', 'width': coords['width'] + 'px', 'height': coords['height'] + 'px', 'position': 'absolute', 'visibility': 'visible', 'border':'0' } });
		newFrame.setAttribute("allowtransparency", "true");
		newFrame.setAttribute("frameborder", "0");
		newFrame.setHTML("javascript:'<html></html>';");
		//alert(newFrame.getStyle("top") + ' ' + newFrame.getStyle("left") + ' ' + newFrame.getStyle("width") + ' ' + newFrame.getStyle("height"));
		newFrame.injectInside(document.body);
		this.iframes[this.iframes.length] = newFrame;*/
		
		// Cover all interfering objects with an iframe
		$$('embed').each(function(el) {
			el.setAttribute('wmode', 'opaque');
			
			try {
				var coords = el.getCoordinates();
				
				// If this is a flash movie, get its height from the movie itself
				/*if(el.getTag() == 'embed')
					coords['height'] = el.TGetProperty('/', 9);*/
				
				var newFrame = new Element('iframe', { styles: { 'zIndex':this.theDiv.getStyle("zIndex") - 1, 'top': coords['top'] + 'px', 'left': coords['left'] + 'px', 'width': coords['width'] + 'px', 'height': coords['height'] + 'px', 'position': 'absolute', 'visibility': 'visible', 'border':'0' } });
				newFrame.setAttribute("allowtransparency", "true");
				newFrame.setAttribute("frameborder", "0");
				newFrame.setHTML("javascript:'<html></html>';");
				//alert(newFrame.getStyle("top") + ' ' + newFrame.getStyle("left") + ' ' + newFrame.getStyle("width") + ' ' + newFrame.getStyle("height"));
				newFrame.injectInside(document.body);
				this.iframes[this.iframes.length] = newFrame;
			}
			catch(ex) {
				// Nothing
			}
		}, this);
	},
	destroyIFrameLayers: function() {
		for(var i = 0; i < this.iframes.length; i++)
			this.iframes[i].remove();
		
		this.iframes.length = 0;
	},
	hideOverflowElements: function() {
		this.overflows.length = 0;
		this.theDiv.getElements('div').each(function(el) {
			var overflow = el.getStyle('overflow');
			//alert(overflow + ' ' + el.id);
			if(overflow == 'auto' || overflow == 'scroll') {
				this.overflows[this.overflows.length] = new Object({ 'div': el, 'overflow': overflow});
				el.setStyle('overflow', 'hidden');
			}
		}, this);
	},
	showOverflowElements: function() {
		for(var i = 0; i < this.overflows.length; i++)
			this.overflows[i]['div'].setStyle('overflow', this.overflows[i]['overflow']);
		
		this.overflows.length = 0;
	}
});
RolloutClass.implement(new Options, new Events);