fiveleft.namespace('Application');

(function($){
	
	function Application() 
	{
		var addressInit = false;
		var targetProject;
		var targetIndex;
		
		var _section = null;
		var _sectionMap = {};
		var _workState = {};
		
		// elements
		var flashElement;
		var $controlbar;
		var $feature;
		var $scroller;
		var $topnav;
		var $worknav;

		
		/**
		 * Initialize Application
		 */
		function initialize() {
			
			// ScrollView
			$topnav = $(".topnav-item");
			$worknav = $(".worknav-item");
			$controlbar = $("#controlbar");
			$scroller = fiveleft.getRootScroller();
			$feature = $("#feature");
			
			// Set sectionMap and initial section
			$("#main .section").each( function(i,el){
				var eid = $(el).attr("id");
				var id = eid.replace("section-", "");
				var s = { elem:$(el), eid:eid, id:id, index:i };
				_sectionMap[s.id] = s;
				_sectionMap[s.index] = s;
			});
			_section = _sectionMap[0];
			_workState = { view:"grid", p:null };
			
			// Set Navigation States
			$("a.topnav-item." + _section.id)
				.toggleClass("active", true)
				.parent().siblings().children("a").toggleClass("active", false);
			
			// Set Event Listeners
			$topnav.click( clickTopNav );
			$worknav.click( clickWorkNav );
			$("a.grid-item").click( clickGridItem );
			$.address.change( handleAddressChange );
			
			// Set up Feature Area
			initializeFeature();
		}

		/**
		 * Initialize Flash called from within SWF
		 *  on the Event.ADDED_TO_STAGE event
		 */
		this.flashFeatureLoaded = function() {
			$controlbar.mousedown(clickControlBar);
		}
		
		/**
		 * Flash Mouse Event called from within SWF
		 *  on the MouseEvent.MOUSE_DOWN	 event
		 *  @param eventType {String}
		 */
		this.flashFeatureClick = function( eventType ) {
			$feature.addClass("active");
		}
		
		/**
		 * Initialize Feature
		 */
		function initializeFeature()
		{
			var vars = {};  
			var params = {allowScriptAccess:"always", wmode:"transparent"}; 
			var attrs = {id:"flash"};
			//swfobject.embedSWF("assets/swf/shell.swf", "flash", "880", "720", "9.0.0", false, vars, params, attrs, initializeFeatureComplete);
			initializeFeatureComplete( {success:false} );
		}
		
		/**
		 * Initialize Feature Complete
		 * @param e {Event}
		 */
		function initializeFeatureComplete( e ) 
		{
			if( e.success ) {
				flashElement = $(e.ref)[0];
			}else{
				$("#flash .no-flash").delay(400).animate({opacity:1},800,"easeOutCubic");
			}
		}

		/**
		 * Click Control Bar
		 * @param e {Event}
		 */
		function clickControlBar( e )
		{
			e.preventDefault();
			fiveleft.trackEvent([_section.id, "clickControlBar"]);
			if( flashElement !== null ) {
				$feature.addClass("active");
				flashElement.jsControlBarTrigger();
			}
		}
		
		/**
		 * Click Grid Item
		 * @param e {Event}
		 */
		function clickGridItem( event ) 
		{
			event.preventDefault();
			var gridItemID = $(this).attr("id");
			$.address.value( "work?view=project&p=" + gridItemID );
			fiveleft.trackEvent([_section.id, "clickGridItem", gridItemID]);
		}
		
		/**
		 * Click Top Nav
		 * @param event {Event}
		 */
		function clickTopNav( event )
		{
			event.preventDefault();
			var targetSection = _sectionMap[ $(this).attr('href').substr(1) ];
			switch( true )
			{
				case targetSection.id == _section.id :
					updateScrollPosition();
					break;
				case targetSection.id == "work" :
					var workQuery = "?";
					workQuery += "view=" + _workState.view;
					workQuery += _workState.p !== null ? "&p=" + _workState.p : "";
					$.address.value( "work" + workQuery );
					break;
				default :
					$.address.value( targetSection.id );
					break;
			}
		}
		
		/**
		 * Click Work Nav
		 * @param event {Event}
		 */
		function clickWorkNav( event )
		{
			event.preventDefault();
			$.address.value( $(this).attr('href').substr(1) );  
		}
		
		/**
		 * Handle Browser Address Change
		 * @param e Event
		 */
		function handleAddressChange( e ) {
			sectionChange();
		}
		

		/**
		 * Initialize Grid
		 */
		function initializeGrid()
		{
			// Grid 
			$("a.grid-item").click( function(event) {
				event.preventDefault();
				$.address.path( "work" ).queryString( "view=project&p=" + $(this).attr("id") );
			});
			
			// Fade Content Back In
			$(".work-content").animate({opacity:1}, 600, "easeOutCubic");
		}

		/**
		 * Initialize Project Layout and Functionality
		 */
		function initializeProject()
		{
			// Set Up Widths of Media Containers
			$(".project").each( function(i,el){
				var mc = $(el).find(".media-container");
				$(mc).css({ "width" : $(mc).children().length * $(".project-media").width() });
			});
			
			// Make Project Nav Items Clickable
			$("a.project-nav-item").click( function(event)
			{
				event.preventDefault();
				targetProject = $(this).parents(".project");
				targetIndex = $(this).attr("id");
				fiveleft.trackEvent([_section.id, "clickProjectNavItem", targetProject.attr("id") + ":" + targetIndex]);
				updateSelectedMedia( targetProject, targetIndex );
			});
			
			// Make Project Media Items Clickable
			$("a.media-item").click( function(event)
			{
				event.preventDefault();
				targetProject = $(this).parents(".project");
				targetIndex = ( $(this).next().length > 0 ) ? $(this).next().attr("id") : 0;
				fiveleft.trackEvent([_section.id, "clickMediaItem", targetProject.attr("id") + ":" + targetIndex]);
				updateSelectedMedia( targetProject, targetIndex );
			});
			
			// Position Media relative to Parent Container 
			$(".media").load( function(){
				positionMedia($(this));
			});
			
			// Fade Content Back In
			$(".work-content").animate({opacity:1}, 600, "easeOutCubic");
		}


		/**
		 * Position Media
		 */ 
		function positionMedia( target )
		{
			var ptop = Math.round(($(target).parent().height()-$(target).height())*0.5);
			var h = $(target).parent().height();
			$(target).parent().css({"padding-top":ptop + "px", "height":Math.floor(h-ptop) + "px"});
		}
		
		
		/**
		 * Section Change
		 */
		function sectionChange() 
		{ 
			var targetSection = ($.address.pathNames().length > 0) ? _sectionMap[$.address.pathNames()[0]] : undefined;
			switch( true ) 
			{
				case targetSection == undefined && _section.id == _sectionMap[0].id :
					
					break;
				case targetSection == undefined && _section.id !== _sectionMap[0].id : 
					_section = _sectionMap[0];
					break;
				default : 
					_section = targetSection;
					break;
			}
			
			$("a.topnav-item." + _section.id)
				.toggleClass("active", true)
				.parent().siblings().children("a").toggleClass("active", false);
			
			updateScrollPosition();
		}

		
		/**
		 * Slide to Media Complete
		 * @param curElem {HTMLElement}
		 * @param tarElem {HTMLElement}
		 */
		function slideToMedia( curElem, tarElem )
		{
			// Direction dictated by going up or down in Index value
			var direction = (tarElem.index() > curElem.index()) ? -1 : 1;
			
			// Position Target
			tarElem.css({"left":(-direction*tarElem.width()), "opacity":0});
			tarElem.addClass("showing");
			curElem.removeClass("showing");
			
			// Animate Target and Current Divs
			var scrollComplete = function() { 
				tarElem.animate( {left:"0px", opacity:1}, 500, "easeInOutCubic" );
				curElem.animate( {left:(direction*curElem.width()) + "px", opacity:0}, 500, "easeInOutCubic", function(){slideToMediaComplete(curElem);} );
			}
			
			if( _workState.view == "stack" ) {
				// Scroll Target
				var project = $(curElem).parents(".project");
				var projectTop = project.offset().top;
				if( project.index() == 0 ) projectTop -= 237;
				updateScrollPosition( projectTop, scrollComplete );
			}else{
				scrollComplete();
			}
		}
		
		/**
		 * Slide to Media Complete
		 * @param elem {HTMLElement}
		 */
		function slideToMediaComplete( elem )
		{
		}
		
		/**
		 * Update Selected Media
		 * @param project {String}
		 * @param index {int}
		 */
		function updateSelectedMedia( project, index )
		{
			// Update Nav
			var targetNav = project.find("a.project-nav-item[id='" + index + "']");
			targetNav.addClass("project-nav-selected");
			targetNav.parent().siblings().children("a").removeClass("project-nav-selected");
			
			// Target Project
			var container = project.find(".media-container");
			
			// Determine Current Target
			var curElem = container.children("a.showing");
			var tarElem = container.children("a[id='" + index + "']");

			//
			switch( true )
			{
				case curElem.attr("id") == tarElem.attr("id") :
					// SAME DIV, DO NOTHING
					break;
			
				case tarElem.children("span").length > 0 :
					tarElem.children("span").replaceWith('<img class="media loaded" src="' + tarElem.attr("src") + '">');
					tarElem.children("img").load(function(){
						positionMedia($(this))
						slideToMedia( curElem, tarElem );
					});
					break;
					
				default :
					slideToMedia( curElem, tarElem );
					break;
			}
		}


		/** 
		 * Update Scroll Position
		 * @param target {Number} Optional
		 * @param callback {Function} Optional
		 */
		function updateScrollPosition( target, callback )
		{
			// Determine Target scrollTo DIV
			var scrollY = $scroller.scrollTop();
			var top = target || $(_section.elem).position().top;
			var maxdist = 3000;
			var distance = Math.min(maxdist, Math.abs(scrollY - top));
			var maxtime = 1500;
			var mintime = 300;
			var animateTime = Math.round( mintime+ ((distance/maxdist) * (maxtime-mintime)) );
			var onComplete = callback || updateScrollPositionComplete;
			
			// Update Feature to active/inactive
			if( $feature.hasClass("active") && _section.id !== "home" ) {
				$feature.removeClass("active");
			}
			
			if( distance <= 5 ) { 
				$scroller.scrollTop( top );
				onComplete();
			}else{
				$scroller.animate({scrollTop:top}, animateTime, "easeInOutCubic", onComplete);
			}
		}


		/** 
		 * Update Scroll Position
		 */
		function updateScrollPositionComplete()
		{
			if( _section.id == "work" ) updateWorkView();
		}


		/**
		 * Update Work View
		 */
		function updateWorkView()
		{	
			var newViewState = ( $.address.parameter("view") !== undefined ) ? $.address.parameter("view") : _workState.view;
			var newProject = ( $.address.parameter("p") !== undefined ) ? $.address.parameter("p") : null;
			
			if( _workState.view !== newViewState || _workState.p !== newProject ) {
				
				// If we require a new workViewState, empty the current view and
				//  replace with a load spinner
				$(".work-content").empty().append( "<div class='loader'><img src='assets/img/ajax-loader.gif' alt=''></img></div>" );
				
				var reqData = {request:newViewState};
				if( newProject !== null ) reqData.id = newProject;
				
				// Call the AJAX Data
				$.ajax({
					context:this,
					url:"includes/work.php",
					data:reqData, 
					success:updateWorkViewComplete
				});
			}

			_workState.view = newViewState;
			_workState.p = newProject;
			
			$("a.worknav-item").each(function(i,el){
				$(el).toggleClass("active", $(el).hasClass( "view-" + _workState.view ));
			});
		}
		
		/**
		 * Update Work View Complete
		 * @param data
		 * @param textStatus
		 * @param XMLHttpRequest
		 * @return
		 */
		function updateWorkViewComplete( data, textStatus, XMLHttpRequest )
		{
			$(".work-content").empty().append( data );
			$(".work-content").css({"opacity":0});
			switch( $(".work-content > div").attr("id") )
			{	
				case "grid" :
					initializeGrid();
					break;
				case "stack" :
					initializeProject();
					break;
				case "project" :
					initializeProject();
					break;
			}
		}
		
		
		// When its all said and done...
		initialize();
	}
	
	
	$(document).ready(function(){
		fiveleft.Application = new Application();
	});
	
		
})(jQuery);
