/**
 *  Global javascript for oomph! media
 */

// Variable to hold transition parameters
var transition = { enabled: false, section: 0, subsection: 0 };

// List of functions to run on document load
$(function () { $.each ([

	// Tag the document as js-enabled
	function () { $('#wrapper').addClass ('js'); },

	// Transition callbacks
	function ()
	{
		var container = $('#inner-wrapper'), sidebar = $('#sidebar'), viewport = $('#viewport');
		var width_offset = 5 + sidebar.outerWidth (true);

		transition.callback = {
			// Init
			init: function ()
			{
				var hash = location.hash;
				if (!hash) hash = transition.hash.build ('#home');
				transition.hash.parse (hash);
			},

			// DEBUG
			debug: function (msg)
			{
				if (window.console) console.log (msg);
			},

			// Start animation
			start: function (params)
			{
				if (params.scrollTop == viewport.scrollTop())
					return;

				if (params.section && params.section != 2)
					$(transition.roller).parent ().css ({display: 'none'});

				viewport.stop ().animate ({opacity: 0}, {duration:'fast', complete: function ()
				{
					viewport
						.css ({visibility: 'hidden'})
						.width (params.width)
						.scrollTop (params.scrollTop)
					;
					container.width (width_offset + params.width);
					location.hash = transition.hash.build (params.hash);

					if (!params.section || !transition.enabled || !transition.obj.toSection || !transition.obj.toSection (params.section, params.subsection))
						transition.callback.done ();
				}});
			},

			// End of animation
			done: function (section, subsection)
			{
				if (section && section == 2 && subsection != 1)
					transition.callback.roller (2);
				else
					transition.callback.reveal ();
			},

			// Reveal viewport
			reveal: function ()
			{
				if (viewport.css('visibility') == 'hidden')
					viewport
						.css ({visibility: ''})
						.animate ({opacity: 1}, {duration: 'fast'})
					;
			},

			// Roller animation
			roller: function (section)
			{
				var roller = $(transition.roller).parent ();

				if (roller.is (':visible'))
					transition.callback.done (2, 1);
				else
					roller.css ({display: 'block'});
			},

			//Portfolio subsection
			portfolio: function (subsection)
			{
				var li = $('#nav-portfolio');
				var liSubNavs = li.find ('li').removeClass ('active');

				if (subsection && subsection <= liSubNavs.length)
					li = liSubNavs.eq (subsection - 1)

				var a = li.children ('a');
				li.addClass ('active');
				transition.callback.start ({
					section: li.data ('section'),
					subsection: li.data ('subsection') || 0,
					scrollTop: li.data ('target_top'),
					width: li.data ('target_width'),
					hash: a.attr ('href')
				});
			}
		}

		transition.hash = {
			// Translate location.hash into corresponding section call
			parse: function (hash)
			{
				var matches = [];
				if (matches = hash.match (/^#\/(.+?)(\/(.+))?$/))
				{
					if (matches[2] && matches[3])
					{
						$('a[href=#' + matches[1] + ']').click ();
						$('a[href=#' + matches[1] + '-' + matches[3] + ']').click ();
					}
					else
						$('a[href=#' + matches[1] + ']').click ();

					return true;
				}
				else
					return false;
			},

			// Translate ID into parseable location.hash
			build: function (hash)
			{
				var matches = [];
				if (matches = hash.match (/^#(.+?)(-(.+))?$/))
				{
					if (matches[2] && matches[3])
						return '#/' + matches[1] + '/' + matches[3];
					else
						return '#/' + matches[1];
				}
				else
					return hash;
			}
		};
	},

	// Add Flash transition
	function ()
	{
		// Utility function, generates flashvar string from object
		function toFlashvarsString ()
		{
			var s = '';
			for(var key in this)
				if(typeof this[key] != 'function')
					s += key+'='+encodeURIComponent(this[key])+'&';
			return s.replace (/&$/, '');
		};

		// Utility function, generates attribute string from object
		function toAttributeString()
		{
			var s = '';
			for(var key in this)
				if (typeof this[key] != 'function' && this[key] !== '')
					s += key+'="'+this[key]+'" ';
			return s;
		};

		// Utility function, generates param strings from object
		function toParamString ()
		{
			var s = '';
			for (var key in this)
				if (typeof this[key] != 'function' && this[key] !== '')
					s += '<param name="'+key+'" value="'+this[key]+'" />\n';
			return s;
		};

		// Override default FLash update notification - degrade silently
		$.fn.flash.pluginOptions.update = $.fn.flash.pluginOptions.expressInstall = false;

		// Override default Flash output
		$.fn.flash.transform = function (htmlOptions)
		{
			var attrs = { data: htmlOptions.src };
			var params = {
				movie: htmlOptions.src,
				allowscriptaccess: '',
				wmode: '',
				flashvars: '',
				pluginspage: '',
				quality: '',
				scale: '',
				play: '',
				loop: '',
				bgcolor: ''
			};
			for (i in htmlOptions)
				if (i in params)
					params[i] = htmlOptions[i];
				else
					attrs[i] = htmlOptions[i];

			attrs.toString = toAttributeString;
			if (params.flashvars) params.flashvars.toString = toFlashvarsString;
			params.toString = toParamString;

			return '<object '+attrs+'>\n'+params+'</object>\n';
		}

		if (!$.fn.flash.hasFlash('8.0.0'))
			return;
		else
			with ({o: transition})
			{
				o.enabled = true;
				$('#wrapper').addClass ('flash');

				o.obj = $('<div id="transition-container"></div>').flash ({
					src: 'swf/transition.swf',
					width: 870,
					height: 720,
					id: 'transition',
					allowscriptaccess: 'always',
					wmode: 'transparent',
					scale: 'noscale',
					flashvars: { callback: 'transition.callback' }
				})
				.appendTo ($('#wrapper'))
				.find('#transition').get(0)
				;

				o.roller = $('<div id="roller-container"></div>').flash ({
					src: 'swf/roller.swf',
					width: 870,
					height: 420,
					id: 'roller',
					allowscriptaccess: 'always',
					wmode: 'transparent',
					scale: 'noscale',
					flashvars: { callback: 'transition.callback' }
				})
				.appendTo ($('#wrapper'))
				.find('#roller').get(0)
				;
			}
	},

	// Navigation
	function ()
	{
		var options = {
			duration: 250,
			width: 190,
			height: 22,
			paddingTop: '100px'
		};
		var viewport = $('#viewport');
		var contentBlocks = viewport.children();
		var liMainNav = $('#nav > li');
		var liContainerNav = $('#nav-about, #nav-portfolio');
		var ulSubNav = liMainNav.children('ul');
		var liSubNav = ulSubNav.children('li');

		// Store target for each main nav
		liMainNav.each (function (i)
		{
			var target = $($(this).children('a').attr('href'));
			$(this)
				.data ('section', i + 1)
				.data ('target_top', target.position().top)
				.data ('target_width', target.width ())
			;
		});

		var subsection = 0;
		// Store target for each sub nav
		liSubNav.each (function (i)
		{
			var target = $($(this).children('a').attr('href'));
			$(this)
				.data ('section', $(this).parent ('ul').parent ('li').data ('section'))
				.data ('subsection', ($(this).parent ('ul').parent ('li').data ('section') == 3)? ++subsection: 0)
				.data ('target_top', target.position().top)
				.data ('target_width', target.width ())
			;
		});

		// Handle show/hide sub nav
		liContainerNav.children('a').click (function (e)
		{
			$.Event(e).preventDefault ();

			$(this).next('ul')
				.stop (true)
				.find('li > a > span').css ({left: 0}).end ()
				.each (function () { height = options.height * $(this).children('li').length })
				.css ({display: 'block', overflow: 'hidden', width: 0, height: 0, paddingTop: 0})
				.animate ({width: options.width}, options.duration)
				.animate ({paddingTop: options.paddingTop}, options.duration)
				.animate ({height: height}, options.duration)
				.queue ('fx', function ()
				{
					$(this)
						.css ({overflow: 'visible'})
						.find ('li > a > span').animate ({left: 15}, 'fast')
					;
				})
			;
		});

		// Hook main nav to Flash transition
		liMainNav.children('a').click (function (e)
		{
			$.Event(e).preventDefault ();

			var a = $(this);
			var li = a.parent('li');
			liMainNav.removeClass ('active');
			liSubNav.removeClass ('active');
			li.addClass ('active');
			ulSubNav.not (a.next('ul')).stop (true, false).hide ();

			transition.callback.start ({
				section: li.data ('section'),
				scrollTop: li.data ('target_top'),
				width: li.data ('target_width'),
				hash: a.attr ('href')
			});
		})

		// Hook sub nav to normal (JS) transition
		liSubNav.children('a').click (function (e)
		{
			$.Event(e).preventDefault ();

			var a = $(this);
			var li = a.parent('li');
			liSubNav.removeClass ('active');
			li.addClass ('active');

			transition.callback.start ({
				section: li.data ('section'),
				subsection: li.data ('subsection'),
				scrollTop: li.data ('target_top'),
				width: li.data ('target_width'),
				hash: a.attr ('href')
			});
		})
	},

	// Sub-pagination within portfolio
	function ()
	{
		$('ul.panels').each (function ()
		{
			var panels = $(this).children ('li');
			var pages = Math.ceil (panels.length / 3);
			var pagination = $('<ul class="pagination"><li class="desc">Page:</li></ul>').click (function (e)
			{
				var li = $($.Event (e).originalEvent.target).closest ('.pagination li:not(.desc):not(.current)');
				var offset = 3 * li.data ('offset');
				if (li.length)
				{
					panels.css ({display: 'none'})
						.slice (offset, offset + 3).css ({display: 'block'});
					li.addClass ('current')
						.siblings ().removeClass ('current');
				}
			});

			for (var i = 0; i < pages; ++i)
				$('<li>' + (i+1) + '</li>')
					.data ('offset', i)
					.appendTo (pagination)
				;

			$(this).after (pagination);
			pagination.children ('li:not(.desc)').eq (0).click ();
		});
	},

	// Home carousel
	function ()
	{
		$('#home-carousel').jcarousel ({
			visible: 3,
			wrap: null
		})
		.find ('li > a').each (function ()
		{
			var viewport = $('#viewport'),
				$this = $(this),
				caption = $this.attr ('title'),
				popup = $('<div class="popup"><div class="caption"></div><div class="tip"></div></div>').appendTo (viewport),
				timer = false,
				showing = false
			;

			$this
				.removeAttr ('title')
				.hover (
					function ()
					{
						if (showing) return;

						var offset = $this.offset ();

						if (timer) { clearTimeout (timer); timer = false; }
						showing = true;
						popup
							.children ('.caption').text (caption).end ()
							.css ({
								'position': 'absolute',
								'margin-top': 10,
								'opacity': 0
							})
							.offset ({ top: offset.top - 50, left: offset.left })
							.stop ()
							.animate ({
								'margin-top': 0,
								'opacity': 1
							})
							.hover (
								function () { if (timer) { clearTimeout (timer); timer = false; } },
								hidePopup
							)
						;
					},
					hidePopup
				)
			;
			
			function hidePopup ()
			{
				if (timer) clearTimeout (timer);
				timer = setTimeout (function () {
					if (popup)
						popup.stop ().animate ({
							'margin-top': -20,
							'opacity': 0
						});
					timer = showing = false;
				}, 500);
			}
		});
	},

	// Initial state
	function ()
	{
		if (!transition.enabled)
			transition.callback.init ();
		// else wait for transition.callback.init to be triggered by flash
	}

], function () { this(); /*try { this(); } catch (e) {}*/ })});

