/********************************************************************************************************************

	Fusion Menu Javascript. Originally based on script provided by Invision Power Services Inc, used with permission
	Fusion Menu Modifications (c) 2010 Fusion Digital Entertainment Limited

********************************************************************************************************************/

var fd = {
	menus: {}
	
};

fd.menu = Class.create({

	initialize: function (elem, target) {
		if (!$(elem) || !$(target)) {
			return;
		}

		this.elem = $(elem);
		this.target = $(target);

		$(this.target).hide();

		$(elem).observe('mouseover', this.event_mouseover.bindAsEventListener(this));
		$(elem).observe('mouseout', this.event_mouseout.bindAsEventListener(this));
	},

	doShow: function () {
		Debug.write("Showing " + $(this.elem).id);

		$(this.target).setStyle({
			position: 'absolute'
		});

		if (!$(this.elem).hasClassName('left')) {
			$(this.elem).addClassName('active');
		}
		new Effect.Appear($(this.target), { duration: 0.1 });
	},

	doHide: function () {
		if ($(this.target).visible()) {
			Debug.write("Hiding " + $(this.elem).id);

			if (!$(this.elem).hasClassName('left')) {
				$(this.elem).removeClassName('active');
			}
			new Effect.Fade($(this.target), { duration: 0.1 });
		}
	},

	event_mouseover: function (e) {
		window.clearTimeout(this._meventHide);
		this._meventShow = this.doShow.bind(this).delay(0.2);
	},

	event_mouseout: function (e) {
		window.clearTimeout(this._meventShow);
		this._meventHide = this.doHide.bind(this).delay(0.2);
	}
});

/************************************************/
/* IPB3 Javascript								*/
/* -------------------------------------------- */
/* ips.popup.js - Popup creator					*/
/* (c) IPS, Inc 2008							*/
/* -------------------------------------------- */
/* Author: Rikki Tissier						*/
/************************************************/

/**
 * Full list of options:
 * 
 * type: 			balloon, pane
 * modal: 			true/false
 * w: 				width
 * h: 				height
 * classname: 		classname to be applied to wrapper
 * initial: 		initial content
 * ajaxURL: 		If supplied, will ping URL for content and update popup
 * close: 			element that will close popup (wont work with balloon)
 * attach: 			{ target, event, mouse, offset }
 * hideAtStart: 	Hide after creation (allows showing at a later time)
 * stem: 			true/false
 * delay: 			{ show, hide }
 */

fd.popup = Class.create({
		
	initialize: function( id, options, callbacks )
	{		
		/* Set up properties */
		this.id				= '';
		this.wrapper		= null;
		this.inner			= null;
		this.stem			= null;
		this.options		= {};
		this.timer			= [];
		this.ready			= false;
		this._startup		= null;
		this.hideAfterSetup	= false;
		this.eventPairs		= {	'mouseover': 	'mouseout',
								'mousedown': 	'mouseup'
							  };
		this._tmpEvent 		= null;
		
		/* Now run */
		this.id = id;
		this.options = Object.extend({
			type: 				'pane',
			w: 					'500px',
			modal: 				false,
			modalOpacity: 		0.4,
			hideAtStart: 		true,
			delay: 				{ show: 0, hide: 0 },
			defer: 				false,
			hideClose: 			false,
			closeContents: 		"x"		
		}, arguments[1] || {});
		
		this.callbacks = callbacks || {};
		
		// Are we deferring the load?
		if( this.options.defer && $( this.options.attach.target ) )
		{
			this._defer = this.init.bindAsEventListener( this );
			$( this.options.attach.target ).observe( this.options.attach.event, this._defer );
			
			if( this.eventPairs[ this.options.attach.event ] )
			{
				this._startup = function(e){ this.hideAfterSetup = true; this.hide() }.bindAsEventListener( this );
				$( this.options.attach.target ).observe( this.eventPairs[ this.options.attach.event ], this._startup  );
			}
		}
		else
		{
			this.init();
		}
	},
	
	init: function()
	{
		try {
			Event.stopObserving( $( this.options.attach.target ), this.options.attach.event, this._defer );
		} catch(err) { }
		
		this.wrapper = new Element('div', { 'id': this.id + '_popup' } ).setStyle('z-index: 16000').hide().addClassName('popupWrapper');
		this.inner = new Element('div', { 'id': this.id + '_inner' } ).addClassName('popupInner');
		
		if( this.options.w ){ this.inner.setStyle( 'width: ' + this.options.w ); }
		if( this.options.h ){ this.inner.setStyle( 'max-height: ' + this.options.h ); }
		this.wrapper.insert( this.inner );
		
		if( this.options.hideClose != true )
		{
			this.closeLink = new Element('div', { 'id': this.id + '_close' } ).addClassName('popupClose').addClassName('clickable');
			this.closeLink.update( this.options.closeContents );
			this.closeLink.observe('click', this.hide.bindAsEventListener( this ) );
			this.wrapper.insert( this.closeLink );
		}
		
		$$('body')[0].insert( this.wrapper );
		
		if( this.options.classname ){ this.wrapper.addClassName( this.options.classname ); }
		
		if( this.options.initial ){
			this.update( this.options.initial );
		}
		
		// If we are updating with ajax, handle the show there
		if( this.options.ajaxURL ){
			this.updateAjax();
			setTimeout( this.continueInit.bind(this), 80 );
		} else {
			this.ready = true;
			this.continueInit();
		}
		
		// Need to set a timeout for continue,
		// in case ajax is still running
	},
	
	continueInit: function()
	{
		if( !this.ready )
		{
			setTimeout( this.continueInit.bind(this), 80 );
			return;
		}
		
		//Debug.write("Continuing...");
		// What are we making?
		if( this.options.type == 'balloon' ){
			this.setUpBalloon();
		} else {
			this.setUpPane();
		}
		
		// Set up close event
		try {
			if( this.options.close ){
				closeElem = $( this.wrapper ).select( this.options.close )[0];
				
				if( Object.isElement( closeElem ) )
				{
					$( closeElem ).observe( 'click', this.hide.bindAsEventListener( this ) );
				}
			}
		} catch( err ) {
			Debug.write( err );
		}
		
		// Callback
		if( Object.isFunction( this.callbacks['afterInit'] ) )
		{
			this.callbacks['afterInit']( this );
		}
		
		if( !this.options.hideAtStart && !this.hideAfterSetup )
		{
			this.show();
		}
		if( this.hideAfterSetup && this._startup )
		{	
			Event.stopObserving( $( this.options.attach.target ), this.eventPairs[ this.options.attach.event ], this._startup );
		}
	},
	
	updateAjax: function()
	{
		new Ajax.Request( this.options.ajaxURL,
						{
							method: 'get',
							onSuccess: function(t)
							{
								if( t.responseText != 'error' )
								{
									//Debug.write( t.responseText );
									Debug.write( "AJAX done!" );
									this.update( t.responseText );
									this.ready = true;
									
									// Callback
									if( Object.isFunction( this.callbacks['afterAjax'] ) )
									{
										this.callbacks['afterAjax']( this, t.responseText );
									}
								}
								else
								{
									Debug.write( t.responseText );
									return;
								}
							}.bind(this)
						});
	},
	
	show: function(e)
	{
		if( e ){ Event.stop(e); }
		
		if( this.timer['show'] ){
			clearTimeout( this.timer['show'] );
		}
		
		if( this.options.delay.show != 0 ){
			this.timer['show'] = setTimeout( this._show.bind( this ), this.options.delay.show );
		} else {
			this._show(); // Just show it
		}
	},
	
	hide: function(e)
	{
		if( e ){ Event.stop(e); }
		if( this.document_event ){
			Event.stopObserving( document, 'click', this.document_event );
		}
		
		if( this.timer['hide'] ){
			clearTimeout( this.timer['hide'] );
		}
				
		if( this.options.delay.hide != 0 ){
			this.timer['hide'] = setTimeout( this._hide.bind( this ), this.options.delay.hide );
		} else {
			this._hide(); // Just hide it
		}
	},
	
	_show: function()
	{		
		if( this.options.modal == false ){
			new Effect.Appear( $( this.wrapper ), { duration: 0.3, afterFinish: function(){
				if( Object.isFunction( this.callbacks['afterShow'] ) )
				{
					this.callbacks['afterShow']( this );
				}
			}.bind(this) } );
			this.document_event = this.handleDocumentClick.bindAsEventListener(this);
			Event.observe( document, 'click', this.document_event );
		} else {
			new Effect.Appear( $('document_modal'), { duration: 0.3, to: this.options.modalOpacity, afterFinish: function(){
				new Effect.Appear( $( this.wrapper ), { duration: 0.4, afterFinish: function(){
					if( Object.isFunction( this.callbacks['afterShow'] ) )
					{
						this.callbacks['afterShow']( this );
					}
				}.bind(this) } )
			}.bind(this) });
		}
	},
	
	_hide: function()
	{
		if( this._tmpEvent != null )
		{
			Event.stopObserving( $( this.wrapper ), 'mouseout', this._tmpEvent );
			this._tmpEvent = null;
		}
		
		if( this.options.modal == false ){
			new Effect.Fade( $( this.wrapper ), { duration: 0.3, afterFinish: function(){
				if( Object.isFunction( this.callbacks['afterHide'] ) )
				{
					this.callbacks['afterHide']( this );
				}
			}.bind(this) } );
		} else {
			new Effect.Fade( $( this.wrapper ), { duration: 0.3, afterFinish: function(){
				new Effect.Fade( $('document_modal'), { duration: 0.2, afterFinish: function(){
					if( Object.isFunction( this.callbacks['afterHide'] ) )
					{
						this.callbacks['afterHide']( this );
					}
				}.bind(this) } )
			}.bind(this) });
		}
	},
	
	handleDocumentClick: function(e)
	{
		if( !Event.element(e).descendantOf( this.wrapper ) )
		{
			this._hide(e);
		}
	},
	
	update: function( content )
	{
		this.inner.update( content );
	},
	
	setUpBalloon: function()
	{
		// Are we attaching?
		if( this.options.attach )
		{
			var attach = this.options.attach;
			
			if( attach.target && $( attach.target ) )
			{
				if( this.options.stem == true )
				{
					this.createStem();
				}
				
				// Get position
				if( !attach.position ){ attach.position = 'auto'; }
				if( Object.isUndefined( attach.offset ) ){ attach.offset = { top: 0, left: 0 } }
				if( Object.isUndefined( attach.offset.top ) ){ attach.offset.top = 0 }
				if( Object.isUndefined( attach.offset.left ) ){ attach.offset.left = 0 }
				
				if( attach.position == 'auto' )
				{
					Debug.write("Popup: auto-positioning");
					var screendims 		= document.viewport.getDimensions();
					var screenscroll 	= document.viewport.getScrollOffsets();
					var toff			= $( attach.target ).viewportOffset();
					var wrapSize 		= $( this.wrapper ).getDimensions();
					var delta 			= [0,0];
					
					if (Element.getStyle( $( attach.target ), 'position') == 'absolute')
					{
						var parent = element.getOffsetParent();
						delta = parent.viewportOffset();
					}
				
					toff['left'] = toff[0] - delta[0];
					toff['top'] = toff[1] - delta[1] + screenscroll.top;
					
					//Debug.write( toff['left'] + "    " + toff['top'] );
					// Need to figure out if it will be off-screen
					var start 	= 'top';
					var end 	= 'left';
					
					//Debug.write( "Target offset top: " + toff.top + ", wrapSize Height: " + wrapSize.height + ", screenscroll top: " + screenscroll.top);
					if( ( toff.top - wrapSize.height - attach.offset.top ) < ( 0 + screenscroll.top ) ){
						var start = 'bottom';
					}
					
					if( ( toff.left + wrapSize.width - attach.offset.left ) > ( screendims.width - screenscroll.left ) ){
						var end = 'right';
					}
					
					finalPos = this.position( start + end, { target: $( attach.target ), content: $( this.wrapper ), offset: attach.offset } );
					
					if( this.options.stem == true )
					{
						finalPos = this.positionStem( start + end, finalPos );
					}
				}
				else
				{
					Debug.write("Popup: manual positioning");
					
					finalPos = this.position( attach.position, { target: $( attach.target ), content: $( this.wrapper ), offset: attach.offset } );
					
					if( this.options.stem == true )
					{
						finalPos = this.positionStem( attach.position, finalPos );
					}
				}
				
				// Add mouse events
				if( !Object.isUndefined( attach.event ) ){
					$( attach.target ).observe( attach.event, this.show.bindAsEventListener( this ) );
					
					if( attach.event != 'click' && !Object.isUndefined( this.eventPairs[ attach.event ] ) ){
						$( attach.target ).observe( this.eventPairs[ attach.event ], this.hide.bindAsEventListener( this ) );
					}
						
					$( this.wrapper ).observe( 'mouseover', this.wrapperEvent.bindAsEventListener( this ) );					
				}				
			}
		}
		
		Debug.write("Popup: Left: " + finalPos.left + "; Top: " + finalPos.top);
		$( this.wrapper ).setStyle( 'top: ' + finalPos.top + 'px; left: ' + finalPos.left + 'px; position: absolute;' );		
	},
	
	wrapperEvent: function(e)
	{
		if( this.timer['hide'] )
		{
			// Cancel event now
			clearTimeout( this.timer['hide'] );
			this.timer['hide'] = null;
			
			if( this.options.attach.event && this.options.attach.event == 'mouseover' )
			{
				// Set new event to account for mouseout of the popup,
				// but only if we don't already have one - otherwise we get
				// expontentially more event calls. Bad.
				if( this._tmpEvent == null ){
					this._tmpEvent = this.hide.bindAsEventListener( this );
					$( this.wrapper ).observe('mouseout', this._tmpEvent );
				}
			}
		}
	},
	
	positionStem: function( pos, finalPos )
	{
		var stemSize = { height: 16, width: 31 };
		var wrapStyle = {};
		var stemStyle = {};
		
		switch( pos.toLowerCase() )
		{
			case 'topleft':
				wrapStyle = { marginBottom: stemSize.height + 'px' };
				stemStyle = { bottom: -(stemSize.height) + 'px', left: '5px' };
				finalPos.left = finalPos.left - 15;
				break;
			case 'topright':
				wrapStyle = { marginBottom: stemSize.height + 'px' };
				stemStyle = { bottom: -(stemSize.height) + 'px', right: '5px' };
				finalPos.left = finalPos.left + 15;
				break;
			case 'bottomleft':
				wrapStyle = { marginTop: stemSize.height + 'px' };
				stemStyle = { top: -(stemSize.height) + 'px', left: '5px' };
				finalPos.left = finalPos.left - 15;
				break;
			case 'bottomright':
				wrapStyle = { marginTop: stemSize.height + 'px' };
				stemStyle = { top: -(stemSize.height) + 'px', right: '5px' };
				finalPos.left = finalPos.left + 15;
				break;
		}
		
		$( this.wrapper ).setStyle( wrapStyle );
		$( this.stem ).setStyle( stemStyle ).setStyle('z-index: 6000').addClassName( pos.toLowerCase() );
		
		return finalPos;
	},
	
	position: function( pos, v )
	{
		finalPos = {};
		var toff			= $( v.target ).viewportOffset();
		var tsize	 		= $( v.target ).getDimensions();
		var wrapSize 		= $( v.content ).getDimensions();
		var screenscroll 	= document.viewport.getScrollOffsets();
		var offset 			= v.offset;
		var delta			= [0,0];
		
		if (Element.getStyle( $( v.target ), 'position') == 'absolute')
		{
			var parent = element.getOffsetParent();
			delta = parent.viewportOffset();
		}
		
		toff['left'] = toff[0] - delta[0];
		toff['top'] = toff[1] - delta[1];
		
		if( !Prototype.Browser.Opera ){
			toff['top'] += screenscroll.top;
		}
		
		switch( pos.toLowerCase() )
		{
			case 'topleft':
				finalPos.top = ( toff.top - wrapSize.height - tsize.height ) - offset.top;
				finalPos.left = toff.left + offset.left;						
				break;
			case 'topright':
				finalPos.top = ( toff.top - wrapSize.height - tsize.height ) - offset.top;
				finalPos.left = ( toff.left - ( wrapSize.width - tsize.width ) ) - offset.left;
				break;
			case 'bottomleft':
				finalPos.top = ( toff.top + tsize.height ) + offset.top;
				finalPos.left = toff.left + offset.left;
				break;
			case 'bottomright':
				finalPos.top = ( toff.top + tsize.height ) + offset.top;
				finalPos.left = ( toff.left - ( wrapSize.width - tsize.width ) ) - offset.left;
				break;
		}
		
		return finalPos;
	},
	
	createStem: function()
	{
		this.stem = new Element('div', { id: this.id + '_stem' } ).update('&nbsp;').addClassName('stem');
		this.wrapper.insert( { top: this.stem } );
	},
	
	setUpPane: function()
	{
		// Does the document have a modal blackout?
		if( !$('document_modal') ){
			this.createDocumentModal();
		}
		
		this.positionPane();	
	},
	
	positionPane: function()
	{
		// Position it in the middle
		var elem_s = $( this.wrapper ).getDimensions();
		var window_s = document.viewport.getDimensions();
		var window_offsets = document.viewport.getScrollOffsets();

		var center = { 	left: ((window_s['width'] - elem_s['width']) / 2),
						top: (((window_s['height'] - elem_s['height']) / 2)/2)
					}
					
		if( center.top < 10 ){ center.top = 10; }
					
		$( this.wrapper ).setStyle('top: ' + center['top'] + 'px; left: ' + center['left'] + 'px; position: fixed;');
	},
			
	createDocumentModal: function()
	{
		var pageSize = $$('body')[0].getDimensions();
		var viewSize = document.viewport.getDimensions();
		
		var dims = [];
		
		//Debug.dir( pageSize );
		//Debug.dir( viewSize );
		
		if( viewSize['height'] < pageSize['height'] ){
			dims['height'] = pageSize['height'];
		} else {
			dims['height'] = viewSize['height'];
		}
		
		if( viewSize['width'] < pageSize['width'] ){
			dims['width'] = pageSize['width'];
		} else {
			dims['width'] = viewSize['width'];
		}
		
		var modal = new Element( 'div', { 'id': 'document_modal' } ).addClassName('modal').hide();
		modal.setStyle('width: ' + dims['width'] + 'px; height: ' + dims['height'] + 'px; position: absolute; top: 0px; left: 0px; z-index: 15000;');
		
		$$('body')[0].insert( modal );
	},
	
	getObj: function()
	{
		return $( this.wrapper );
	}
});

/**********************************************/

var Debug = {
	write: function( text ){
		if( jsDebug && !Object.isUndefined(window.console) ){
			console.log( text );
		}
	},
	dir: function( values ){
		if( jsDebug && !Object.isUndefined(window.console) ){
			console.dir( values );
		}
	},
	error: function( text ){
		if( jsDebug && !Object.isUndefined(window.console) ){
			console.error( text );
		}
	},
	warn: function( text ){
		if( jsDebug && !Object.isUndefined(window.console) ){
			console.warn( text );
		}
	},
	info: function( text ){
		if( jsDebug && !Object.isUndefined(window.console) ){
			console.info( text );
		}
	}
}
