

	/*********************************************************
	*  X31 Main Scripts File                                 *
	*  All scripts are the copyrighted work of               *
	*  ElectricStorm // PrintedExistence.com unless          *
	*  otherwise stated.                                     * 
	/********************************************************/
	
	
	
	//=======================================================
	//  OnLoad Stuff
	//=======================================================
	
	
	// when document ready, initialize other functions
	window.onload = activate;
	
	
	// on DOCUMENT load, initialize other functions: 
	function activate() {
		blurLinks();
		goToCorrectPage(); //(ajax fetch the right page)
		setInterval('goToCorrectPage()', 500); //(run this function repeatedly (every 1/2 second) to ensure it updates if user clicks back button)	
	}
	
	
	
	// blurLinks function
	// Gets rid of the annoying dotted line that appears around clicked links.
	function blurLinks() {
		
		var links = document.getElementsByTagName('A');
		
		for (var i = 0; i < links.length; i++) { 
			currentLink = links[i];
			currentLink.onfocus = function() { this.blur(); };
		}
		
	}
	
	
	
	//(use this to check whether hash has changed each time we re-run goToCorrectPage)
	var prevHash = '#home'; 
	
	
	// goToCorrectPage function
	// loads in the correct ajax pane depending on hash in the url (if there is one).
	function goToCorrectPage() {
			
		var theHash = window.location.hash;
		
		//if the hash has changed since the last time we ran this function...
		if (theHash != prevHash) {		
							
			//load in the appropriate ajax pane (will also update prevHash)
			var thePage = theHash.substr(1); //(cut off the #) 
			swapPage(thePage); 
	
		}
	
	}
	
	
	//=======================================================
	
	
	
	
	
	
	//=======================================================
	//  Ajax Functions
	// (this section contains no site-specific references).
	//=======================================================
	
	
	// define xmlHttp as global var 
	// (this way we can use it to check whether a request is in progress)
	var xmlHttp = null;
	
	
	// ajaxCreate function 
	// creates the HttpRequest object for the other ajax functions and passes it back.
	// (receives the containerId for use in the onreadystatechange bit)
	function ajaxCreate(containerId) {
	
		try {
			//Firefox, Opera 8.0+, Safari, IE7+
			xmlHttp = new XMLHttpRequest();
		}
		catch (e) {
			
			try {
				//IE 6 and older- preference:
				xmlHttp = new ActiveXObject('MSXML2.XMLHTTP.6.0');
			}
			catch (e) {
				
				try {
					//IE 6 and older- last chance- use anything! 
					//(nb, never call to just MSXML2 as versions other than 6 and 3 are broken)
					xmlHttp = new ActiveXObject('MSXML.XMLHTTP');
				}
				catch (e) {
					//(browser can't understand ajax):
					return false;
				}
			}
		}

	
		//onreadystatechange property: stores function that will process the response from server.
		xmlHttp.onreadystatechange = function() {
		
			//readyState 4 means the request is complete.
			if (xmlHttp.readyState == 4) {
	
				//responseText holds the servers response.
				document.getElementById(containerId).innerHTML = xmlHttp.responseText;
				
				//set global var back to null when we're done with it (so we know whether it's ok to start another request):
				xmlHttp = null;
			}
	
		}
		
		return xmlHttp;
	
	}
	
	
	
	// ajaxFetch function 
	// fetches a file in with ajax and places it in the given container.
	function ajaxFetch(containerId, fetchPage) {
	
		//create the HttpRequest object using my seperate function:
		var xmlHttp = ajaxCreate(containerId);
		
		//if HttpRequest object created successfully send request:
		if (xmlHttp != null) {	
			//open takes 3 params: method, url, asyncronous (true/false).
			xmlHttp.open('GET', fetchPage, true);	
			xmlHttp.send(null);
		}
		
	}
	
	
	
	// ajaxPost function 
	// submits the contents of a form to a processing page using ajax.
	function ajaxPost(containerId, formId, processingPage) {
	
		//create the HttpRequest object using my seperate function:
		var xmlHttp = ajaxCreate(containerId);
		
		//if HttpRequest object created successfully...
		if (xmlHttp != null) {	
	
			//fetch the form & process the contents into a string seperated by ampersands using my processForm function:
			var theForm = document.getElementById(formId);
			var params = processForm(theForm);
			
			//open takes 3 params: method, url, asyncronous (true/false).
			xmlHttp.open('POST', processingPage, true);
			xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
			xmlHttp.send(params);
	
		}
	
	}
	
	
	
	// processForm function 
	// processes the form fields and returns a single ampersand seperated string of name / value pairs.
	function processForm(theForm) {
	
		var str = '';
	
		//loop through every field in the form:
		for (var i = 0; i < theForm.elements.length; i++) {	
			
			//if text field / textarea / hidden / radio / submit:
			if (theForm.elements[i].type == 'text' || theForm.elements[i].type == 'password' || theForm.elements[i].type == 'textarea' 
			|| theForm.elements[i].type == 'hidden' || theForm.elements[i].type == 'radio' || theForm.elements[i].type == 'submit') {	
				str += theForm.elements[i].name + '=' + escape(theForm.elements[i].value) + '&';
			}			
			//if select box:
			else if (theForm.elements[i].type == 'select-one') {
				str += theForm.elements[i].name + '=' + theForm.elements[i].options[theForm.elements[i].selectedIndex].value + '&';
			}				
			//if checkbox: 
			if (theForm.elements[i].type == 'checkbox') {	
				//just add it with an "on" if it is checked:
				if (theForm.elements[i].checked == true) {
					str += theForm.elements[i].name + '=on&';
				}
			}			
		
		}
	
		//add a final var (in case processing pages need to distinguish between forms sent with php & with ajax):
		str += 'ajaxform=true';
		
		//need to encode any + signs in the string (otherwise they get replaced with spaces):
		str = str.replace(/\+/g, '%2B');		
		
		return str;
	
	}
	
	
	//=======================================================
	
	
	
	
	
	
	//=======================================================
	//  Page Swapping
	// this section handles the ajax page swapping and requires:
	// 1. the ajax functions section above.
	// 2. the looping goToCorrectPage function (see onload section).
	//=======================================================
	
	
		
	
	//array of all valid pages with their paths:
	var validPages = new Array();
	validPages['about'] = 'http://x31.net/folio/content/pages/about.php';
validPages['blog'] = 'http://x31.net/folio/content/pages/blog.php';
validPages['contact'] = 'http://x31.net/folio/content/pages/contact.php';
validPages['flows'] = 'http://x31.net/folio/content/pages/flows.php';
validPages['home'] = 'http://x31.net/folio/content/pages/home.php';
validPages['home_bak'] = 'http://x31.net/folio/content/pages/home_bak.php';
validPages['websites'] = 'http://x31.net/folio/content/pages/websites.php';
validPages['wireframes'] = 'http://x31.net/folio/content/pages/wireframes.php';
	
	
	//array of all pages that have titles with their titles:
	var pageTitles = new Array();
	pageTitles['home'] = 'X31 - Experience Design';
pageTitles['login'] = 'X31 - Experience Design - Log In';
pageTitles['logout'] = 'X31 - Experience Design - Log Out';
pageTitles['lostpass'] = 'X31 - Experience Design - Lost Password';
pageTitles['changepass'] = 'X31 - Experience Design - Change Password';
	
	
	
	// swapPage function
	// nb, if OPTIONAL allowRefresh param is 1, we will reload the same page (e.g. at the end of a login lockout).
	// 1. checks the given content page is valid and new.
	// 2. sets the location hash so this page state can be bookmarked / gone back to.
	// 3. update prevhash so we won't reload this page. 
	// 4. take the user to the top of the page, and load in the new content.
	// 5. update the window title.
	// 6. activate swapPage2() to setup new content when ready.
	function swapPage(toPage, allowRefresh) {	
		
		//set default for optional allowRefresh:
		if (allowRefresh == undefined) { allowRefresh = 0; }
		
		//see whether given toPage is key in the validPages array above (i.e. is valid):
		if (validPages[toPage] == undefined) { 
			//if it isn't, reset it to home:
			toPage = 'home';
		}	
	
		//if we're going to a new page...
		if ('#' + toPage != prevHash || allowRefresh == 1) {
		
			//set the hash so we can recognise this page state:
			window.location.hash = toPage;
			
			//grab the from page for setting the bulge bg:
			var fromPage = prevHash.substr(1);
			
			//update the global too so we don't keep reloading the same content:
			prevHash = '#' + toPage; 
		

			//handle the current page link marking. 

			//first the bottom links (about / contact):
			//(these just need the class adding to make them orange if current page, and removing if not).	
			if (toPage == 'contact') {
				document.getElementById('contactlink').className = 'navslinkon';
			}
			else {
				document.getElementById('contactlink').className = '';
			}
			
			if (toPage == 'about') {
				document.getElementById('aboutlink').className = 'navslinkon';
			}
			else {
				document.getElementById('aboutlink').className = '';
			}
			
			//now the top links (home, flows, wireframes, websites, blog):
			var topNavPages = new Array();
			topNavPages['home'] = 'x31 homepage';
topNavPages['flows'] = 'view our site flow diagrams';
topNavPages['wireframes'] = 'view our wireframes';
topNavPages['websites'] = 'view our websites';

			//adjust the actual links (to either clickable or static current page):
			for (var p in topNavPages) {
				
				//if this is the to page, write in the current page image (no link):
				if (p == toPage) { 
					if (document.getElementById(p + 'link')) { //(only necessary if it is currently a link)
						document.getElementById(p + 'td').innerHTML = '<img src="http://x31.net/folio/grafix/navs/' + p + '_on.png" alt="' + p + '" />';
					}
				}
				//if it isn't the to page, make sure it is a clickable link:
				else {
					if (!document.getElementById(p + 'link')) { //(only necessary if it is currently NOT a link)						
						
						var theLink = '<a href="http://x31.net/folio/index.php&#63;p=' + p + '" title="' + topNavPages[p] + '" id="' + p + 'link" ';
						theLink += 'onclick="swapPage(\'' + p + '\'); return false;" onmouseover="fadeOut(\'' + p + 'img\', 20);" onmouseout="fadeIn(\'' + p + 'img\', 20);">'; 
						theLink += '<img src="http://x31.net/folio/grafix/navs/' + p + '.png" alt="' + p + '" id="' + p + 'img" /></a>';
						
						document.getElementById(p + 'td').innerHTML = theLink;					
					}	
				}
				
			}
			
			//now deal with the bulge background on the top right navs:
			
			//NB, SECTION EDITED SO THE BULGE GOES TO HOME FOR ABOUT OR CONTACT TOO.
			
			/*
			//if we're going to a page that isn't one of the top 5, clear the bulge completely:
			if (!topNavPages[toPage]) {
				document.getElementById('navs').className = 'navsbgpos0';
			}
			else {
			*/
				//if we're coming from a page that isn't one of the top 5, just stick the bulge in with no slide:
				//if (!topNavPages[fromPage]) {
					
					if (toPage == 'flows') { document.getElementById('navs').className = 'navsbgpos2'; }
					else if (toPage == 'wireframes') { document.getElementById('navs').className = 'navsbgpos3'; }
					else if (toPage == 'websites') { document.getElementById('navs').className = 'navsbgpos4'; }
					// else if (toPage == 'blog') { document.getElementById('navs').className = 'navsbgpos5'; }
					else { document.getElementById('navs').className = 'navsbgpos1'; }	
				
				//}
				//else {
				
					//if we're going from one top 5 to another, slide the background along:
					
					//first determine the from bg position:
					if (fromPage == 'flows') { var fromPos = 50; }
					else if (fromPage == 'wireframes') { var fromPos = 124; }
					else if (fromPage == 'websites') { var fromPos = 200; }
					// else if (fromPage == 'blog') { var fromPos = 254; }
					else { var fromPos = 0; }
					
					//and the to bg position: 
					if (toPage == 'flows') { var toPos = 50; }
					else if (toPage == 'wireframes') { var toPos = 124; }
					else if (toPage == 'websites') { var toPos = 200; }
					// else if (toPage == 'blog') { var toPos = 254; }
					else { var toPos = 0; }
					
					slideBulge(fromPos, toPos);
				
				//}	
			
			//}

			
			//ensure the user is brought to the top of the new page (they may have scrolled down):
			instantPageTop();
		
			//do the ajax fetch:
			ajaxFetch('pagecontent', validPages[toPage]);	
	
			//update the window title:
			toPageTitle = toPage;
			if (pageTitles[toPageTitle] == undefined) {
				toPageTitle = 'home'; //(home title is default- some pages may not have own title)
			}
			document.title = pageTitles[toPageTitle];
	
			//and run the swapPage2 function to setup the new content:
			swapPage2();
		
		}
	
	}
	
	
	
	// swapPage2 function
	// 1. waits until the ajax content has arrived.
	// 2. runs blurLinks again to blur all the links on the new content pane.
	// 3. sets up any page-specific content (adds scripts etc).
	function swapPage2() {
	
		//if ajax content isn't in yet, wait patiently...
		if (xmlHttp != null) {
			setTimeout('swapPage2()', 50);
		}
		else { //when ready...
	
			//blur links in the new content:
			blurLinks();


			//login page:
			//if lock-out countdown form is showing, insert countdown script:
			if (document.getElementById('cdform')) {
				
				//allow script access (this is a protected script):
				ajaxFetch('inviscontent', 'http://x31.net/folio/content/includes/scriptaccess.php?to=1');
				
				insertScript('countdown.php');
				
				//also hide the refresh link here (doing it in the countdown script doesn't work if reloading page):
				document.getElementById('login_refreshlink').style.display = 'none';				
			}
			
		}
	
	}
	
	
	
	// insertScript function
	// inserts the given script once ajax content (script access file) is fetched
	// then turns script access off again. 
	function insertScript(scriptName) {
	
		//if script access isn't in yet, wait patiently...
		if (xmlHttp != null) {
			setTimeout('insertScript(\'' + scriptName + '\')', 50);
		}
		else { //when ready...
		
			//create the script id (name minus any none-alphanumeric chars like dots):
			var scriptId = scriptName.replace(/[^a-zA-Z0-9]+/g, '');
			
			//check the new script doesn't already exist
			//(re-adding can cause multiple instances of the script to run at once!)
			if (!document.getElementById(scriptId)) { 

				//if ok add the new script:
				var newScript = document.createElement('script');
				newScript.src = 'http://x31.net/folio/scripts/' + scriptName;
				newScript.id = scriptId;
				document.body.appendChild(newScript);						
			
			}
			
			//and turn off script access again:
			ajaxFetch('inviscontent', 'http://x31.net/folio/content/includes/scriptaccess.php');
		}
				
	}
	
	
	
	// instantPageTop function
	// brings the user instantly to the top of the page.
	// (used after swapping a page).
	function instantPageTop() {
	
		var distScrolled = window.pageYOffset;
		
		//(IE understands document.documentElement.scrollTop instead of window.pageYOffset):
		if (distScrolled == undefined) {
			distScrolled = document.documentElement.scrollTop;
		}
			
		window.scrollBy(0, 0 - distScrolled); 
	
	}
	
	
	
	// TOP RIGHT NAVS BACKGROUND SLIDING
	
	// store timeout in global so can be accessed by both slideBulgeLeft and slideBulgeRight functions (so they never overlap and get stuck!)
	var bulgeTimeout; 
	

	// slideBulge function
	// slides the top right menu bulge bg left or right by the given amount.
	function slideBulge(currentPos, endPos) {
	
		//stop the slideBulge function (if it is still looping)
		clearTimeout(bulgeTimeout);
	
		//set the jumpSize and jumpSpeed:
		var jumpSize = 3;
		var jumpSpeed = 10;
		currentPos = parseInt(currentPos);
		endPos = parseInt(endPos);
	
		//if not already at endPos:
		var newPos = currentPos + (endPos > currentPos ? jumpSize : -jumpSize);
	
		if ((newPos > currentPos && newPos >= endPos) || (newPos < currentPos && newPos <= endPos)) {
			newPos = endPos;
		} 
		else {
			bulgeTimeout = setTimeout("slideBulge('"+newPos+"', '"+endPos+"')", jumpSpeed);
		}
	
		//make the bg position adjustment:
		document.getElementById('navs').style.backgroundPosition = newPos + 'px bottom';
	
	}


	//=======================================================
		
	
	
	
	
	
	//=======================================================
	//  General Functions (misc reusable stuff)
	//=======================================================
	
	
	// FADE IN / OUT:
	
	var currentOpacity = new Array(); //(store current opacity of each element in global (so in / out functions can both access))
	var fadeInTimeout = new Array(); //(stop fade in / out functions from overlapping each other)
	var fadeOutTimeout = new Array(); //(^ditto- 2 separate arrays prevent values from being immediately readded if loops overlap)
	
	
	// fadeIn function
	// fades a layer in.
	function fadeIn(itemID, fadeSpeed) {
		
		//console.log("fadeIn | ItemID: ", itemID, " | fadeInTimeout[itemID]: ", fadeInTimeout[itemID], " | currentOpacity[itemID]: ", currentOpacity[itemID], " | opacity: ", document.getElementById(itemID) ? document.getElementById(itemID).style.opacity : "no element");


		if (document.getElementById(itemID)) { //(check exists- can be errors if swapping fading items)
		
			//stop the fadeOut function (if it is still looping)
			if (fadeOutTimeout[itemID] && fadeOutTimeout[itemID] != "monkeh") { 
				
				//console.log("FADE IN CLEARED TIMEOUT | ItemID: ", itemID, " | fadeOutTimeout[itemID]: ", fadeOutTimeout[itemID]);
				
				clearTimeout(fadeOutTimeout[itemID]); 
				fadeOutTimeout[itemID] = 'monkeh'; //(aribtary static value that isn't empty (so it still works on the first loop))
			}
			
			//see've currentOpacity is set for this element:
			if (currentOpacity[itemID] == undefined) {
				//if not set the default start opacity:
				currentOpacity[itemID] = 0;
			}
			
			currentOpacity[itemID] += 10;
		
			var theItem = document.getElementById(itemID);
			theItem.style.opacity = currentOpacity[itemID] / 100.0;
			theItem.style.filter = 'alpha(opacity='+ currentOpacity[itemID] +')'; 
			
			if (currentOpacity[itemID] < 100) {
				fadeInTimeout[itemID] = setTimeout('fadeIn("'+itemID+'", "'+fadeSpeed+'")', fadeSpeed);
			}
			else {
				clearTimeout(fadeInTimeout[itemID]); 
				fadeInTimeout[itemID] = undefined; //(clear any monkehs)
			}
		
		}
		else {
			clearTimeout(fadeInTimeout[itemID]); 
			fadeInTimeout[itemID] = undefined; //(clear any monkehs)
		}
		
	}
	
	
	// fadeOut function
	// fades a layer out. 
	function fadeOut(itemID, fadeSpeed) {
				
		//console.log("fadeOut | ItemID: ", itemID, " | fadeOutTimeout[itemID]: ", fadeOutTimeout[itemID], " | currentOpacity[itemID]: ", currentOpacity[itemID], " | opacity: ", document.getElementById(itemID) ? document.getElementById(itemID).style.opacity : "no element");


		if (document.getElementById(itemID)) { //(check exists- can be errors if swapping fading items)

			//stop the fadeIn function (if it is still looping)
			if (fadeInTimeout[itemID] && fadeInTimeout[itemID] != "monkeh") { 
				
				//console.log("FADE OUT CLEARED TIMEOUT | ItemID: ", itemID, " | fadeInTimeout[itemID]: ", fadeInTimeout[itemID]);
				
				clearTimeout(fadeInTimeout[itemID]); 
				fadeInTimeout[itemID] = 'monkeh'; //(aribtary static value that isn't empty (so it still works on the first loop))
			}
		
			//see've currentOpacity is set for this element:
			if (currentOpacity[itemID] == undefined) {
				//if not set the default end opacity:
				currentOpacity[itemID] = 100;
			}
		
			currentOpacity[itemID] -= 10;

			var theItem = document.getElementById(itemID);	
			theItem.style.opacity = currentOpacity[itemID] / 100.0;
			theItem.style.filter = 'alpha(opacity='+ currentOpacity[itemID] +')'; 
			
			if (currentOpacity[itemID] > 0) {
				fadeOutTimeout[itemID] = setTimeout('fadeOut("'+itemID+'", "'+fadeSpeed+'")', fadeSpeed);
			}
			else {
				clearTimeout(fadeOutTimeout[itemID]); 
				fadeOutTimeout[itemID] = undefined; //(clear any monkehs)
			}
		
		}
		else {
			clearTimeout(fadeOutTimeout[itemID]); 
			fadeOutTimeout[itemID] = undefined; //(clear any monkehs)
		}
			
	}
	
	
	
	
	// SLIDE LEFT / RIGHT:
	
	// store timeouts for each individual sliding item in array (stops them interfering with each other)
	// in global so can be accessed by both slideLeft and slideRight functions (so they never overlap and get stuck!)
	var hSlideTimeout = new Array(); 
	
	
	// slideLeft function
	// slides the given absolutely positioned element to the left by the given amount.
	// jumpSize and jumpSpeed are optional (defaults are set inside).
	function slideLeft(itemID, currentPos, endPos, jumpSize, jumpSpeed) {
		
		//stop the slideRight function for this item (if it is still looping)
		clearTimeout(hSlideTimeout[itemID]);
	
		//set the default jumpSize and jumpSpeed (if not passed):
		if (jumpSize == null) { jumpSize = 3; }
		if (jumpSpeed == null) { jumpSpeed = 10; }
	
		//multiplying converts passed sizes to ints (otherwise JS would just append)
		currentPos *= 1;
		endPos *= 1;
		jumpSize *= 1;
		jumpSpeed *= 1;
		
		//if not already at endPos:
		//(nb, remember we're going backwards (to the left) so slide if endPos is smaller)
		if (currentPos > endPos) {
							
			//- jumpSize px:
			var newPos = currentPos - jumpSize; 
			//see've we've jumped below the desired endPos- if so, set as that: 
			if (newPos < endPos) { newPos = endPos; }
				
			//make the position adjustment:
			document.getElementById(itemID).style.left = newPos + 'px';
			
			//if we're not yet at endPos, wait jumpSpeed ms then go again:
			if (newPos > endPos) {
				hSlideTimeout[itemID] = setTimeout("slideLeft('"+itemID+"', '"+newPos+"', '"+endPos+"', '"+jumpSize+"', '"+jumpSpeed+"')", jumpSpeed);
			}
			//otherwise DELETE the timeout from the global array
			//(this is so other functions can tell whether we're finished sliding this item):
			else { 
				delete(hSlideTimeout[itemID]);
			}
		}		
		else { 
			delete(hSlideTimeout[itemID]);
		}
	
	}
	
	
	// slideRight function
	// slides the given absolutely positioned element to the right by the given amount.
	// jumpSize and jumpSpeed are optional (defaults are set inside).
	function slideRight(itemID, currentPos, endPos, jumpSize, jumpSpeed) {
	
		//stop the slideLeft function for this item (if it is still looping)
		clearTimeout(hSlideTimeout[itemID]);
		
		//set the default jumpSize and jumpSpeed (if not passed):
		if (jumpSize == null) { jumpSize = 3; }
		if (jumpSpeed == null) { jumpSpeed = 10; }
	
		//multiplying converts passed sizes to ints (otherwise JS would just append)
		currentPos *= 1;
		endPos *= 1;
		jumpSize *= 1;
		jumpSpeed *= 1;
	
		//if not already at endPos:
		if (currentPos < endPos) {
			
			//+ jumpSize px:
			var newPos = currentPos + jumpSize; 
			//see've we've jumped above the desired endPos- if so, set as that: 
			if (newPos > endPos) { newPos = endPos; }
				
			//make the position adjustment:
			document.getElementById(itemID).style.left = newPos + 'px';
			
			//if we're not yet at endPos, wait jumpSpeed ms then go again:
			if (newPos < endPos) {
				hSlideTimeout[itemID] = setTimeout("slideRight('"+itemID+"', '"+newPos+"', '"+endPos+"', '"+jumpSize+"', '"+jumpSpeed+"')", jumpSpeed);
			}
			//otherwise DELETE the timeout from the global array
			//(this is so other functions can tell whether we're finished sliding this item):
			else { 
				delete(hSlideTimeout[itemID]);
			}
		}		
		else { 
			delete(hSlideTimeout[itemID]);
		}
	
	}
	
	
	
	
	// getUrlStart function 
	// gets the first part of the given url (everything except the filename).
	function getUrlStart(theUrl) {
		
		//split the url by the slashes:
		var urlArr = theUrl.split('/');	
		var newUrl = '';
		
		for (var i = 0; i < urlArr.length -1; i++) { //(-1 cuts off the last array item (the filename))
			newUrl += urlArr[i] + '/';	
		}
		
		return newUrl;	
		
	}
	
	
	
	
	// showInlineEl function
	// makes an inline element visible.
	function showInlineEl(theEl) {
		if (document.getElementById(theEl)) {
			document.getElementById(theEl).style.display = 'inline';
		}
	}
	
	
	// showBlockEl function
	// makes an block level element visible.
	function showBlockEl(theEl) {
		if (document.getElementById(theEl)) {
			document.getElementById(theEl).style.display = 'block';
		}
	}
	
	
	// hideEl function
	// makes the given element invisible.
	function hideEl(theEl) {
		if (document.getElementById(theEl)) {
			document.getElementById(theEl).style.display = 'none';
		}
	}
	
	
	//=======================================================
	
	
	
	
	
	
	//=======================================================
	//  Homepage Stuff
	//=======================================================
	
	
	// CLIENTS SLIDESHOW:
	
	// array containing all logos to appear in the show, in order, in their blocks of 4:
	var homeClientLogos = new Array();
	homeClientLogos[0] = new Array('misc/cbs.png', 'misc/cyberarts.png', 'misc/ebay.png', 'misc/evb.png');
	homeClientLogos[1] = new Array('misc/salesforce.png', 'misc/sapient.png', 'misc/stubhub.png', 'misc/syndero.png');
	homeClientLogos[2] = new Array('misc/filemaker.png', 'misc/fp.png', 'misc/ing.png', 'misc/quantcast.png');
	homeClientLogos[3] = new Array('healthcare/amgen.png', 'healthcare/astra.png', 'healthcare/ucsf.png', 'healthcare/genentech.png');
	homeClientLogos[4] = new Array('healthcare/gsk.png', 'healthcare/jazz.png', 'healthcare/medtronic.png', 'healthcare/pfizer.png');
	// homeClientLogos[5] = new Array('healthcare/cephalon.png'); //(note, only 1 here)
	
	
	//currently visible slide (index in homeClientLogos array):
	var homeClientsCurSlide = 1; //(nb, 0 is initially invisible so it can slide in)
	
	//set a global to determine whether the show is currently moving 
	//(complete each move before allowing user to initiate another):
	var homeClientsMoving = 0;
	
	
	
	// moveHomeClientsShow function
	// 1. locks self down so we can't slide again until finished
	// 2. moves the relevant slides
	// 3. kicks off part 2.
	function moveHomeClientsShow(direction) {
		
		//only proceed if we're not already moving:
		if (homeClientsMoving == 0) {
			
			//block us from moving again until finished:
			homeClientsMoving = 1;
	
			//determine which direction we're sliding in (right is default):
			if (direction == 'left') {
				//go left:
				slideLeft('homeclientlogosinner2', 0, -256, 5); //(middle box off the stage) 
				slideLeft('homeclientlogosinner3', 256, 0, 5); //(right box on to the stage)
			}
			else {		
				//go right:
				slideRight('homeclientlogosinner2', 0, 256, 5); //(middle box off the stage) 
				slideRight('homeclientlogosinner1', -256, 0, 5); //(left box on to the stage)
			}
				
			//now set off the next part of the function
			//(it will wait until the slides are finished before starting):
			moveHomeClientsShow2(direction);
				
		}
	
	}
	
	
	
	// moveHomeClientsShow2 function
	// 1. waits until all slides are finished moving
	// 2. deletes the surplus slide and reassign the IDs
	// 3. updates the homeClientsCurSlide global with new current slide
	// 4. resets homeClientsMoving global (so we can slide again)
	function moveHomeClientsShow2(direction) {	
		
		//wait until we're done sliding all slides before activating this function
		//(important that we don't switch IDs too early or slides may move twice!)
		if (hSlideTimeout['homeclientlogosinner1'] || hSlideTimeout['homeclientlogosinner2'] || hSlideTimeout['homeclientlogosinner3']) {
			setTimeout("moveHomeClientsShow2('"+direction+"')", 200);
		}
		else {
	
			//fetch all 3 slides (as we'll be deleting things / changing ids)
			var slide1 = document.getElementById('homeclientlogosinner1');
			var slide2 = document.getElementById('homeclientlogosinner2');
			var slide3 = document.getElementById('homeclientlogosinner3');
			
			//and the container: 
			var theCont = document.getElementById('homeclientlogos');
			
			
			//determine which direction we've slid in (right is default):
			if (direction == 'left') {
				
				//if we slid left:
		
				//delete the lefthand box- old center one has replaced it:
				theCont.removeChild(slide1);
				
				//shift the IDs up:
				slide2.id = 'homeclientlogosinner1';
				slide3.id = 'homeclientlogosinner2';
				
				//and the new slide we're going to create's ID will be...
				var newSlideID = 'homeclientlogosinner3';
				
				//set the new current slide in homeClientsCurSlide global:
				homeClientsCurSlide += 1;
				if (homeClientsCurSlide >= homeClientLogos.length) {
					homeClientsCurSlide = 0; 
				}
		
				//now determine the content of the slide we'll be creating:		
				var newSlideNum = homeClientsCurSlide + 1; //(plus ANOTHER 1)
				if (newSlideNum >= homeClientLogos.length) {
					newSlideNum = 0; 
				}	
			
			}
			else {		
				
				//if we slid right:
		
				//delete the righthand box- old center one has replaced it:
				theCont.removeChild(slide3);
				
				//shift the IDs down:
				slide2.id = 'homeclientlogosinner3';
				slide1.id = 'homeclientlogosinner2';
				
				//and the new slide we're going to create's ID will be...
				var newSlideID = 'homeclientlogosinner1';
				
				//set the new current slide in homeClientsCurSlide global:
				homeClientsCurSlide -= 1;
				if (homeClientsCurSlide < 0) {
					homeClientsCurSlide = homeClientLogos.length -1; //(-1 because it starts from 0)
				}
		
				//now determine the content of the slide we'll be creating:		
				var newSlideNum = homeClientsCurSlide - 1; //(minus ANOTHER 1)
				if (newSlideNum < 0) {
					newSlideNum = homeClientLogos.length -1; //(-1 because it starts from 0)
				}
		
			}
						
	
			//now create the new box (this part is the same whichever way we slid):
			var newBox = document.createElement("DIV");	
			newBox.className = 'homeclientlogosinner';
			newBox.setAttribute('id', newSlideID);
					
			//add the appropriate logos:
			var loopNo = 1;
			for (var i = 0; i < homeClientLogos[newSlideNum].length; i++) {
				//(nb, if we edit this, make sure we edit the html version to match)
				newBox.innerHTML += '<a href="http://x31.net/folio/index.php&#63;p=about" title="view all our clients">' + 
									'<img src="http://x31.net/folio/content/clientlogos/' + homeClientLogos[newSlideNum][i] + '" width="120px" height="60px" alt="" ' + 
									'class="homeclientlogo' + loopNo + '" /></a>';
				loopNo++;
			}
				
			theCont.appendChild(newBox);
				
			
			//reset homeClientsMoving global (so we can slide again):	
			homeClientsMoving = 0;
				
		}
	
	}
	
	
	//=======================================================
		
				
	
			
	
	
	//=======================================================
	//  Slideshow Stuff (used on 3 pages)
	//=======================================================
	
	
	// call in the info from config...
	
	// 1. websites slideshow.
	
	var ssSiteTitles = new Array();
	ssSiteTitles['01'] = 'Food Perfected';
ssSiteTitles['02'] = 'Jacob Health Care';
ssSiteTitles['03'] = 'NeuroField';
ssSiteTitles['04'] = 'Om Limo';
ssSiteTitles['05'] = 'Om Limo Reservations';
ssSiteTitles['06'] = 'SuperGraphics';
ssSiteTitles['07'] = 'Marijuana Social Network';
ssSiteTitles['08'] = 'eBay / StubHub';
ssSiteTitles['09'] = 'Armanino Family Cellars';
	
	var ssSiteUrls = new Array();
	ssSiteUrls['01'] = '<a href="http://www.foodperfected.com" title="food perfected" target="_blank">www.foodperfected.com</a>';
ssSiteUrls['02'] = '<a href="http://x31.net/jacobs" title="jacob healthcare center" target="_blank">Jacob HealthCare</a>';
ssSiteUrls['03'] = '<a href="http://www.neurofield.com" title="neurofield" target="_blank">www.neurofield.com</a>';
ssSiteUrls['04'] = '<a href="http://www.omlimo.com" title="om limo" target="_blank">www.omlimo.com</a>';
ssSiteUrls['05'] = '<a href="http://www.omlimo.com/#reservations" title="om limo reservations" target="_blank">www.omlimo.com</a>';
ssSiteUrls['06'] = '<a href="http://x31.net/super/flash/" title="supergraphics" target="_blank">SuperGraphics Flash Gallery</a>';
ssSiteUrls['07'] = '';
ssSiteUrls['08'] = '<a href="http://www.stubhub.com/account/" title="ebay / stubhub" target="_blank">www.stubhub.com/account/</a>';
ssSiteUrls['09'] = '<a href="http://www.armaninofamilycellars.com" title="armanino family cellars" target="_blank">www.armaninofamilycellars.com</a>';
	
	var ssSiteRoles = new Array();
	ssSiteRoles['01'] = 'Role: IA, UX, PM, Visual Design, Development';
ssSiteRoles['02'] = 'Role: IA, UX, PM, Visual Design, Development';
ssSiteRoles['03'] = 'Role: IA, UX, PM, Visual Design, Development';
ssSiteRoles['04'] = 'Role: IA, UX, PM, Visual Design, Development';
ssSiteRoles['05'] = 'Role: IA, UX, PM, Visual Design, Development';
ssSiteRoles['06'] = 'Role: Front End Website Development, IA, UX, PM for Flash Gallery';
ssSiteRoles['07'] = 'Role: UX, Visual Design, Development';
ssSiteRoles['08'] = 'Role: IA, UI';
ssSiteRoles['09'] = 'Role: IA, UX, PM, Visual Design, Development';
	
	var ssSiteDescs = new Array();
	ssSiteDescs['01'] = 'Requirements were: clean, easy, always know where you are, use Facebook style navigation, keep the links page, and colors (lime) from the legacy site. Added sliding Nav arrow, designed in the AJAX; home buckets slide open.';
ssSiteDescs['02'] = 'This was an complex project as there are 5 websites that needed different information, photos, job postings, etc. <a href="#" title="read more" id="site02morelink" onclick="showInlineEl(\'site02more\'); hideEl(\'site02morelink\'); return false;">Read More...</a> <span id="site02more" style="display: none;">We wanted to keep it as single view as possible, so we created front end portlets with JavaScript, so that site visitors could get quick info regarding: hospital info, request a brochure, or general contact info from the home page. We also added show hide to the jobs descriptions, and the backend area where administrators could make changes to all site page content.</span>';
ssSiteDescs['03'] = 'Healthcare site for a colleague who needed a simple way to allow providers to communicate via a message board with each other, and push out firmware updates securely potential for commerce. Not X31 maintained.';
ssSiteDescs['04'] = 'Client wanted a clean site where a patron could see photos, read yelp reviews, and reserve online. We set up the API to bring in the Yelp feeds and JS to display pricing totals in real-time, In-Line validation during reservations, PayPal checkout.';
ssSiteDescs['05'] = 'Client wanted a clean site where a patron could see photos, read yelp reviews, and reserve online. We set up the API to bring in the Yelp feeds and JS to display pricing totals in real-time, In-Line validation during reservations, PayPal checkout.';
ssSiteDescs['06'] = 'Circa 1999-2000. Flash Gallery.';
ssSiteDescs['07'] = '';
ssSiteDescs['08'] = 'My Account.';
ssSiteDescs['09'] = 'Armanino wanted backgrounds that carried their wine labels, and for those labels to be in the banner. We also designed a custom WordPress theme you can see on the "What\'s New" Page. Crushpad used the code to integrate e-commerce/online ordering.';
	
	
	// 2. wireframes slideshow.
	
	var ssWireTitles = new Array();
	ssWireTitles['01'] = 'FileMaker';
ssWireTitles['02'] = 'Dashboard (Generic)';
ssWireTitles['03'] = 'Image Viewer';
ssWireTitles['04'] = 'Pharmaceutical Game';
ssWireTitles['05'] = 'Kiosk';
ssWireTitles['06'] = 'Food Perfected';
ssWireTitles['07'] = 'Community Convalescent Hospital';
ssWireTitles['08'] = 'Om Limo';
ssWireTitles['09'] = 'eBay / StubHub';
	
	var ssWireUrls = new Array();
	ssWireUrls['01'] = '<a href="https://store.filemaker.com/US/ENG/LIC?nav=volume-licensing" title="Visit the FileMaker Volume Licensing site" target="_blank">FileMaker Volume Licensing Site</a>';
ssWireUrls['02'] = '';
ssWireUrls['03'] = '';
ssWireUrls['04'] = '';
ssWireUrls['05'] = '';
ssWireUrls['06'] = '<a href="http://www.foodperfected.com" title="food perfected" target="_blank">www.foodperfected.com</a>';
ssWireUrls['07'] = '<a href="http://x31.net/jacobs" title="community convalescent hospital" target="_blank">Jacob HealthCare</a>';
ssWireUrls['08'] = '<a href="http://www.omlimo.com" title="om limo" target="_blank">www.omlimo.com</a>';
ssWireUrls['09'] = '<a href="http://www.stubhub.com/account/" title="ebay / stubhub" target="_blank">www.stubhub.com/account/</a>';
	
	var ssWireRoles = new Array();
	ssWireRoles['01'] = 'Role: IA/UX';
ssWireRoles['02'] = 'Role: IA/UX';
ssWireRoles['03'] = 'Role: IA/UX';
ssWireRoles['04'] = 'Role: IA/UX';
ssWireRoles['05'] = 'Role: IA/UX';
ssWireRoles['06'] = 'Role: IA, UX, PM, Visual Design, Development';
ssWireRoles['07'] = 'Role: IA, UX, PM, Visual Design, Development';
ssWireRoles['08'] = 'Role: IA, UX, PM, Visual Design, Development';
ssWireRoles['09'] = 'Role: IA, UI';
	
	var ssWireDescs = new Array();
	ssWireDescs['01'] = 'Volume Licensing (in-build)';
ssWireDescs['02'] = '';
ssWireDescs['03'] = 'This image viewer had editing tools on the top page and each image stack drilled into a side by side image comparison of before and after treatment.';
ssWireDescs['04'] = 'This wire was done completely in Visio to express part of a 9 section game to teach doctors about a disease. The page was titled: Locate the 3 clues to advance...';
ssWireDescs['05'] = 'Used a screenshot of a Sony plasma as a background as this design was specifically for convention persons to walk by and be prompted to start selecting criteria for a pseudo-patient.';
ssWireDescs['06'] = 'Initial wireframe handed off to Dev for the home page of the food perfected catering website.';
ssWireDescs['07'] = 'This view shows the left hand contact portlet in open position. All 3 portlets opened to try to offer users effortless access to immediate information. We later found a similar feature on the southwest airlines site (<a href="http://www.southwest.com" title="southwest.com" target="_blank">www.southwest.com</a>).';
ssWireDescs['08'] = 'Initial wireframe for the reservation page / contact tab. Tabs not shown in this view, they came later in the design as we realized we had the ability to add fares in real-time using Ajax, then allow users to add contact info and pay via PayPal.';
ssWireDescs['09'] = 'Styleguide (asked for at the last minute) for a ultra high fidelity wireframe/GUI that was developed as is on handoff.';
	
	
	// 3. process flows slideshow.
	
	var ssFlowTitles = new Array();
	ssFlowTitles['01'] = 'E-Commerce Product Search vs. Browse';
ssFlowTitles['02'] = 'Process Flows';
ssFlowTitles['03'] = 'User paths';
ssFlowTitles['04'] = 'Game - User paths';
ssFlowTitles['05'] = 'Swim Lanes (Reporting Structure)';
ssFlowTitles['06'] = 'Finance Flow';
ssFlowTitles['07'] = 'User Flow (Marketing)';
ssFlowTitles['08'] = 'Product and marketing flow (Generic)';
ssFlowTitles['09'] = 'Project Runway Game - User Flow';
	
	var ssFlowUrls = new Array();
	ssFlowUrls['01'] = '';
ssFlowUrls['02'] = '';
ssFlowUrls['03'] = '';
ssFlowUrls['04'] = '';
ssFlowUrls['05'] = '';
ssFlowUrls['06'] = '';
ssFlowUrls['07'] = '';
ssFlowUrls['08'] = '';
ssFlowUrls['09'] = '';
	
	var ssFlowRoles = new Array();
	ssFlowRoles['01'] = 'Role: IA/UX';
ssFlowRoles['02'] = 'Role: IA/UX';
ssFlowRoles['03'] = 'Role: IA/UX';
ssFlowRoles['04'] = 'Role: IA/UX';
ssFlowRoles['05'] = 'Role: IA';
ssFlowRoles['06'] = 'Role: IA/UX';
ssFlowRoles['07'] = 'Role: IA/UX';
ssFlowRoles['08'] = 'Role: IA/UX';
ssFlowRoles['09'] = 'Role: IA/UX';
	
	var ssFlowDescs = new Array();
	ssFlowDescs['01'] = 'Mapping of an E-Commerce site (www.viator.com) for disection purposes in order to design our front end to incorporate the API feeds.';
ssFlowDescs['02'] = 'E-Commerce Volume licensing flow of site visitors and those driven in by email campaigns and renewals for annual and site licensing.';
ssFlowDescs['03'] = '';
ssFlowDescs['04'] = '';
ssFlowDescs['05'] = 'These swim lanes (in this case, where we want to display how a task crosses over with a role) were created to determine which personas engineering would need to associate a user with a role';
ssFlowDescs['06'] = '';
ssFlowDescs['07'] = '';
ssFlowDescs['08'] = 'This is a genericized user flow for a marketer or advertiser who wanted to create or select a product and build a campaign.';
ssFlowDescs['09'] = 'This was a blueprint for the Project Runway game at <a href="http://www.fantasyrunway.com" title="project runway" target="_blank">www.fantasyrunway.com</a> (defunct). Requirements included a game with points system, league ability (friends can join forces), and instant messaging between participants. Winner went to Bryant park in NYC for the show finale.';
	
	
	
	// ssSwapMain function
	// swaps the main slideshow image, title and info to the given slide. 
	function ssSwapMain(toNo, whichShow) {
		
		//swap the main stage image:
		var mainImg = document.getElementById('ssmain');
		var oldNo = mainImg.src.substr(mainImg.src.length - 6, 2);
		mainImg.src = getUrlStart(mainImg.src) + toNo + '.jpg';
		
		//see which show we're on, and set us up to refer to the correct arrays:
		if (whichShow == 'wireframes') {
			var titlesArr = ssWireTitles;
			var urlsArr = ssWireUrls;
			var rolesArr = ssWireRoles;
			var descsArr = ssWireDescs;
		}
		else if (whichShow == 'flows') {
			var titlesArr = ssFlowTitles;
			var urlsArr = ssFlowUrls;
			var rolesArr = ssFlowRoles;
			var descsArr = ssFlowDescs;	
		}
		else {
			var titlesArr = ssSiteTitles;
			var urlsArr = ssSiteUrls;
			var rolesArr = ssSiteRoles;
			var descsArr = ssSiteDescs;
		}
			
		//swap the title and url below the main stage image:
		document.getElementById('sstitle').innerHTML = titlesArr[toNo];
		document.getElementById('sslink').innerHTML = urlsArr[toNo];
		
		//swap the title, role and description on the right:
		document.getElementById('ssdesctitle').innerHTML = titlesArr[toNo];
		document.getElementById('ssdescrole').innerHTML = rolesArr[toNo];
		document.getElementById('ssdesctext').innerHTML = descsArr[toNo];
		
		//swap the gold border to the new current slide thumb (only if changing):
		if (oldNo != toNo) {
			var ssThumbs = document.getElementById('ssthumbtable').getElementsByTagName('IMG');
			
			for (var i = 0; i < ssThumbs.length; i++) {
				if (ssThumbs[i].src.substr(ssThumbs[i].src.length - 6, 2) == toNo && ssThumbs[i].className == 'ssthumb') {
					ssThumbs[i].className = 'ssthumbon'; 
				}
				else if (ssThumbs[i].className == 'ssthumbon') {
					ssThumbs[i].className = 'ssthumb'; 
				}
			}
		}
		
	}
	
	
	
	// ssGoToPrevSlide function
	// goes to the previous slide (or back to 9 if we are on 1) 
	// nb, this is a quick-n-dirty designed to work only with exactly 9 slides. 
	function ssGoToPrevSlide(whichShow) {
			
		//get only the image number (sans leading zero) from the main image url:
		var mainImg = document.getElementById('ssmain');
		var curNo = mainImg.src.substr(mainImg.src.length - 5, 1);
		
		//if we're on 1, go to 9, otherwise go to curNo - 1:
		if (curNo == 1) {
			var prevSlide = '09';
		} 
		else {
			var prevSlide = '0' + (parseInt(curNo) - 1);
		}
		
		//and swap the slide: 
		ssSwapMain(prevSlide, whichShow); 
		
	}
	
	
	
	// ssGoToNextSlide function
	// goes to the next slide (or back to 1 if we are on 9) 
	// nb, this is a quick-n-dirty designed to work only with exactly 9 slides. 
	function ssGoToNextSlide(whichShow) {
			
		//get only the image number (sans leading zero) from the main image url:
		var mainImg = document.getElementById('ssmain');
		var curNo = mainImg.src.substr(mainImg.src.length - 5, 1);
	
		//if we're on 9, go to 1, otherwise go to curNo + 1:
		if (curNo == 9) {
			var nextSlide = '01';
		} 
		else {
			var nextSlide = '0' + (parseInt(curNo) + 1);
		}
		
		//and swap the slide: 
		ssSwapMain(nextSlide, whichShow); 
		
	}

	
	//=======================================================


	



