/**
 * Main javascipt for the On The Road website. Provides methods for communication
 * between Flash element and rest of site. Depends on the following libraries:
 * - mootools 1.2
 * - swfobject 2.0
 * 
 * The external interface of the Flash object provides the following callbacks:
 * displayPageHeading(heading:String):void; displays the requested page heading in the flash
 * 		object. One of the following values should be given: 'contact', 'about', 'colofon',
 * 		'newsletter' or 'press'.
 * displayMedium(url:String, type:String):void; displays a medium in the flash object. 'url'
 * 		specifies the location of the medium to display. 'type' specifies the type of the
 * 		medium, which should be given one of the following values: 'video', 'audio' or 'image'.
 */
var OnTheRoad = new Class({
	
	// Flag indicicating Flash has loaded all its assets and is ready for display
	mFlashReady: false,
	// Cache for static page heading, used to display static page heading in the case Flash is ready
	mStaticPageHeadingCache: null,
	// Reference to the flash object element
	mFlashObject: null,
	// The minimum height of the ajax content
	mMinAjaxContentHeight: 0,

	// Called from mootools
	initialize: function()
	{	
		this.initialiseFooter();
		this.writeFlash();
		this.setMinAjaxContentHeight();
	},
	
	initialiseFooter: function()
	{
		moo$$('span.footer-link').each(function(element)
		{
			if (element.hasClass('footer-link'))
			{
				var link = element.getElement('a');
				link.addEvent('click', this.displayStaticPage.create({'bind':this}));
			}
		}, this);
	},
	
	writeFlash: function()
	{
		swfobject.embedSWF('OnTheRoad5.swf', 'flashContent', 950, 526, '9', 'js/expressInstall.swf', {version:1},
			{menu:'false', wmode:'opaque', allowFullScreen:'true', allowScriptAccess:'sameDomain'}, {id:'flashObject', name:'flashObject'});
			
	},
	
	/**
	Callback called from Flash. Returns whether or not the site is ready for communication with Flash.
	Since this is called after the Flash has been loaded, we also obtain the reference to the HTML flash object,
	so we can communicate easily with Flash.
	*/
	isReady: function()
	{
		this.mFlashObject = moo$('flashObject');
		//alert(this.mFlashObject.displayPageHeading);
		return true;
	},
	
	/** Callback called from Flash to signal Flash is completely ready, having loaded all needed assets. */
	setFlashReady: function()
	{
		this.mFlashReady = true;
		
		// Check to see if user already clicked a static page link
		if (this.mStaticPageHeadingCache != null)
		{
			displayStaticPageHeading(this.mStaticPageHeadingCache);
		}
	},
	
	setMinAjaxContentHeight: function()
	{
		// 86 is ajaxContent padding-top + padding-bottom
		// 106 is same values + footer height
		var footer = moo$('footer');
		
		this.mMinAjaxContentHeight = window.getSize().y - moo$('flashContainer').getStyle('height').toInt() -
			footer.getStyle('height').toInt() - footer.getStyle('padding-top').toInt() - footer.getStyle('padding-bottom').toInt() - 106;
		
		if (((moo$('ajaxInner').getStyle('height').toInt() - 86) < this.mMinAjaxContentHeight) && (this.mMinAjaxContentHeight > 0))
		{
			moo$('ajaxContent').setStyle('height', this.mMinAjaxContentHeight);
		}
	},
	
	/** Callback called from Flash to show a description with a corresponding slide. */
	showAjaxContent: function(html)
	{
		var ajaxContent = moo$('ajaxContent');
		var ajaxInner = moo$('ajaxInner');
		// Clear the height style
		ajaxInner.setStyle('height', '');
		// Unescape html (needed, since it might be escaped)
		html = unescape(html);
		
		// Check if page load failed
		if (html == "undefined")
		{
			alert("Page loading failed");
		}
		
		// Add clearer div to end of html, to make sure the height of the inner ajax container is known
		html += "<div class=\"clear\"/>";
		// Store current height of ajax content element
		var currentHeight = parseInt(ajaxContent.getStyle('height'));
		// Set html, reset height to current height, and animate
		ajaxInner.set('html', html);
		// Store inner height
		var newInnerHeight = parseInt(ajaxInner.getStyle('height'));
		ajaxInner.setStyle('opacity', 0);
		ajaxInner.setStyle('height', 0);
		
		ajaxContent.setStyle('height', Math.max(this.mMinAjaxContentHeight, currentHeight));
		ajaxContent.get('tween', {duration: 300}).start('height', Math.max(this.mMinAjaxContentHeight, newInnerHeight));
		ajaxInner.get('tween', {duration: 300}).start('height', newInnerHeight).chain(
			function()
			{ 
				ajaxInner.get('tween', {duration:300}).start('opacity', 1).chain(
					function()
					{
						moo$$('div.archive-link').each(function(element)
						{
							if (element.hasClass('archive-link'))
							{
								var link = element.getElement('a');
								link.addEvent('click', gOTR.displayArchiveItem.create({'bind':gOTR}));
							}
						});
						moo$$('div.film-link').each(function(element)
						{
							if (element.hasClass('film-link'))
							{
								var link = element.getElement('a');
								link.addEvent('click', gOTR.displayExtraFilm.create({'bind':gOTR}));
							}
						});
					}
				)
			}
		);
	},
	
	/** Callback called from Flash to hide the description with any slide. */
	hideAjaxContent: function()
	{
		// Check if a description element is present
		var ajaxContent = moo$('ajaxContent');
		var ajaxInner = moo$('ajaxInner');
		var innerHeight = parseInt(ajaxInner.getStyle('height'));
		
		var newHeight = Math.max(this.mMinAjaxContentHeight, parseInt(ajaxContent.getStyle('height')) - innerHeight);
		ajaxInner.get('tween', {duration: 300}).start('opacity', 0).chain(
			function()
			{
				ajaxContent.get('tween', {duration:300}).start('height', newHeight).chain(
					function()
					{
						// Clear the html and the height of the inner element
						ajaxInner.set('html', '');
						ajaxInner.setStyle('height', '');
					}
				)
			}
		);
	},
	
	displayStaticPage: function(event)
	{
		// Stop event propagation
		event = new Event(event);
		event.stop();
		
		// Obtain target of event (only the last bits though)
		var target = String(event.target).substring(String(event.target).lastIndexOf('/') + 1);
		this.displayStaticPageImpl(target);
	},
	
	displayStaticPageImpl: function(target)
	{
		// Obtain data using ajax
		var request = new Request({
			method:'get',
			url:'get_static_content.php',
			noCache: true,
			onComplete: function(result)
			{
				gOTR.showAjaxContent(result);
			}
		});
		request.send('page=' + target);
		
		if (this.mFlashReady)
		{
			this.displayStaticPageHeading(target);
		}
		else
		{
			// Store the last target, so we can display the selection when Flash is ready
			this.mStaticPageHeadingCache = target;
		}
	},
	
	displayStaticPageHeading: function(heading)
	{
		this.mFlashObject.displayPageHeading(heading);
	},
	
	displayArchiveContent: function()
	{
		// Obtain data using ajax
		var request = new Request({
			method:'get',
			url:'get_archive_content.php',
			noCache: true,
			onComplete: function(result)
			{
				gOTR.showAjaxContent(result);
			}
		});
		request.send('');
	},
	
	displayArchiveItem: function(event)
	{
		// Stop event propagation
		event = new Event(event);
		event.stop();
		
		// Send request
		var request = new Request({
			method:'get',
			url: 'get_archive_item.php',
			noCache: true,
			onComplete: function(result)
			{
				// The result, which is in XML format, will be passed to the Flash part of the application
				// Result contains attribute type and title & url tags
				gOTR.displayArchiveItemResult(result);
			}
		});
		var id = String(event.target).substring(String(event.target).lastIndexOf('/') + 1);
		request.send("id=" + id);
	},
	
	displayArchiveItemResult: function(str)
	{
		this.mFlashObject.displayArchiveItem(str);
	},
	
	displayExtraFilm: function(event)
	{
		// Stop event propagation
		event = new Event(event);
		event.stop();
		
		// Obtain the id from the element which was pressed
		var id = String(event.target).substring(String(event.target).lastIndexOf('/') + 1);
		// Delegate event to Flash object
		this.mFlashObject.displayExtraFilm(id);
		
		// Notify stats (function is placed in html)
		siteStatCallback("home.films." + id);
	}
});

// Store global reference to main class
var gOTR = null;

// Callbacks from Flash, will all map to equally named function in the main class
function isReady()
{
	return gOTR.isReady();
}
function setFlashReady()
{
	gOTR.setFlashReady();
}
function showDescription(html)
{
	// Call with a short timeout (Flash video loading & JS seem to conflict here)
	setTimeout('gOTR.showAjaxContent(\'' + escape(html) + '\')', 250);
}
function hideDescription()
{
	gOTR.hideAjaxContent();
}
function displayArchiveContent()
{
	gOTR.displayArchiveContent();
}
function displayStaticPage(page)
{
	gOTR.displayStaticPageImpl(page);
}

// Handle window load event. Initialises Flex BrowserHistory
//handleLoadEvent = function()
//{
//	BrowserHistory.initialize();
//}

// Initialisation called when DOM is ready. Initialises browser history (deeplinking)
// and the Javascript site object
handleDomReadyEvent = function()
{
	//BrowserHistory.initialize();
	gOTR = new OnTheRoad();
}

// Handle window resize events
handleResizeEvent = function()
{
	if (gOTR != null)
	{
		gOTR.setMinAjaxContentHeight();
	}
}

//window.addEvent('load', handleLoadEvent);
window.addEvent('domready', handleDomReadyEvent);
window.addEvent('resize', handleResizeEvent);
