/*
 *
 *	Brian Corr; Corr@F-Robots.com
 *	for F-Robots; F-Robots.com
 *	for The Guild; GuildIsGood.com
 *	2011
 *
 */

/*
 * REQUIRES: common_guild.js
 * 
 */

/* TODO: 
 * 		- pro-rate animation duration for short trips
 * 		-? header shows during loading - maybe just "loading"  
 * 
 */



// --- settings --- // 
var frameRate = 1000 / 35;
var animDur = 1000;


// --- vars --- //
var isMobile = false;

var leftTop = [0, 0]; 
var eye = new Object({x:0, y:0});

var scrollPos = 0;

var viewportH;

var getScrollPos;
var currentSection = 0;
var currentSectionPct;

var layers = [];
var pages = [];
var scrollMarkers = [0];

var transitionPx = 4000;
var scrollRatio = 4;
var sectionStayPx = 200;
var scrollEndMarginPx = 1;
var minScrollSectionPx = 0;

var animWhiteWash = new Object({from:0, to:1, at:1});

var resizeTimeout;

// --- sprites --- //
var scrollBox;
var stage;
var header;
var contentLayer;
var logoUnder;
var logoOver;

// --- jQuery objects --- //
var whiteWashJQO;
var logoOverJQO;

//--- scroll menu --- //
var menuBtns = [];
var isAnimating = false;
var animIvl;
var animation = new Object();



function onDocumentReady(){
	getScrollPos = initGetPageScroll();// - returns a function 
	
	// - sprites and sudo-sprites - //
	scrollBox = document.getElementById("scroll_box");
	stage = document.getElementById("stage");
	// - hide site until ready
	stage.style.display = "none";
	
	header = document.getElementById("header");
	logoOverJQO = $("#logo_over");
	whiteWashJQO = $("#white_wash");
	setWhiteWashAlpha(0);
	
	logoUnder = document.getElementById("logo_under");
	logoOver = document.getElementById("logo_over");
	
	if (isNonCompliantBrowser){
		document.getElementById("logo_outline").style.display = "inline-block";
	}
	
	setLogoOverAlpha(0);
	
	// - parallax layers - //
	makeLayer("layer0", 0.5);
	makeLayer("layer1", 1);
	makeLayer("layer2", 2);
	contentLayer = makeLayer("content_layer", 4);
	makeLayer("layer4", 0.3);
	
	makeLayer("layer5", 0.75);
	
	
	var grid = 500;//800;
	var pgPos1 = {x:2, y:3};//{x:2, y:-3};
	
	var pgPos4 = {x:pgPos1.x + 1.5, y:pgPos1.y + 0.5};// - set
	var pgPos2 = {x:pgPos4.x - 2, y:pgPos4.y + 1.4};// - set    //pgPos2 = {x:pgPos4.x + 1.5, y:pgPos4.y + 1.2};//pgPos2 = {x:pgPos1.x - 1.2, y:pgPos1.y -2.1};//
	var pgPos3 = {x:-0.5, y:1.5};//pgPos3 = {x:pgPos4.x + 1.5, y:pgPos4.y + 1.2};//pgPos3 = {x:pgPos1.x - 1.5, y:pgPos1.y - 1.9};
	makePage(0, 0, 0, "assets/logo_navy.png");
	makePage(1, pgPos1.x * grid, pgPos1.y * grid, "assets/logo_purple.png");//makePage(1, 6000, -4000);
	makePage(2, pgPos2.x * grid, pgPos2.y * grid, "assets/logo_green.png");//makePage(2, 8000, 1000);
	makePage(3, pgPos3.x * grid, pgPos3.y * grid, "assets/logo_orange.png");//makePage(3, 4000, 4000);
	makePage(4, pgPos4.x * grid, pgPos4.y * grid, "assets/logo_blue.png");
	
	pgNameIndex.home = 0;
	pgNameIndex.who = 1;
	pgNameIndex.work = 2;
	pgNameIndex.talent = 3;
	pgNameIndex.where = 4;
	
	// - extra elements - //
	document.getElementById("pgx_lr4_0").style.left = (1.4 * grid * layers[4].scrollMult)+"px";
	document.getElementById("pgx_lr4_0").style.top = (6 * grid * layers[4].scrollMult)+"px";
	$("#pgx_lr4_0").removeClass("hidden");
	
	// - mannequins 
	document.getElementById("pgx_lr1_0").style.left = (0.7 * grid * layers[1].scrollMult)+"px";//-0.5 * grid * layers[1].scrollMult;
	document.getElementById("pgx_lr1_0").style.top = (3.75 * grid * layers[1].scrollMult)+"px";
	$("#pgx_lr1_0").removeClass("hidden");
	
	// - cat nap 
	document.getElementById("pgx_lr5_0").style.left = (3.7 * grid * layers[5].scrollMult)+"px";//-0.5 * grid * layers[1].scrollMult;
	document.getElementById("pgx_lr5_0").style.top = (1.25 * grid * layers[5].scrollMult)+"px";
	$("#pgx_lr5_0").removeClass("hidden");
	
	// - bubble Annie 
	document.getElementById("pgx_lr2_0").style.left = (0.8 * grid * layers[2].scrollMult)+"px";
	document.getElementById("pgx_lr2_0").style.top = (1.45 * grid * layers[2].scrollMult)+"px";
	$("#pgx_lr2_0").removeClass("hidden");
	
	initButtons();
	
	// - once page is loaded and all sprites have been made:
	//if (isNonCompliantBrowser){
		//fixIEPNG();
	//}
	
	// - show site
	//stage.style.display = "inline-block";
	showSite();
	//loadLayerImages();//<-------------------------------------<<<
	// - initialize - //
	onResize();
	$(window).resize(resizeHandler);
	
	window.onscroll = onScroll;
	onScroll();
	updateMenuStatus();
}


/* - init factories - */
function makeLayer(id, scrollMult){
	$("#"+id).removeClass("hidden");// <--------------------------<<< 
	var layerObj = new Object();
	layerObj.element = document.getElementById(id);
	layerObj.scrollMult = scrollMult;
	layers.push(layerObj);
	return layerObj;
}

function makePage(id, x, y, logoSrc){
	var pageObj = new Object();
	pageObj.index = id;
	pageObj.x = x * contentLayer.scrollMult;// TODO: shift after for loop?
	pageObj.y = y * contentLayer.scrollMult;
	pageObj.eyeX = x;
	pageObj.eyeY = y;
	pageObj.element = document.getElementById("section"+id);
	pageObj.contentContainer = document.getElementById("pg"+id+"_content");//$("#section"+id+" > .container")[0];
	pageObj.offset = 0;
	pageObj.offsetPct = 0;
	pageObj.overflow = 0;
	pageObj.height = 0;
	pageObj.logoSrc = logoSrc;
	pageObj.logoImg = new Image();
	pageObj.logoImg.src = logoSrc;
	
	pageObj.figureHeight = function(){
		this.height = parseFloat( this.contentContainer.offsetHeight ) + parseFloat( getStyle(this.element, "padding-top") );
	}
	pageObj.figureHeight();
	
	pageObj.element.style.left = (pageObj.x)+"px";
	pageObj.element.style.top = (pageObj.y)+"px";
	
	var layerElement;
	var layerI;
	for (layerI = 0; layerI < layers.length; layerI++){
		layerElement = document.getElementById("pg"+id+"_lr"+layerI);
		if (typeof layerElement != 'undefined' && layerElement != null){
			layerElement.style.left = (x * layers[layerI].scrollMult)+"px";
			layerElement.style.top = (y * layers[layerI].scrollMult)+"px";
		}
	}
	
	// - 
	
	pageObj.setOffsetPct = function(pct){
		if (typeof pct != 'undefined' && !isNaN(pct)){
			this.offset = -(this.overflow * pct);
			this.offsetPct = pct;
		}else{
			this.offsetPct = this.overflow == 0 ? 0 : (-this.offset) / this.overflow;
		}
		
		this.contentContainer.style.top = (this.offset)+"px";
		
		return this.offsetPct;
	}
	
	pages.push(pageObj);
	
	return pageObj;
}


function resizeHandler(){
	onResize();
}

function onResize(altScrollPct){
	isAnimating = true;
	// - get section and percent
	var maintainScrollPos = [currentSection, currentSectionPct];
	if (typeof altScrollPct != 'undefined'){
		maintainScrollPos[1] = altScrollPct;
	}
	viewportH = $(window).height();
	
	var page;
	var newOverflow;
	var i;
	for (i = 0; i < pages.length; i++){
		page = pages[i];
		page.figureHeight();
		
		newOverflow = page.height - viewportH;
		if (newOverflow < minScrollSectionPx) newOverflow = minScrollSectionPx;
		page.overflow = newOverflow;
		scrollMarkers[i*2+1] = scrollMarkers[i*2] + newOverflow * scrollRatio + sectionStayPx;
		scrollMarkers[i*2+2] = scrollMarkers[i*2+1] + transitionPx;
	}
	
	scrollBox.style.height = (scrollMarkers[scrollMarkers.length - 1] + viewportH + scrollEndMarginPx)+"px";
	
	// - set section and percent after scrolling is done 
	clearTimeout(resizeTimeout);
	var resetScrollPos = function(){
		isAnimating = false;
		setSectionPercent(maintainScrollPos[0], maintainScrollPos[1]);
	}
	resizeTimeout = setTimeout(resetScrollPos, 100);
}


function getSectionPercent(){
	var section;
	var pct;
	var i = section = scrollMarkers.length - 1;
	while (i > 0 && scrollPos < scrollMarkers[i]){
		i--;
		section = i;
	}
	
	var beginVal = scrollMarkers[section];
	var endVal = scrollMarkers[section + 1];
	
	// - check for div by 0 - technically the ratio would be infinite ACCEPT that if the section has 0 height we must on the mark of beginning and end so we call it lock to the beginning. Even though 0/0 should be 1 (I know conventional math disagrees) but 
	pct = endVal - beginVal == 0 ? 0 : (scrollPos - beginVal) / (endVal - beginVal);
	
	return [section, pct];// could just return a real number but we'll be nice to our selves
}

function setSectionPercent(section, pct){
	if (typeof pct == 'undefined' || isNaN(pct)) pct = 0;
	
	currentSection = section;
	// TODO: repeat line; consolidate 
	currentPage = currentSection * 0.5; // - will not be an integer if we are in an animation section
	currentSectionPct = pct;
	var beginVal = scrollMarkers[section];
	var endVal = scrollMarkers[section + 1];
	var scrollTo = ((endVal - beginVal) * pct) + beginVal;
	var scrollDist = scrollTo - scrollPos;
	window.scrollBy(0, scrollDist);
}

function updateSectionPercent(){
	var scrollSectionPct = getSectionPercent();
	currentSection = scrollSectionPct[0];
	currentSectionPct = scrollSectionPct[1];
}


function onScroll(){
	leftTop = getScrollPos();
	stage.style.left = (-leftTop[0])+"px";
	header.style.left = (-leftTop[0])+"px";
	scrollPos = leftTop[1];
	
	
	// - we disregard page updates while animating
	// 		the animation will issue a scrollBy when it finishes 
	//		to update the scroll position to the animated-to position
	if (isAnimating) return;
	
	var prevSection = currentSection;
	updateSectionPercent();
	// - lock on section corner, 0 scroll - also resets scrollbar to 0
	//		there must be a frame update on a marker crossing, up or down
	if (currentSection != prevSection){
		var scrollTo;
		var animPct;
		
		// - set up percents assumes currentSection is a scroll section, then changed later if needed 
		if (currentSection < prevSection){// moving back
			currentSection = modulo(prevSection - 1, scrollMarkers.length - 1);
			animPct = 0;
			scrollTo = scrollMarkers[prevSection]-1;
		}else{// - moving forward
			currentSection = modulo(prevSection + 1, scrollMarkers.length - 1);
			animPct = 1;
			scrollTo = scrollMarkers[currentSection];
		}
		
		// TODO: repeat line; consolidate 
		currentPage = currentSection * 0.5; // - will not be an integer if we are in an animation section
		
		if (currentSection % 2 == 0){// if true the user has moved from an anim section into a scroll section
			handelTransition(prevSection, animPct);
		}else{// - user moved from a scroll section into and animation section 
			// - so we have to reverse the pct vals
			animPct = 1 - animPct;
			handelTransition(currentSection, animPct);
		}
		
		handelOverflow(currentSection, currentSectionPct);
		
		var scrollDist = scrollTo - scrollPos;
		
		updateMenuStatus();
		onPgChange();
		
		// - Safari in windows doesn't trigger the onScroll when a scrollBy is called from inside onScroll so ...
		scrollBySafariFix(scrollDist);
	}else{
		onManualScroll();
	}
}
function scrollBySafariFix(scrollDist){
	isAnimating = true;
	setTimeout( "scrollBySafariFix2("+scrollDist+")" , 1);
}
function scrollBySafariFix2(scrollDist){
	isAnimating = false;
	window.scrollBy(0, scrollDist);
}


function setWhiteWashAlpha(pct){
	animWhiteWash.at = pct;
	pct = pct * 0.7;
	whiteWashJQO.css('opacity', pct);
}


function setLogoOverAlpha(pct){
	logoOverJQO.css('opacity', pct);
}


function updateMenuStatus(){
	// - currentPage will not be an integer if we are in an animation section
	var btn;
	var btnI;
	for (btnI = 0; btnI < menuBtns.length; btnI++){
		btn = menuBtns[btnI];
		if(btn.pgId == currentPage){
			btn.setEnable(false, false);
			if (typeof btn.plusElement != 'undefined') btn.plusElement.style.display = "inline-block";
			logoUnder.src = pages[currentPage].logoImg.src;
		}else{
			btn.setEnable(true);
			if (typeof btn.plusElement != 'undefined') btn.plusElement.style.display = "none";
		}
	}
}


function onManualScroll(){
	handelOverflow(currentSection, currentSectionPct);
	
	if (currentSection % 2 != 0){// odd, animation section
		handelTransition(currentSection, currentSectionPct);
	}
}


function handelOverflow(section, pct){
	var oppositeSection = getOppositeSection(section);
	var page;
	var sectionI;
	var rangeMin;
	var rangeMax;
	var inRangeVal;
	var outRangeVal;
	
	if (section < oppositeSection){
		rangeMin = section;
		rangeMax = oppositeSection;
		inRangeVal = 0;
		outRangeVal = 1;
	}else{
		rangeMin = oppositeSection;
		rangeMax = section;
		inRangeVal = 1;
		outRangeVal = 0;
	}// if there is only one section?
	
	for (sectionI = 0; sectionI < scrollMarkers.length - 1; sectionI += 2){// - NOTE: count by 2
		page = pages[sectionI/2];
		if (sectionI == section){
			page.setOffsetPct(pct);
		}else if(sectionI == oppositeSection){
			page.setOffsetPct(1 - pct);
		}else if(rangeMin < sectionI && sectionI < rangeMax){
			page.setOffsetPct(inRangeVal);
		}else{
			page.setOffsetPct(outRangeVal);
		}
	}
}

function getOppositeSection(section){
	var base = scrollMarkers.length - 1;
	return modulo( (base/2) + section, base);
}


function handelTransition(section, pct){
	
	var fromPageId = (section - 1)/2;
	var fromSection = pages[fromPageId];
	
	var toPageId = modulo(fromPageId + 1, pages.length);
	var toSection = pages[toPageId];
	
	pct = defaultEase(pct);
	if (toPageId == 0){
		setWhiteWashAlpha(1-pct);
	}else if(fromPageId == 0){
		setWhiteWashAlpha(pct);
	}
	
	if (logoOver.src != toSection.logoImg.src){
		logoOver.src = toSection.logoImg.src;
	}
	setLogoOverAlpha(pct);
	
	if (fromPageId == 0){// - we want the first time a user scrolls the page for it to go down with the scroll then turn right
		var xPct = defaultYEase(pct);
		var yPct = defaultXEase(pct);
	}else{
		var xPct = defaultXEase(pct);
		var yPct = defaultYEase(pct);
	}
	
	eye.x = ((toSection.eyeX - fromSection.eyeX) * xPct) + fromSection.eyeX;
	eye.y = ((toSection.eyeY - fromSection.eyeY) * yPct) + fromSection.eyeY;
	
	moveEye();
}

function moveEye(x, y){
	if (typeof x != 'undefined') eye.x = x;
	if (typeof y != 'undefined') eye.y = y;
	
	var layer;
	var i;
	for (i = 0; i < layers.length; i++){
		layer = layers[i];
		layer.element.style.left = (-(eye.x * layer.scrollMult))+"px";
		layer.element.style.top = (-(eye.y * layer.scrollMult))+"px";
	}
}


// --- animation --- //

// - eases - //
function linearEase(pct){
	return pct;
}

function squareEase(pct){
	return pct * pct;
}

function rootEase(pct){
	return Math.sqrt(pct);
}

function sineEase(pct){
	return (Math.cos( (1 - pct) * Math.PI ) + 1) * 0.5;
}

var cubeEase = makeExponentialEase(3);// - returns a function 
var cubeRootEase = makeExponentialEase(1/3);// - returns a function 

var defaultEase = function(pct){
	pct = sineEase(pct);
	pct = sineEase(pct);
	//pct = sineEase(pct);
	return pct;
}//sineEase;
var defaultXEase = cubeRootEase;
var defaultYEase = cubeEase;

// --- //


function onMenuBtn(btnId){
	menuBtns[btnId].setEnable(false, false);
	scrollToPage(menuBtns[btnId].pgId);
}

function scrollToPage(pageId, scrollPx){
	var toOffset = 0;
	if (typeof scrollPx != 'undefined' && scrollPx != 0){
		toOffset = scrollPx / pages[pageId].overflow;
		toOffset = clamp(toOffset, 0, 1);
	}
	startToPageAnimation(
			{x:eye.x, y:eye.y}, 
			pages[pageId], 
			animDur, // TODO: pro-rate this for short trips
			defaultEase, //sineEase, //linearEase, 
			defaultXEase, //cubeRootEase, //rootEase, 
			defaultYEase, //cubeEase//squareEase
			toOffset
	);
}

function startToPageAnimation(fromPos, page, duration, animationEase, xEase, yEase, toOffset){
	clearInterval(animIvl);
	isAnimating = true;
	
	if (typeof animationEase != 'function') animationEase = linearEase;
	if (typeof xEase != 'function') xEase = linearEase;
	if (typeof yEase != 'function') yEase = linearEase;
	
	animation.page = page;
	animation.fromPos = fromPos;
	animation.fromOffset = animation.page.setOffsetPct();
	animation.toOffset = toOffset;
	animation.duration = duration;
	animation.animationEase = animationEase;
	animation.xEase = xEase;
	animation.yEase = yEase;
	
	animWhiteWash.from = animWhiteWash.at;
	if (page.index == 0){
		animWhiteWash.to = 0
	}else{
		animWhiteWash.to = 1;
	}
	setLogoOverAlpha(0);
	logoOver.src = page.logoImg.src;
	
	animation.startTime = new Date();
	animIvl = setInterval(animateToPageOnFrame, frameRate);
}

function animateToPageOnFrame(){
	var nowTime = new Date();
	var elapsed = nowTime - animation.startTime;
	var pct = elapsed / animation.duration;
	var done = false;
	if (pct >= 1){
		pct = 1;
		done = true;
	}
	
	pct = animation.animationEase(pct);
	var xPct = animation.xEase(pct);
	var yPct = animation.yEase(pct);
	var newOffsetPct = (animation.toOffset - animation.fromOffset) * pct + animation.fromOffset;
	var whiteWashAlpha = (animWhiteWash.to - animWhiteWash.from) * pct + animWhiteWash.from; 
	
	setWhiteWashAlpha(whiteWashAlpha);
	setLogoOverAlpha(pct);
	animation.page.setOffsetPct(newOffsetPct);
	eye.x = (animation.page.eyeX - animation.fromPos.x) * xPct + animation.fromPos.x;
	eye.y = (animation.page.eyeY - animation.fromPos.y) * yPct + animation.fromPos.y;;
	moveEye();
	
	if (done){
		clearInterval(animIvl);
		setSectionPercent(animation.page.index * 2, animation.toOffset);
		
		updateMenuStatus();
		onPgChange();
		isAnimating = false;
		onScroll();
	}
}


function initButtons(){
	menuBtns[0] = makeImageButton("#logo", "#home_roll_over", "assets/logo_navy.png", onMenuBtn, 0);
	menuBtns[0].pgId = 0;
	
	
	menuBtns[1] = makeImageButton("#who_btn", "#who_btn", "assets/menu_who_bold.png", onMenuBtn, 1);
	menuBtns[1].pgId = 1;
	menuBtns[1].plusElement = document.getElementById("plus_who");
	
	menuBtns[2] = makeImageButton("#work_btn", "#work_btn", "assets/menu_work_bold.png", onMenuBtn, 2);
	menuBtns[2].pgId = 2;
	menuBtns[2].plusElement = document.getElementById("plus_work");
	
	menuBtns[3] = makeImageButton("#talent_btn", "#talent_btn", "assets/menu_talent_bold.png", onMenuBtn, 3);
	menuBtns[3].pgId = 3;
	menuBtns[3].plusElement = document.getElementById("plus_talent");
	
	menuBtns[4] = makeImageButton("#where_btn", "#where_btn", "assets/menu_where_bold.png", onMenuBtn, 4);
	menuBtns[4].pgId = 4;
	menuBtns[4].plusElement = document.getElementById("plus_where");
	
}



// --- utilities --- //
// - in common_guild.js

