/**
 * Product Configurator jQuery
 * 
 * @version    1.0
 * 
 * @author     Bob Bonifield <bob@360ideas.com>
 * @package    Harper Trucks Products DB
 * @subpackage Products Configurator
 *
 */

$( document ).ready ( function ( ) {
	/**
	 * Loads the application with the default and/or stored state
	 *
	 */
	$.configuratorLoadState = function ( ) {
		$.configuratorSendRequest ( "reloadState", null );
	}
	
	
	/**
	 * Sends the request to the server and calls to the two processing functions once
	 * the request is complete
	 *
	 * @param string sendCall - The call to send to the server
	 * @param string sendData - The data to attach to the call
	 *
	 */
	$.configuratorSendRequest = function ( sendCall, sendData ) {
		$.getJSON (
		"/product_configure2.ajax.php?call=" + sendCall +
		"&data=" + sendData,
		function ( returnData ) {
			$.configuratorStepPopulateTiles ( returnData );
			$.configuratorSummaryPopulateTiles ( returnData );
			
		});
	}
	
	
	/**
	 * Contains all code necessary for populating the JSON step data back into the DOM
	 *
	 * @param object returnData - Data returned from the AJAX postback
	 */
	$.configuratorStepPopulateTiles = function ( returnData ) {
		$stepQueue = $( "#stepTiles" );
		
		if ( returnData.currentState != returnData.previousState ) {
			// Hide the tile container and then remove current tiles
			$stepQueue.fadeTo ( 'fast', 0.05 );
			$stepQueue.queue ( function ( ) {
				$( "div.tile, div.groupLabel, div.configClear, div.stepNote", this ).remove ( );
				$stepQueue.dequeue ( );
			} );
			
			// Update step labels
			$stepQueue.queue ( function ( ) {
				$( "#stepHeader span.step" ).html ( "Step " + returnData.stepNumber + ":" );
				$( "#stepHeader span.choose" ).html ( "Choose your " + returnData.stepLabel );
				$stepQueue.dequeue ( );
			} );
			
			// Add in step notes for optional and/or select-multiple steps
			if ( returnData.stepOptional == true )
				$stepQueue.queue ( function ( ) {
					$tmpObject = $( "<div class=\"stepNote\"></div>" );
					$tmpObject.html ( "<strong>Note:</strong> This step is optional.  If you don't need any " +
						"of these options, <a href=\"javascript: void(0);\">click here</a> to skip this step." )
						.find ( "a" )
						.click ( function ( e ) {
							$.configuratorSendRequest ( returnData.nextCall, 0 );
						} );
					$tmpObject.appendTo ( $stepQueue );
					$stepQueue.dequeue ( );
				} );
			else if ( returnData.stepMultiple == true )
				$stepQueue.queue ( function ( ) {
					$( "<div class=\"stepNote\"></div>" )
						.html ( "<strong>Note:</strong> This step accepts multiple selections.  Continue " +
						"clicking options if you wish to add more than one selection. Clicking an already " +
						"selected option will deselect that option." )
						.appendTo ( $stepQueue );
					$stepQueue.dequeue ( );
				} );
			
			// Process tile array
			var curGroupLabel = '';
			var curGroupCounter = 0;
			$.each ( returnData.stepTileArray, function ( k, tileData ) {
				// Add in group labels if the step requires it
				if ( tileData.groupLabel != curGroupLabel ) {
					curGroupLabel = tileData.groupLabel;
					curGroupCounter = 0;
					if ( curGroupLabel.length > 0 ) {
						if ( k != 0 )
							$stepQueue.queue ( function ( ) {
								$( "<div class=\"configClear\"></div>" ).appendTo ( $stepQueue );
								$stepQueue.dequeue ( );
							} );
						$stepQueue.queue ( function ( ) {
							$( "<div class=\"groupLabel\">" + tileData.groupLabel + "</div>" ).appendTo ( $stepQueue );
							$stepQueue.dequeue ( );
						} );
					}
				}
				// Build individual tiles
				var tmpHtml = returnData.stepTileHtml
					.replace ( /\{tileImage\}/, tileData.tileImage )
					.replace ( /\{name\}/, tileData.name )
					.replace ( /\{subHead\}/, tileData.subHead );
				var $tmpObject = $(tmpHtml);
				// Add description items into temporary object
				if ( $.makeArray ( tileData.descItems ).length > 0 )
					$.each ( tileData.descItems, function ( k2, listItemText ) {
						$( "ul", $tmpObject ).append ( "<li>" + listItemText + "</li>" );
					} );
				else
					$( "ul", $tmpObject ).remove ( );
				// Add class to object if it is the currently selected option
				if ( tileData.selected == true )
					$tmpObject.addClass ( "selected" );
				// Add object into container element using the $stepQueue
				// Also add hover/click effects to the tile
				$stepQueue.queue ( function ( ) {
					$tmpObject.configuratorAddStepEffect ( returnData.nextCall, tileData.id )
						.appendTo ( $stepQueue );
					$stepQueue.dequeue ( );
				} );
				if ( ++curGroupCounter % 4 == 0 && curGroupCounter != 0 )
					$stepQueue.queue ( function ( ) {
						$( "<div class=\"configClear\"></div>" ).appendTo ( $stepQueue );
						$stepQueue.dequeue ( );
					} );
			} );
			// Show the tile container
			$stepQueue.fadeTo ( 'slow', 1 );
		}
	}
	
	
	/**
	 * Contains all code necessary for populating the JSON summary data back into the DOM
	 *
	 * @param object returnData - Data returned from the AJAX postback
	 */
	$.configuratorSummaryPopulateTiles = function ( returnData ) {
		$summaryQueue = $( "#summaryTiles" );
		
		// Remove existing tiles if they are no longer in the tiles array.
		$.each ( $( "div.tile", $summaryQueue ), function ( k ) {
			var tileKey = $( this ).attr("id").replace ( /summaryTile\_/, '' );
			if ( $.inArray ( tileKey, returnData.summaryTileArrayKeys ) == -1 ) {
				$( this ).slideUp ( 'slow', function ( ) { $( this ).remove ( ); } );
			}
		} );
		
		// Add/Remove instructions
		if ( $.makeArray ( returnData.summaryTileArray ).length > 0 )
			$summaryQueue.queue ( function ( ) {
				$( "#summaryHolder p" ).slideUp ( 'slow', function ( ) {
					$(this).remove ( );
					$summaryQueue.dequeue ( );
				} );
			} );
		$summaryQueue.dequeue ( );
		// Process new tile array
		$.each ( returnData.summaryTileArray, function ( k, tileData ) {
			// Reverse of previous check.  Create new tiles from scratch if they weren't
			// already on the page.
			if ( $( "#summaryTile_" + tileData.stateName ).length == 0 ) {
				var tmpHtml = returnData.summaryTileHtml
					.replace ( /\{stateName\}/, tileData.stateName )
					.replace ( /\{stateLabel\}/, tileData.stateLabel );
				var $tmpObject = $(tmpHtml);
				// Process the selections for a given step, building them into a list with
				// a filler element in the event that no selection was chosen.
				if ( $.makeArray ( tileData.selections ).length > 0 ) {
					$.each ( tileData.selections, function ( k2, listItemObject ) {
						var tmpHtml2 = returnData.summaryTileRowHtml
							.replace ( /\{name\}/, listItemObject.name )
							.replace ( /\{subHead\}/, listItemObject.subHead );
						$( "ul", $tmpObject ).append ( tmpHtml2 );
					} );
				} else {
					var tmpHtml2 = returnData.summaryTileRowHtml
						.replace ( /\{name\}/, 'None selected' )
						.replace ( /\{subHead\}/, '' );
					$( "ul", $tmpObject ).append ( tmpHtml2 );
				}
				// Insert the newly created tile into the tile container and add effects.
				$tmpObject.configuratorAddSummaryEffect ( 'reloadState', tileData.stateName )
					.appendTo ( $summaryQueue ).hide ( ).slideDown ( 'slow' );
			// Check to see if we're working with the last updated value, if so, we'll
			// update the selections for this element.
			} else if ( returnData.summaryTileArrayMod == tileData.stateName ) {
				$tileObject = $( "#summaryTile_" + tileData.stateName );
				// Remove the existing UL element using the queue for the tile
				$summaryQueue.queue ( function ( ) {
					$( "ul", $tileObject ).slideUp ( 'slow', function ( ) {
						$tileObject.find ( "li" ).remove ( );
						$summaryQueue.dequeue ( );
					} );
				} );
				// If selections are made on the step, process them.
				// If not, add in a holder LI element stating that none are selected.
				if ( $.makeArray ( tileData.selections ).length > 0 ) {
					$.each ( tileData.selections, function ( k2, listItemObject ) {
						var tmpHtml2 = returnData.summaryTileRowHtml
							.replace ( /\{name\}/, listItemObject.name )
							.replace ( /\{subHead\}/, listItemObject.subHead );
						// Adding elements into the list using the queue for the tile
						$summaryQueue.queue ( function ( ) {
							$( "ul", $tileObject ).append ( tmpHtml2 );
							$summaryQueue.dequeue ( );
						} );
					} );
				} else {
					var tmpHtml2 = returnData.summaryTileRowHtml
						.replace ( /\{name\}/, 'None selected' )
						.replace ( /\{subHead\}/, '' );
					// Adding elements into the list using the queue for the tile
					$summaryQueue.queue ( function ( ) {
						$( "ul", $tileObject ).append ( tmpHtml2 );
						$summaryQueue.dequeue ( );
					} );
				}
				// Slide in the new UL element using the queue for the tile
				$summaryQueue.queue ( function ( ) {
					$( "ul", $tileObject ).slideDown ( 'slow', function ( ) {
						$summaryQueue.dequeue ( );
					} );
				} );
			}
		} );
		
		// If we're dealing with the final step ( accessories selection ), we need to show the
		// totals information
		if ( returnData.completionState == 'total' || returnData.currentState == 'accessory' ) {
			$totalHolder = $( "#configureSummary div.totalHolder" );
			if ( $totalHolder.length == 0 ) {
				var tmpHtml = returnData.totalData.html
					.replace ( /\{model\}/, returnData.totalData.model )
					.replace ( /\{price\}/, returnData.totalData.price );
				$( tmpHtml ).insertAfter ( $summaryQueue ).hide ( ).slideDown ( 'slow' );
				//$( "#configureSummary div.tiles" ).after ( tmpHtml );
			} else {
				$summaryQueue.queue ( function ( ) {
					$( "div.model span", $totalHolder ).html ( returnData.totalData.model );
					$( "div.price span", $totalHolder ).html ( returnData.totalData.price );
					$summaryQueue.dequeue ( );
				} );
			}
		} else
			$( "#configureSummary div.totalHolder" ).slideUp ( 'slow', function ( ) {
				$( this ).remove ( );
			} );
	}
	
	
	/**
	 * Adds hover effects to the step and adds a click event handler to toggle the "selected"
	 * class on the element ( in the event we're on the accessories step ).  Also, triggers the
	 * send request to update the state
	 *
	 * @param string sendCall - The call to send to the server when the tile is clicked
	 * @param string sendData - The data that should be attached to the call
	 *
	 */
	$.fn.configuratorAddStepEffect = function ( sendCall, sendData ) {
		$(this).hover (
			function ( )  {
				$(this).addClass("hover");
			},
			function ( ) {
				$(this).removeClass("hover");
			}
		).click ( function ( e ) {
			$( this ).toggleClass ( "selected" );
			$.configuratorSendRequest ( sendCall, sendData );
		} );
		return this;
	}
	
	
	/**
	 * Adds click event handler to the <a> tag's of the tile.
	 *
	 * @param string sendCall - The call to send to the server when the <a> is clicked
	 * @param string sendData - The data that should be attached to the call
	 *
	 */
	$.fn.configuratorAddSummaryEffect = function ( sendCall, sendData ) {
		$( "a", this ).click ( function ( e ) {
			$.configuratorSendRequest ( sendCall, sendData );
		} );
		return this;
	}
	
	
	
	// Initialize application
	$.configuratorLoadState ( );
} );