/* ---------------- Global init -------------------------- */
$(document).ready(function() {
	//Init scroller
	var qscroller = scroller.hookUp({
		container: '#scroller',
		list: '#phrases',
		quote: '.phrase'
		});
	scroller.init(qscroller);

	//Init address rolldowns
		$('.office span').bind('click', toggleAddress);

	//Init font size detector
	if (!$.browser.msie) //IE has its own offsets, over 9000 in value
	{
		$('.business .horzbar').hide(); //IE is just not up to the task
	}	
		var detector = resizeDetector.init({
			container: '#visual'
		});
	
		$(window).bind('resize', function(){
			onFontResize();
		});
	

	//Init timeline browser
	
	var timeMachine = tBrowser.hookUp({
		timescale: $('#timescale'),
		prospects: $('#prospects'),
		overlays: $('#overlays'),
		prophecy: $('.prophecy'),
		display: $('#display'),
		year: '2012'
	});
	var inited = timeMachine.runner.length;
	if(inited)
		tBrowser.init(timeMachine);
	
});


/* ---------------- Office address switcher --------------------------- */
function toggleAddress(event)
{
	var clicked = $(this).parents('.office');

	if (! ( $(clicked).hasClass('selected')  ) )
	{
		var all = $('#offices-list').find('.office');
		var current = $(all).siblings('.selected');
		var currenttext = $(current).find('p');
		var newtext = $(clicked).find('p');


		//hide

		$(currenttext).slideUp('fast', function(){
			$(current).removeClass('selected');
			$(current).find('span').addClass('pseudo');
			$(clicked).find('span').removeClass('pseudo');

			//show
			var cwidth = $('.contact').width();
			$(newtext).css({width: cwidth});
			$(newtext).slideDown('normal', function(){$(clicked).addClass('selected');});

		});


	}
}

/* ---------------- Top speech bubble scroller ------------------------ */

var scroller = {}

scroller.hookUp = function(sParams)
{
	//hook up html elements
	this.container = $(sParams.container);
	this.list = $(sParams.list);
	this.quote = $(sParams.quote);

	var defParams = {
		container: $('#scroller'),
		list: $('#phrases'),
		quote: $('.phrase')
	};

	return $.extend({}, defParams, sParams ? sParams : {});
}

scroller.init = function(hookUp){
	var leftBtn = $(hookUp.container).find("#left");
	var rightBtn = $(hookUp.container).find('#right');

	var numPhrases = $(hookUp.list).children('div').length;

	//random phrase here
	var randomIndex = Math.floor(Math.random() * numPhrases) + 1;
	scroller.select(randomIndex, hookUp);

	leftBtn.bind('click', {
		dir: -1,
		q: numPhrases,
		hookUp: hookUp
	}, scroller.scroll);
	rightBtn.bind('click', {
		dir: 1,
		q: numPhrases,
		hookUp: hookUp
	}, scroller.scroll);

}

scroller.scroll = function(event)
{
	if (!$(event.data.hookUp.container).siblings('.phrase').is(':animated')) {
		var currentIndex = $(event.data.hookUp.quote).attr('id');
		currentIndex = currentIndex.substr(currentIndex.indexOf('_') + 1, 1);
		var selectIndex = parseInt(currentIndex) + parseInt(event.data.dir);
		selectIndex = ((selectIndex > event.data.q) ? 1 : (selectIndex == 0 ? event.data.q : selectIndex));
		scroller.select(selectIndex, event.data.hookUp);
	}
}

scroller.select = function(i, hookUp)
{
	var selected = $(hookUp.list).children('#quote_'+i);
	var newTitle = selected.find('.title').html();
	var newPhrase = selected.find('.quote').html();

	$(hookUp.container).children('#title').html(newTitle+'<span class="shadow">' + newTitle + '</span>');

	var replacedPhrase = $(hookUp.container).siblings('.phrase');

	replacedPhrase.fadeOut('fast', function(){
		replacedPhrase.html(newPhrase).attr('id', 'quote_'+i);
	});

	replacedPhrase.fadeIn('normal');
}

/* ------------------- (Simple) Text resize detector ----------------------- */
var resizeDetector = {};

resizeDetector.init = function(sParams)
{
	//hook up container
	this.container = $(sParams.container);

	var defParams = {
		container: $('html')
	};

	//update starting params
	sParams = $.extend({}, defParams, sParams ? sParams : {});

	if ($(sParams.container + '#textResizeControl').length == 0) //create measurer
	{
		var textSizeMeasurer = $('<span></span>').attr({'id' : 'textResizeControl'}).css({position: 'absolute', left: -9999, width: '1ex', height: '1ex'}).html('&nbsp;').prependTo($(sParams.container));
	}

	//ok, got the measurer, take its size
	var iSize = textSizeMeasurer.height();
	var startSize = iSize;
	var nSize = -1;

	//initial fire
	onFontResize(iSize);

	//set up timer
	setInterval (function(){
		var nSize = textSizeMeasurer.height();
		if (nSize != iSize) {
			iSize = nSize;
			onFontResize(startSize);
		}
		return iSize;
	}, 200);

	return 0;
}

function onFontResize(startSize){
	
     //get the baseline of anchor element ('Our business')
	 var bItem = $('li.business');
	 var baseLine = bItem.offset().top + bItem.height();

	 //get the baseline of the bar, which should remain constant relative to map
	 var bar = $('#mapbar');
	 var map = $('.analytics .map');
	 var barBase = map.offset().top + 225; //225px to the lowest point

	 var newHeight = barBase - baseLine + 35;

	 if (newHeight > 120) //grow up
	 {
		 bar.css({
			 height : newHeight < 120 ? 120 : newHeight,
			 marginTop : 120 - newHeight
		 });
	 }
	 else
	 {
		 if (newHeight < 0) //grow down
		 {
			 bar.css({
				height : 145 - newHeight,
				marginTop: 0
			 });
		 }
		 else//rely on doubling div
		 {
			 bar.css({
				 height: 120,
				 marginTop : 0
			});
		 }
	 }
	 
	 //arrest values
	 var values = $('.balloon');
	 var measurer = $('#textResizeControl');
	 var iefix = 0;
	 var safarifix = 0;
	 if ($.browser.webkit)
	 {
		 safarifix = (navigator.vendor.indexOf('Apple') != -1) ? -1 : 0;
	 }
	 //alert('ssize:' + startSize + ', mh:' + measurer.height());
	 if ($.browser.msie){
		 iefix = -1 + (measurer.height() - 8);
	 }

	 values.css({
		 fontSize: 24 + safarifix + iefix - (measurer.height() > 17 ? 17 : measurer.height())
	 });
 }

/* ------------- Timeline browser ----------------- */
var tBrowser = {}

tBrowser.hookUp = function(sParams)
{
	//hook up html elements
	this.timescale = $(sParams.timescale);
	this.prospects = $(sParams.prospects);
	this.overlays = $(sParams.overlays);
	this.prophecy = $(sParams.prophecy);
	this.texts = $(sParams.texts);
	this.display = $(sParams.display);
	this.runner = $(sParams.runner);

	var defParams = {
		timescale: $('#timescale'),
		prospects: $('#prospects'),
		overlays: $('#overlays'),
		prophecy: $('#prophecy'),
		display: $('#display'),
		runner: $('#runner'),
		rOffset: 0
	};

	return $.extend({}, defParams, sParams ? sParams : {});
}

tBrowser.init = function(hookUp)
{
	//fix the runner offset
	hookUp.rOffset = $(hookUp.runner).position().left;

	//bind the years
	var years = $(hookUp.timescale + ".wrapper .year");
	$(years).each(function()
	{
		var id = $(this).attr('id');
		if( id.indexOf('y') == 0 )
		{
			$(this).bind('click', {year: id.substr(1,4), hookUp: hookUp}, tBrowser.click );
			$(this).addClass('clickable');
		}
	});
	
	//preload images

	var imgArray = Array();
	var ovlImgs = hookUp.overlays.find('img');
	ovlImgs.each( function(intIndex) {
		var img = new Image;
		img.src = $(this).attr('src');
		imgArray[intIndex] = img;
	});

	hookUp.runner.bind('mousedown', {hookUp: hookUp}, tBrowser.runnerDown);
	
	//build up the timescale
	var wrapper = $(hookUp.timescale).children('.wrapper');
	var ww = wrapper.width();

	var scales = wrapper.children('.year');
	
	//find first and last years of the timescale;
	var ts_start = $(scales).filter('.first').attr('id');
	ts_start = ts_start.substr(1,4);
	
	var ts_end = $(scales).filter('.last').attr('id');
	ts_end = ts_end.substr(1,4);
	
	var timespan = ts_end - ts_start;
	var xOffset = 0;
	
	scales.each(function (index) {
		
		var c_year = $(this).attr('id');
		c_year = c_year.substr(1, 4);
		
		var n_year = ts_start;
		
		var c_width = 0;
		
		var isLast = $(this).hasClass('last');
		
		if( !isLast )
		{
			n_year = $(scales[index+1]).attr('id');
			n_year = n_year.substr(1, 4);
			
			var c_span = n_year - c_year;
			c_width = c_span * 120 / timespan;
			
			$(this).css({ width: c_width + '%' });
		}
		$(this).css({left: xOffset + '%'});		
		xOffset += c_width;
		
	});
	
	wrapper.removeClass('hidden');
	
	tBrowser.select(hookUp.year, hookUp);
}

tBrowser.click = function(event)
{
	tBrowser.select(event.data.year, event.data.hookUp)
}

tBrowser.runnerDown = function(event)
{
	event.preventDefault(); //prevent dragging in Firefox

	if($.browser.msie){//Prevent dragging in IE
		$('html').bind('selectstart',function(){return false;});
	}

	var prophecy = $(event.data.hookUp.prophecy);
	
	jTweener.removeTween($(this));
	jTweener.removeTween(prophecy);

	$('html').bind('mousemove', {
			rX: $(this).position().left,
			tW: $(event.data.hookUp.timescale).width(),
			iX: event.pageX,
			iY: event.pageY,
			runner: $(this),
			prophecy: prophecy,
			pX: prophecy.position().left,
			pW: prophecy.width(),
			rOffset: event.data.hookUp.rOffset
		}, tBrowser.runnerMove);

	$('html').bind('mouseup', {hookUp: event.data.hookUp}, tBrowser.runnerUp);

	return false; //disable text selection in Opera
}

tBrowser.runnerMove = function(event)
{
	var xOffset = event.data.iX - event.pageX; 

	//var yOffset = event.data.iY - event.clientY;//don't need Y anyway
	var newpos = event.data.rX - xOffset;
	var pOffset = event.data.pX - xOffset;

	newpos = (newpos < event.data.rOffset ? event.data.rOffset : newpos > event.data.tW-25 ? event.data.tW-25 : newpos);
	pOffset = (pOffset < -100 ? -100: pOffset > event.data.tW-60 ? event.data.tW-60 : pOffset)

	$(event.data.runner).css({
		left: newpos
	});

	$(event.data.prophecy).css({
		left: pOffset
	});
}

tBrowser.runnerUp = function(event)
{
	$('html').unbind('mousemove');
	$('html').unbind('mouseup');

	if($.browser.msie)
		$('html').unbind('selectstart');

	tBrowser.snap(event.data.hookUp);
}

tBrowser.select = function(year, hookUp, rpos)
{
	//if the year is already selected, do nothing
		//update the year display
		var millenium = year.substr(0, 2);
		var yr = year.substr(2,2);
		var shadow = hookUp.display.siblings('.shadow');
		hookUp.display.html(millenium + '<span class="current">' + yr + '</span>');
		$(shadow).html(year);

		var ydata = hookUp.prospects.children('#prospect'+year);

		//update map - the trickiest part

		var olays = hookUp.overlays.children('.overlay.hidden');
		var shown = hookUp.overlays.children('.overlay').not('.hidden');
		
		//IE handles opacity weirdly, so no fade in/out for it
		var fadetime = ($.support.opacity == true) ? 300 : 0;

		//get the list of items to hide
		var toHide =  shown.filter(function(){
			
			return parseInt( ($(this).attr('id')).substr(4, 4) ) > parseInt(year);

		}).fadeOut(fadetime, function(){$(this).addClass('hidden');});

		//get the list of items to show
		var toShow = olays.filter(function(){
			return ( parseInt( ($(this).attr('id')).substr(4, 4) ) <= parseInt(year) );
		}).fadeIn(fadetime).removeClass('hidden');

		//move the runner and prophecy block
		if (!rpos)
			rpos = $('#y'+year).position().left;

		jTweener.removeTween(hookUp.runner);
		$t(hookUp.runner).tween({
			left: rpos + hookUp.rOffset
		});

		var pOffset = (year >= 2020) ? rpos - 180 : rpos - 50;

		jTweener.removeTween(hookUp.prophecy);
		$t(hookUp.prophecy).tween({
			left: pOffset
		}, 'normal');

		//update prophecy
		var ptext = ydata.html();
		if (ptext)
		{
			var pholder = hookUp.prophecy.children('p');
			if( !hookUp.prophecy.is(':visible') || hookUp.prophecy.is(':animated') || year == hookUp.year )
			{
				pholder.html(ptext);
				hookUp.prophecy.fadeIn('fast', function(){
					if(jQuery.browser.msie) this.style.removeAttribute('filter'); //restore ClearType
				});
			}
			else
			{
				pholder.fadeOut('fast', function(){pholder.html(ptext)});
				pholder.fadeIn('fast', function(){
					if(jQuery.browser.msie) this.style.removeAttribute('filter');
				});
			}
		}
		else
			hookUp.prophecy.fadeOut('normal');

		hookUp.year = year;
}

//get the closest year from where the runner is
tBrowser.snap = function(hookUp)
{
	var pos = hookUp.runner.position().left + hookUp.runner.width()/2;
	
	//find the closest year by position
	var years = $(hookUp.timescale + ".wrapper .year");
	
	var proxyIndex = 0;
	var minOffset = 0;
	
	years.each(function(index){
		var offset = Math.abs(pos - $(years[index]).position().left);
		if (index == 0)
		{
			minOffset = Math.abs(pos - $(years[index]).position().left);
		}
		else
		{
			if (offset < minOffset)
			{
				minOffset = offset;
				proxyIndex = index;
			}
		}
	});
	
	//now that we have the index, convert it to year
	var year = $(years[proxyIndex]);
	
	while (!year.attr('id')) //if we are on the edge, go back one year
	{
		proxyIndex--;
		year = $(years[proxyIndex]);
	}

	tBrowser.select($(year).attr('id').substr(1,4), hookUp);
}
