﻿//------------------------------------------------------
// global.js
// main js file for new gatsby site
//
// relies on :
//		prototype
//		scriptaculous
//
// start date: November 5, 2008
// last revision: November 12, 2008
// started by: Mani Tadayon
// last revised by: Mani Tadayon
//------------------------------------------------------


//------------------------------------------------------
// 				Global Variables
//------------------------------------------------------


//------------------------------------------------------
// VERY IMPORTANT
// regular page loads are handled by setting the 'page' parameter in the URL:
// 	e.g. thegatsbyhollywood.com/?page=homes
// BUT the preferred method is to use the loadPage() function so that the transition is dynamic
//------------------------------------------------------

// keep track of which page is currently displayed
// NEED TO merge these two variables with the navItem variables below

// this is superseded by the SEO optimizations in PHP...
var currentPage = _GET('page');
var defaultPage = 'homes';

// keep track of currently selected navigation item
// 		- also prevents multiple animations being triggered 
var currentNavItem;
var defaultNavItem='homes';


// naming conventions for DOM elements
// please keep this up to date and resist the temptation to hard-code id strings
// your cooperation will be noted and rewarded :)
var menuImgDir = 'media/images/menu/';
var navPrefix = 'nav_';
var imgFileExtension = '.gif';
var imgDivSuffix = '_img';
var downImgSuffix = '_sepia';
var reflectedImgSuffix = '_reflected';
var subMenuDivSuffix = '_submenu';

// direcotry of the large images to be shown in the image viewer
var largeImgDir = 'media/images/content/';
// DOM id of the large image container;
var largeImgDivId = 'large_image';
var largeImgLabelDivId = 'large_image_label';

// keeps track of number of animations in queue, 
// to prevent queued animations from going rogue
var numAnimations = 0;

// set up a blank hash that will contain all the DOM id's for the menu elements
var menuItems = $H({
	'homes' : new Hash(), 
	'historic_preservation' : new Hash(), 
	'eco_edge' : new Hash(), 
	'press' : new Hash(), 
	'location' : new Hash()
});


// the document titles to show on page load
var titles = $H({
	'homes' : 'The Gatsby Hollywood - Hollywood Real Estate', 
	'historic_preservation' : 'The Gatsby Hollywood - Preservation of a Hollywood Landmark', 
	'eco_edge' : 'The Gatsby Hollywood - Solar Powered Green Homes in Hollywood',
	'press' : 'The Gatsby Hollywood - New Home Updates and Press', 
	'location' : 'The Gatsby Hollywood - New Homes For Sale on Fountain and Wilcox'
});


// define any submenus here
var subMenus = $H({
	'homes' : $H({	
		// name			// document title 
		'gallery' : 'The Gatsby Hollywood - Hollywood Real Estate',
		'features' : 'The Gatsby Hollywood - Hollywood Homes For Sale', 
		'plans' : 'The Gatsby Hollywood - Luxury Urban Homes in Los Angeles'})
});

//------------------------------------------------------
//	example of a menuItem entry for reference purposes
//	each entry in menuItems is itself a prototype hash
//------------------------------------------------------
//	MAKE SURE TO USE prototype's Hash#get/set/update 
//	instead of bracket or dot notation!
//	See: 	http://prototypejs.org/api/hash
// var menuItem = $H({ 
//	// document title
//	'title' : 'The Gatsby Hollywood - Eco-Friendly Homes Now Selling in Hollywood',
//
// 	'divId' : 'nav_homes',
// 	'imgDivId' : 'nav_homes_img',
// 	'imgReflectedDivId' : 'nav_homes_img_reflected',
// 	'upImg' : $H({ 'src' : '/media/images/menu/nav_homes.gif',
// 			'reflectedSrc' : '/media/images/menu/nav_homes_reflected.gif'}),
// 	'downImg' : $H({ 'src' : '/media/images/menu/nav_homes_sepia.gif',
// 		'reflectedSrc' : '/media/images/menu/nav_homes_sepia_reflected.gif'}),
// 
//	subMenus = ['gallery', 'features', 'plans'],
// 	//this entry is optional in the DOM, 
// 	// so check for existence before using it! 
// 	'subMenuDivId' : 'nav_homes_submenu',
// 
//	// a hash of one or more URLs to load content from
//	// more than one URL only if there are submenu items
//	'urls' : {'default' : 'homes.php', 
// 		'gallery' : 'homes.php', 
// 		'features' : 'homes_features.php',
// 		'plans' : 'homes_plans.php'
// 	}
// });
//------------------------------------------------------
// END menuItem example
//------------------------------------------------------



//------------------------------------------------------
// set up the menuItems hash with all the necessary info for DOM manipulation
//------------------------------------------------------
menuItems.each( function(pair) {
	// set the document title for the page
	menuItems.get(pair.key).set( 'title' , titles.get(pair.key) );

	// set the DOM id for the main div element
	menuItems.get(pair.key).set( 'divId' , navPrefix + pair.key );

	// set the DOM id for the img container div
	menuItems.get(pair.key).set( 'imgDivId' , 
		navPrefix + pair.key + imgDivSuffix
	);

	// set the DOM id for the reflected img container div
	menuItems.get(pair.key).set('imgReflectedDivId', navPrefix + pair.key + imgDivSuffix + reflectedImgSuffix);

	// set the DOM id for the subMenu div below the main nav menu bar
	menuItems.get(pair.key).set( 'subMenuDivId' , 
		navPrefix + pair.key + subMenuDivSuffix
	);

	// create a hash to contain the up (active) image src's
	var upImgHash = $H({ 
		'src' : 
			menuImgDir + navPrefix + pair.key + imgFileExtension,
		'reflectedSrc' : 
			menuImgDir + navPrefix + pair.key + reflectedImgSuffix + imgFileExtension
	});

	// create a hash to contain the down (inactive) image src's
	var downImgHash = $H({ 
		'src' : 
			menuImgDir + navPrefix + pair.key + downImgSuffix + imgFileExtension,
		'reflectedSrc' : 
			menuImgDir + navPrefix + pair.key + downImgSuffix + reflectedImgSuffix + imgFileExtension
	});

	// set the img src's
	menuItems.get(pair.key).set( 'upImg' , upImgHash );
	menuItems.get(pair.key).set( 'downImg' , downImgHash );
	
	// finally, preload all the images
	upImgHash.each( function (pair) {
		imagePreload(pair.value);
	});
	downImgHash.each( function (pair) {
		imagePreload(pair.value);
	});
	
	// set up urls for page contents
	var urls = new Hash();
	urls.set('default' , pair.key + '.php');
	// add urls for each submenu that is defined
	if ( hasSubMenu(pair.key) ) {
		subMenus.get(pair.key).each ( function(oneSubMenuPair) {
			urls.set( oneSubMenuPair.key , pair.key + '_' + oneSubMenuPair.key + '.php');
		});
	}
	menuItems.get(pair.key).set( 'urls' , urls);
});
//------------------------------------------------------
// END menuItems setup
//------------------------------------------------------


//------------------------------------------------------
// 				Functions of all kinds
//------------------------------------------------------



//------------------------------------------------------
// toggleImg (menuItem)
// switches image and reflected image from sepia to color (and vice-versa)
//------------------------------------------------------
function toggleImg (menuItem) {
	// first set the up image and its reflection
	var currentImg = $(menuItems.get(menuItem).get('imgDivId') ).down();
	var currentReflectedImg = $( menuItems.get(menuItem).get('imgReflectedDivId') ).down();
	var elmUpImgSrc = menuItems.get(menuItem).get('upImg').get('src');
	
	// if the up image is currently displayed, switch to the down image
	// use String.indexOf() to avoid issues with 
	// absolute URLs not matching relative URLs
	if ( currentImg.src.indexOf(elmUpImgSrc) != -1 ) {
		currentImg.src = menuItems.get(menuItem).get('downImg').get('src');

		// don't forget the reflection!
		currentReflectedImg.src = menuItems.get(menuItem).get('downImg').get('reflectedSrc');
	}
	else { //if the down image is currently displayed, swith to the up image
		currentImg.src = menuItems.get(menuItem).get('upImg').get('src');

		// don't forget the reflection!
		currentReflectedImg.src = menuItems.get(menuItem).get('upImg').get('reflectedSrc');		
	}
}


//------------------------------------------------------
// hasSubMenu (menuItem)
// returns true if menuItem's subMenuDivId is defined in the DOM
//------------------------------------------------------
function hasSubMenu (menuItem) {
	var returner = false
	// first check that menuItem is in the hash
	if ( menuItems.get(menuItem) ) {
		/*
		// return true if there is a DOM element with id=subMenuDivId
		var subMenuDivId = menuItems.get(menuItem).get('subMenuDivId');
		if ( $(subMenuDivId) ) returner = true;
		*/
		if (subMenus.get(menuItem)) returner = true;
	}
	return returner;
}


//------------------------------------------------------
// _navUp (menuItemUp, menuItemDown)
// activates one menu item and deactivates another using multiple animations
// menuItemUp: the newly selected menu item to make active
// menuItemDown: the previously selected menu item to make inactive
//
// The following effects are launched for menuItemUp
//	1. Move new item up
//	2. Switch image of new menu item from sepia to color
//	3. Move new item's reflection down
//	4. Switch image of new item's reflection from sepia to color
//	5. Show menu labels for new item
//	6. Show submenu for new item (if any)
//
// All of the above 1-6 are performed in reverse on menuItemDown
//------------------------------------------------------
function _navUp (menuItemUp, menuItemDown) {
	// increment to help reduce runaway animation chains
	numAnimations++;
	
	// set up some variables to access DOM elements by id
	var elmUp = menuItems.get(menuItemUp).get('divId');
	var elmUpReflection = menuItems.get(menuItemUp).get('imgReflectedDivId');
	var elmUpImg = $(menuItems.get(menuItemUp).get('imgDivId') ).down();		
	
	// set up some variables to access DOM elements by id	
	if (menuItemDown) { 
		var elmDown = menuItems.get(menuItemDown).get('divId');
		var elmDownImg = $(menuItems.get(menuItemDown).get('imgDivId') ).down();		
		var elmDownReflection = menuItems.get(menuItemDown).get('imgReflectedDivId');
	}
	
	// the default vertical distance to move an element (negative means up!)
	var yVal = -30;

	// first put menuItemUp's images in the up state	
	// 11/24/08 Client decided that images should always be in full-color
	//toggleImg(menuItemUp);
	
	// the animations are put into an array and triggered all at once using
	// Effect.Parallel
	var subEffects = $A([
		new Effect.Move( elmUp, { sync:true, x: 0, y: yVal, mode: 'relative'}	),
		new Effect.Move(elmUpReflection, {sync:true,x: 0, y: -yVal, mode: 'relative'})
	]);

	// animate the submenu if it exists in the DOM
	if ( hasSubMenu(menuItemUp) ) {
		subMenuDivId = menuItems.get(menuItemUp).get('subMenuDivId');
		subEffects.push(
			new Effect.SlideDown(subMenuDivId, {sync:true})
		);
	}

	// add animations for elmDown only if it exists
	if (typeof(elmDown) != 'undefined') {
		subEffects.push(
			new Effect.Move( elmDown, {sync:true, x: 0, y: -yVal, mode: 'relative'}),
			new Effect.Opacity( $(elmDown).down(), { sync:true, to: 0.0}),
			new Effect.Move(elmDownReflection, {sync:true, x: 0, y: yVal, mode: 'relative'})				
		);
		
		if ( hasSubMenu(menuItemDown) ) {
			subMenuDivId = menuItems.get(menuItemDown).get('subMenuDivId');
			subEffects.push(
				new Effect.SlideUp(subMenuDivId, {sync:true})
			);
		}
		// put menuItemDown's images in the down state
		// 11/24/08 Client decided that images should always be in full-color		
		// toggleImg(menuItemDown);
	}
	
	// finally launch the animations
	new Effect.Parallel( subEffects, 
		{ duration: 0.4, queue: 'end', 
			transition: Effect.Transitions.sinoidal,
			delay : 0.0,
			afterFinish : function () { 
				numAnimations--;
				new Effect.Opacity( $(elmUp).down(), { to: 1.0, duration:0.2});
			}
		}
	);
} 
//------------------------------------------------------
// END _navUp()
//------------------------------------------------------



//------------------------------------------------------
// navUp (e)
// wrapper function to activate a new menu item & 
// deactivate the previous menu item using multiple animations
// e: event that triggers the animation
// menuItem: menu entry to animate
// NOTE: calls _navUp using menuItem and currentNavItem 
//		 to do the actual animation
//------------------------------------------------------
function navUp (e, menuItem) {
	// don't do anything if the event came from the currently focused item
	// or if the event was triggered by a child element without an ID
	if ( numAnimations < 5 && menuItem != currentNavItem ) {
		_navUp ( menuItem , currentNavItem);
		currentNavItem = menuItem;
	}
}


//------------------------------------------------------
// thumbSrcConvert (thumbSrc)
// returns the URL of a large version of a thumbnail
// thumbSrc : complete URL (relative or absolute) of a thumbnail
// NOTE : this function only works if the following conventions are followed:
//	1. Naming : thumbnails have the exact same filename as full-size images
//	2. Directory : full-sized images are stored in largeImgDir (set at the top of this file)
//------------------------------------------------------
function thumbSrcConvert (thumbSrc) {
	// extract the filename only from the img src
	var imgFileName = thumbSrc.replace(/.*\//,'');
	// tack on the directory
	var returner = 	largeImgDir + imgFileName;
	return returner;
}


//------------------------------------------------------
// loadLargeImage (e)
// loads a large image into the image viewer after a thumbnail is clicked
// e : event that triggered this
// NOTE : e should be triggered from an img element!
// NOTE : the label will be set based on the thumbnail's ALT attribute
//------------------------------------------------------
function loadLargeImage (e) {
	var newSrc = thumbSrcConvert (Event.element(e).src);
	var newLabel = Event.element(e).alt;
	new Effect.Fade(largeImgDivId, {queue:'end', duration: 0.2, afterFinish: function() {
			$('large_image').down().next().src = newSrc;
			$(largeImgLabelDivId).innerHTML = newLabel;
			new Effect.Appear(largeImgDivId, {queue:'end', duration: 0.3} );	
		}
	});
}


//------------------------------------------------------
// imagePreload (imgSrc)
// preload an image into the cache to allow for faster loading
// imgSrc : complete URL (relative or absolute) of image
//------------------------------------------------------
function imagePreload (imgSrc) {
	var imgToPreload = new Image();
	imgToPreload.src = imgSrc;
}



function printFloorplan(imgSrc) {
	if (Prototype.Browser.IE)
		//IE mangles the print css, so just serve up a pdf in a new window
		popup( imgSrc.replace('png','pdf'), 600, 800);
	else
		window.print();
}

//------------------------------------------------------
// _GET (key)
// return a GET parameter from the URL
// mimics php's $_GET array
// adapted from : http://www.netlobo.com/url_query_string_javascript.html
//------------------------------------------------------
function _GET(key)
{
  key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var pattern = "[\\?&]"+key+"=([^&#]*)";
  var regex = new RegExp( pattern );
  var returner = regex.exec( window.location.href );
  if( returner == null ) 
		returner = "";
	else 
		returner = returner[1];
  return returner;
}


var elmToHide;

//------------------------------------------------------
// loadPage(pageToLoad)
// loads a new page into the content area and highlights the corresponding menu item
// pageToLoad : name (not URL!) of page to load
// parentMenu : for submenus, the parent menu item
//------------------------------------------------------
function loadPage(e, pageToLoad, exactUrl, parentMenu) {
	if (exactUrl) { // load the exact url passed
					// deprecated usage!
		var suffix = '';
	}
	else { // a regular page, tack on a file extension
		var suffix = '.php';
	}

	if (parentMenu) { // a submenu item
		var docTitle = subMenus.get(parentMenu).get(pageToLoad);
		var newPage = 'pages/' + parentMenu + '_' + pageToLoad + suffix;		
	}
	else { // a main menu item
		var docTitle = menuItems.get(pageToLoad).get('title');
		var newPage = 'pages/' + pageToLoad + suffix;
	}

	window.location.hash = newPage.replace('pages/','').replace('.php','');

	Effect.Fade('bodyContainer', { duration: 0.2, queue: 'end',
		afterFinish: function() {
			new Ajax.Updater('bodyContainer', newPage, 
				{ 
				onComplete: function() {
					Effect.Appear('bodyContainer',  {queue: 'end'});
					document.title = docTitle;
					// do some special processing for pages that need it
					// this is not ideal, but it works for now...
					// NEED TO deal with observer loading better
					// NEED TO deal with observer unloading on page change
					
					// the gallery page needs observers for the thumbnail images
					if (pageToLoad == 'homes' || pageToLoad == 'homes_gallery.php' || pageToLoad == 'gallery') {
						$('homes_content').getElementsBySelector('.thumbnail_group img').each( function(name) {
							// preload the large images using the thumbnail src's
							//imagePreload (thumbSrcConvert( $(name).src ));
							$(name).observe('click', loadLargeImage.bindAsEventListener(this) );
						});
					}
					// the eco_edge page has some simple rollover effects
					else if (pageToLoad == 'eco_edge') {
						var fo = new SWFObject("media/comfortwise_tour/FlowPlayerLP.swf", "FlowPlayer", "427", "262", "9", "#ffffff", true);
						  fo.addParam("AllowScriptAccess", "always");
						  fo.addParam("allowFullScreen", "true");
						  fo.addVariable("config", "{playList: [ { url: 'http://www.comfortwise.com/images/splash.jpg'}, { url: 'ComfortWise_01_Intro.flv' }, { url: 'ComfortWise_02_RightDesign.flv' }, { url: 'ComfortWise_03_Installation.flv' }, { url: 'ComfortWise_04_Testing.flv' }, { url: 'ComfortWise_05_Closing.flv' } ], showPlayListButtons: true, loop: true, initialScale: 'orig', autoBuffering: false, useNativeFullScreen: false, showMenu: false, fullScreenScriptURL: 'http://www.comfortwise.com/fullscreen.js' }");
						  fo.write("cw-tour");
						
						/* smiles
						// get all elements of class 'something_to_hide' because these sneaks all
						// have something to hide right underneath them
						var hiderArray = $$('.something_to_hide');
						
						
						// a little function to handle mouseover events
						function showHiddenCopy(e, targetElm) {

							Effect.toggle(targetElm, 'blind', {duration: 0.2, afterFinish : function() {
									if (elmToHide) Effect.toggle(elmToHide, 'blind', {duration: 0.3});
									elmToHide = targetElm;
								}
							});
							
							// to disable the link, return false to the element
							return false;
						}
						
						hiderArray.each( function (elm) {
							var elmToShow = elm.next();
							elm.observe('click', showHiddenCopy.bindAsEventListener(this, elmToShow) );
						});
						*/
					} else if (pageToLoad == 'location') {
						//removed
					}
				}
			});
		}
	});
	// set the default navigation item
	if (parentMenu) navUp(this, parentMenu);	
	else navUp (this, pageToLoad);
}



/// popup window function
// from the default global.js file
function popup(URL,w,h) {

day = new Date();
id = day.getTime();

var width = w;
var height = h;

var left = ((screen.width-width)/2);
var top = ((screen.height-height)/2);

eval("page" + id + " = window.open(URL, '" + id + 
	"', 'toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=0,width=' + width + ',height=' + height + ',left=' + left + ',top=' + top + '');"
);
}

//------------------------------------------------------
// 				END functions
//------------------------------------------------------



//------------------------------------------------------
// 				Events & Observers
//------------------------------------------------------

// Observers to launch on page load
document.observe("dom:loaded", function() {
	// observe the navigation items and move up the currently mouseover-ed item
	// the event is triggered when the associated image receives a mouseover
	menuItems.each( function(pair) {
		var rolloverObservee = menuItems.get(pair.key).get('imgDivId');
		var receiver = pair.key;
		$(rolloverObservee).observe( 'mouseover', navUp.bindAsEventListener(this , receiver) );
		
		// observe clicks on the navigation menu
		var menuClickObservee =	menuItems.get(pair.key).get('divId');
		//var pageToLoad = menuItems.get(pair.key).get('urls').get('default');
		var pageToLoad = pair.key;
		$(menuClickObservee).observe('click' , loadPage.bindAsEventListener(this, pageToLoad, false) );
		
		// observe clicks on the submenu items
		if ( hasSubMenu(pair.key) ) {
			var subMenuDiv = menuItems.get(pair.key).get('subMenuDivId');
			// get a list of all the defined submenus in the DOM
			var subMenuItems = $(subMenuDiv).getElementsBySelector('div.menu_label');
			subMenuItems.each( function (subMenuItem) {
				//var pageToLoad = menuItems.get(pair.key).get('urls').get(subMenuItem.title);
				$(subMenuItem).observe( 'click' , loadPage.bindAsEventListener(this, subMenuItem.title, false, pair.key) );
			});
		}


		// hide the labels dynamically to allow for 
		// reliable hide/show using scriptaculous
		$(menuItems.get(pair.key).get('divId')).down().setOpacity(0.0);
		$(menuItems.get(pair.key).get('divId')).down().style.visibility = 'visible';
	});

	// set the currentPage to default if it isn't set
	if (! currentPage) currentPage = defaultPage;
	
	// load the content for the current page
	loadPage(null, currentPage);	
}); // END document.observe()