/**
 * @modified		$Date: 2011-11-15 17:27:20 +0000 (Tue, 15 Nov 2011) $
 * @by				$Author: PXLRic $
 * @revision		$Revision: 21 $
 * @url				$HeadURL: https://subversion.assembla.com/svn/bw-bas-mooarc/trunk/assets/js/core.js $
 *
 * Description:
 *
 */

/*
(function(window, undefined) {

	// Prepare
	var History = window.History; // Note: We are using a capital H instead of a lower h
	if (!History.enabled) {
		return false;
	}

	// Bind to StateChange Event
	History.Adapter.bind(window, 'statechange', function() {
		var State = History.getState();
		//History.log(State.data, State.title, State.url);
		// load this page
		loadPage(State.url, State.title);
	});

})(window);*/

var isiPad = navigator.userAgent.match(/iPad/i) != null;

if (Modernizr.history) {
	window.addEventListener("popstate", function(e) {
		if (window.history.state) {
			loadPage(location.href, window.history.state.title, false); // firefox and corrext browsers
		} else {
			loadPage(location.href, '', false); // chrome etc
		}
	});

}

$(document).ready(function() {

	// full screen cycle
	$('#slides').pxlFullScreen().pxlCycle({
		speed: 6000,
		controls: $('#slidenav')
	});

	$('#nav-about').click(function(event) {
		if (!$('#shelf').hasClass('open')) {
			openShelf('about');
		} else {
			swapMenu('about');
		}

		return false;
	});

	$('#nav-contact').click(function(event) {
		if (!$('#shelf').hasClass('open')) {
			openShelf('contact');
		} else {
			swapMenu('contact');
		}

		return false;
	});

	$('#nav-projects').click(function() {
		if (!$('#shelf').hasClass('open')) {
			openShelf('projects');
		} else {
			swapMenu('projects');
		}
		return false;
	});

	$('#nav-contact').click(function() {
		var $this = $(this);
	/*	History.pushState({
			state: $this.attr('href')
		}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
		window.location = $this.attr('href');*/

		if (Modernizr.history) {
			history.pushState({
				title: $this.text()
			}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
			loadPage($this.attr('href'), $this.text(), false);
			return false;
		} else {
			return true;
		}
	});
/*
	$('#nav-news').click(function() {
		var $this = $(this);
	/*	History.pushState({
			state: $this.attr('href')
		}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
		window.location = $this.attr('href');*/

	/*	if (Modernizr.history) {
			history.replaceState({
				title: $this.text()
			}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
			return true;
		} else {
			return true;
		}
//alert('yo');


		//return false;

	});*/

	initProjectsMenu();

	// load homepage or current page
	var pathParts = window.location.pathname.split('/');
	var pageSlug = pathParts[pathParts.length - 1];
	if (pageSlug == '') { // no page set so default to home
		pageSlug = 'home';
	}

	// change the page state - randomise it so it loads correctly on a refresh
	// TODO detect if user clicked link for the active page
	// TODO see why this fires on every page load
	/*History.pushState({
		state: pageSlug+'-'+Math.random()
	}, 'BAS Mooarc', pageSlug);*/

	if (Modernizr.history) {
		history.pushState({
			title: 'BAS Mooarc'
		}, 'BAS Mooarc'+'-'+Math.random(), pageSlug);
		loadPage(pageSlug, 'BAS Mooarc', true);
		return false;
	} else {
		initPage();
		//loadPage(pageSlug, 'BAS Mooarc');
	}

	// loadPage('http://192.168.1.20/basmooarc/design-agency', 'ff'); // TODO non-history


});

$(window).resize(function() {
	setArticleHeight();
});

function setArticleHeight() {
	if (isiPad) {
		if ($('#slides')[0]) { // slides
			$('article').height(458);
		} else {
			$('article').height($('article').height());
		}

	} else {
		$('article').height($(window).height() - 228);
	}

}

function initPage() {
	setArticleHeight();

	// load article links ajax style - check for external classes
	if (Modernizr.history) {
		$('article a').not('[target="_blank"]').one('click', function() {
			$this = $(this);

			history.pushState({
				title: $this.text()
			}, '', $this.attr('href'));
			loadPage($this.attr('href'), '', false);
			return false;
		});

	}


	/*
	 Get all images for this project and put them in an array to preload them
	 we seperate them into two arrays:
	 requiredImages: the first two images - these must be preloaded to start the slide show - we reveal the images
	 they have loaded
	 otherImages: any other images we need to load
	 * */
	if ($('#slides')[0]) {
		var requiredImages = [];
		var otherImages = []

		// move the project description off the page
		// really we hide the description as people may resize their window meaning
		// we'd need to re-position again.
		// when the page needs to be viewed we position then animate it
		$('#project').hide();


		$('#slides img').each(function(index, value) {
			if (index < 2) { // we only need two images before we can show the user
				requiredImages.push($(value).attr('src'));
			} else {
				otherImages.push($(value).attr('src'));
			}
		});

		// preload the images
		$({}).imageLoader({
			images: requiredImages,
			async: false,
			allcomplete: function (e, ui) {
				hideThrobber();
				$('#showdetails').one('click', function() {
					showProjectDetails();
				});
				// make the images cycle
				$('#slides').pxlFullScreen().pxlCycle({
					speed: 6000,
					controls: $('#slidenav')
				});
				// load the rest of the images
				$({}).imageLoader({
					images: otherImages,
					async: true
				});
			}
		});
	} else {
		hideThrobber();
	}

	/* Hovering over team page */
	if ($('#theteam')[0]) {
		$('#theteam area').hover(function() {
			$('#menu-'+$(this).attr('id')).addClass('active');
		}, function() {
			$('#menu-'+$(this).attr('id')).removeClass('active');
		});
	}

	// do we have people?
	if ($('#teammenu')[0]) {
		$('#teammenu > ul > li > a, #theteam > area').click(function() {
			$this = $(this);
			loadProfile($this.attr('href'));
			return false;
		});
	}

	// do we have sub pages?
	if ($('#tertiary2')[0]) {
		$('#tertiary2 > ul > li > a').click(function() {
			$this = $(this);
			/*History.pushState({
				state: $this.attr('href')
			}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
			window.location = $this.attr('href');*/
			if (Modernizr.history) {
				history.pushState({
					title: $this.text()
				}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
				loadPage($this.attr('href'), $this.text(), false);
				return false;
			} else {
				return true;
			}
		});
	}


	if ($('#offices')[0]) {
		initOfficesMap();
	}

}

function initOfficesMap() {
	$('.directions').hide();

	var maps = new Array();
	maps['bas-mooarc-exeter'] = new google.maps.LatLng(50.725562, -3.529435);
	maps['bas-mooarc-guernsey'] = new google.maps.LatLng(49.458752, -2.544002);
	maps['mooarc-london'] = new google.maps.LatLng(51.562198, -0.100788);

	var mapOptions = {
		zoom: 16,
		maxZoom: 16,
		minZoom: 16,
		center: null,
		mapTypeControl: false,
	    navigationControl: true,
	    panControl: false,
	    scrollwheel: false,
	    zoomControl: false,
		streetViewControl: false,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		draggable: false
	};

	// get all map holders
	$('.mapholder').each(function(key, value) {
		var thisID = $(value).attr('id');
		var mapFocus = maps[thisID];
		mapOptions.center = mapFocus;

		var map = new google.maps.Map(document.getElementById(thisID), mapOptions);

		var plot = new google.maps.Marker({
			position: mapFocus,
			map: map
		});

		plot.setClickable(false);

		$(this).click(function() {
			if ($(this).hasClass('open')) {
				$(this).animate({
					height: '163px',
					width: '163px'
				}, function() {
					google.maps.event.trigger(map, 'resize'); // set new map size in Google Maps
					map.panTo(mapFocus);
				}).removeClass('open').next().children('.directions').slideUp();
			} else {
				$(this).animate({
					height: '350px',
					width: '350px'
				}, function() {
					google.maps.event.trigger(map, 'resize'); // set new map size in Google Maps
					map.panTo(mapFocus);
				}).addClass('open').next().children('.directions').slideDown();
			}

		});
	});
}

function showSlideControls() {
	if ($('#slidenav')[0]) {
		$('#slidenav').fadeIn(170);
	}
	if ($('#slideprev')[0]) {
		$('#slideprev, #slidepause, #slidenext').fadeTo(170, 1);
	}
}

function hideSlideControls() {
	if ($('#slidenav')[0]) {
		$('#slidenav').fadeOut(100);
	}
	if ($('#slideprev')[0]) {
		$('#slideprev, #slidepause, #slidenext').fadeTo(170, 0);
	}
}

function showDetailsControl() {
	if ($('#projectcontrols')[0]) {
		$('#projectcontrols').fadeTo(170, 1);
	}
}

function hideDetailsControl() {
	if ($('#projectcontrols')[0]) {
		$('#projectcontrols').fadeTo(100, 0);
	}
}

function openShelf(section) {
	// do we have an active menu?
	if ($('#secondary > .active')[0]) {
		// hide it ready for the new one
		$('#secondary > .active').removeClass().hide();
	}

	// hide slideshow controls if we have them
	hideSlideControls();
	hideDetailsControl();

	// show the menu and make it active
	$('#'+section).css({ // we need to force this as hardware acceleration breaks showing items that are not displayed
		display: 'block',
		opacity: 1
	}).addClass('active');
	$('#shelf').animate({
		top: 340
	}, 500).addClass('open');

	// make the entire content area close the menu when pressed
	$('#content').one('click', function() {
		closeShelf();
	});
}

function closeShelf() {
	$('#shelf').animate({
		top: 0
	}, 500, function() {
		// show slideshow controls if we have them
		showSlideControls();
		showDetailsControl();
	}).removeClass('open');

	$('#content').unbind('click'); // remove close event on page
}

function initProjectsMenu() {
	$('#projects, #about').hide();

	// every sub menu after the first
	$('#projects > li:nth-child(n+2) > ul').hide();

	// set first menu active
	$('#projects > li:first-child').addClass('active');

	// make top menus clickable
	$('#projects > li').click(function() {
		var nextMenu = $(this);
		var nextURL = nextMenu.children('a').attr('href');

		if (nextURL == 'news') {
			//console.log('hello');
		} else {
			// only do actions if we've not clicked the active menu
			if (!nextMenu.hasClass('active')) {
				// remove it's active state and fade out kids
				$('#projects > .active').removeClass('active').children('ul').fadeTo(200, 0, function() {
					$(this).hide();
					// set new menu active and show kids
					nextMenu.find('ul').fadeIn(200);
				});
			}
			nextMenu.addClass('active');
			// stop link firing
			if (Modernizr.history) {
				return false;
			}
		}


	});

	// make project menus clickable
	$('#projects > li > ul > li > ul > li > a, #projects > li > ul > li > a').click(function() {
		// remove active toggle
		$('#about > li > a.active').removeClass('active');
		$('#projects > li > ul a.active').removeClass('active'); // forget active menu
		var $this = $(this);
		$this.addClass('active'); // flag this active

		if (Modernizr.history) {
			history.pushState({
				title: $this.text()
			}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
			loadPage($this.attr('href'), $this.text(), true);
			return false;
		} else {
			return true;
		}

	});

	// other shelves
	$('#about > li > a').click(function() {
		// remove active toggle
		$('#about > li > a.active').removeClass('active');
		$('#projects > li > ul a.active').removeClass('active'); // forget active menu
		var $this = $(this);
		$this.addClass('active'); // flag this active

		if (Modernizr.history) {
			history.pushState({
				title: $this.text()
			}, $this.text() + ' : BAS Mooarc', $this.attr('href'));
			loadPage($this.attr('href'), $this.text(), false);
			return false;
		} else {
			return true;
		}

	});
}

function swapMenu(id) {
	// remove currently active menu
	$('#secondary > .active').removeClass('active').fadeOut(200, function() {
		$('#'+id).addClass('active').fadeIn(200);
	});

	return false;
}

function loadPage(url, title, throbber) {
	var title = title.replace(' : BAS Mooarc', '');
	// remove any active cycles from other pages. this could probably be placed better in the code
	if (runCycle) {
		clearInterval(runCycle);
	}

	if (throbber) {
		showThrobber('Loading ' + title);
	}
	closeShelf();
	$.ajax(url, {
		error: function(jqXHR, textStatus, errorThrown) {
			/*console.log('error');
			console.log(jqXHR);
			console.log(textStatus);
			console.log(errorThrown);*/
		//	return false;

		},
		success: function(data, textStatus, jqXHR) {
			if (textStatus == 'success') {
				// place the data
				$('#content').html(data);
				$('#content').hide().fadeIn(500);
				initPage();
			}

		}
	});
}

function showProjectDetails() {
	// pause the slide show
	// this is required as hardware acceleration doesn't run on hidden elements meaning the images and controls go
	// out-of-sync!
	clearInterval(runCycle);

	$('#project').show().css({
		left: $('#project').width()
	}).animate({
		left: 0
	}, 600, function() {
		$('#showdetails').one('click', function() {
			hideProjectDetails();
		}).addClass('open');
	});

	hideSlideControls();
}

function hideProjectDetails() {
	$('#slides').pxlCycle('play');
	$('#project').animate({
		left: $('#project').width()+'px'
	}, 600, function() {
		$(this).hide();
		$('#showdetails').one('click', function() {
			showProjectDetails();
		}).removeClass('open');
		showSlideControls();
	});
}

// load profiles
function loadProfile(slug) {
	$.ajax('templates/content/profile.php', {
		data: {
			slug: slug
		},
		success: function(data, textStatus, jqXHR) {
			if (textStatus == 'success') {
				$('#people').html(data).children().hide().fadeIn(500);
			}
		}
	});
}

function showThrobber(message) {
	$('#throbbertitle').text(message);
	$('#throbber').fadeIn(100);
}

function hideThrobber() {
	$('#throbber').fadeOut(function() {
		$('#throbbertitle').text('');
	});
}

/*
 * Detect if an image only fills half the screen
 */


function imageIsHalf(imageURL) {
	if (Modernizr.canvas) {
		// make an empty canvas
		var canvas = document.createElement('canvas');
		canvas.width = 1788;
		canvas.height = 1118;
		var context = canvas.getContext('2d');

		// get our image

		var image = new Image();

		// test image has loaded
		var loaded = image.onload = function() {
			// dimensions for the test area
			var x = 900;
			var y = 100;
			var width = 20;
			var height = 1;
			// add our image to the canvas
			context.drawImage(image, 0, 0);

			// #### enable this to see where the test area is reading from
			// context.fillRect(x, y, width, height);

			// get image data
			var imageData = context.getImageData(x, y, width, height);

			// get the RGB of some pixels
			// white = 765 so pixels is 1530
			var firstPixel = imageData.data[0] + imageData.data[1] + imageData.data[2];
			var secondPixel = imageData.data[76] + imageData.data[77] + imageData.data[78];
			if ((firstPixel + secondPixel) == 1530) {
				imageIsHalfResult(true);
			} else {
				imageIsHalfResult(false);
			}

		};
		image.src = imageURL;
		delete image;
		delete canvas;
	}
}

function imageIsHalfResult(bool) {
	// test to see if the next logo is differnet to the current one, if so fade it
	var currentLogo = $('#logo').attr('src');
	if (bool) {
		var nextLogo = 'images/logo-bas-mooarc-colour.png';
	} else {
		var nextLogo = 'images/logo-bas-mooarc.png';
	}

	if (currentLogo != nextLogo) {
		$('#logo').fadeOut(1, function() {
			$(this).attr('src', nextLogo).fadeIn(100);
		});
	}
}

/*
 * Full screen images
 */

// this function creates full screen images that scale with the browser
(function($){
	var screenHeight = 0;
	var screenWidth = 0;

	$.fn.pxlFullScreen = function(options) {
		// default settings
		var settings = {
			'height': 1200,
			'width': 1920
		}

		var selector = this;

		return this.each(function() {
			// override default with user options
			if (options) {
				$.extend(settings, options);
			}

			// attach event to window resizing
			$(window).resize(function() {;
				setImageSize(selector, settings);
			});
			// fire this event when first run
			setImageSize(selector, settings);
		});
	};

	// works out the full screen size
	function getScreenSize() {
		screenHeight = $(window).height();
		screenWidth  = $(window).width();
	}

	// works out the size of the image
	function setImageSize(selector, settings) {
		getScreenSize();
		// work out which ratio is best: screen height to image height or screen width to image width
		// images are always 1920 x 1200
		var heightScale = screenHeight / settings.height;
		var widthScale = screenWidth / settings.width;
		var left = 0;
		var top = 0;

		if (heightScale > widthScale) {
			// the window to image ratio means the width has to be expanded to fit as we're 100% tall
			imageWidth = Math.ceil(settings.width * heightScale);
			imageHeight = screenHeight;

			// centre the image horizontally
			left = Math.ceil((imageWidth - screenWidth) / 2);
			top = 0;

		} else {
			// the window to image ratio means the height has to be expanded to fit as we're 100% wide
			imageHeight = Math.ceil(settings.height * widthScale);
			imageWidth = screenWidth;

			// centre the image horizontally
			top = Math.ceil((imageHeight - screenHeight) / 2);
			left = 0;
		}

		// scale the images to fill the screen

		$(selector).children('img').css({
			left: -left,
			top: -top,
			height: imageHeight,
			width: imageWidth
		});
	}

})(jQuery);

// pxl cycle plugin
// this is used to cycle images in the most basic way
(function($){
	// store this var here as it's needed throughout the plugin for the slide show timer
	window.runCycle = null; // this needs to be at global level as it's passed between pages

	// default settings
	var settings = {
		'speed': 5000,
		'fadeSpeed': 500,
		'controls': null
	}

	// public methods. init is the constructor
	var methods = {
		init: function(options) {
			return this.each(function() {
				// override default with user options
				if (options) {
					$.extend(settings, options);
				}

				// get all the slides
				var slides = $(this).children();
				// hide them
				slides.hide();

				// make slide navigation
				if (settings.controls) {
					var controlsCode = '';
					// make a control for each slide
					for (var i = 0; i < slides.length; i++) {
						if (i == 0) {
							controlsCode += '<span id="pxlcycle-show-'+i+'" class="active">&nbsp;</span>';
						} else {
							controlsCode += '<span id="pxlcycle-show-'+i+'">&nbsp;</span>';
						}
					};
					// them to the page
					settings.controls.html(controlsCode);
					// attach click event
					$(settings.controls).children().click(function() {
						// cancel the slide show timer as the user might have clicked just before a transition
						//clearInterval(runCycle);
						pauseSlides(slides, settings);

						// get the id of clicked item and work out what slide id to show
						var controlID = $(this).attr('id');
						var slideID = controlID.match(/[0-9]+/, controlID)[0]; // find the id

						// test to make sure this is not the already active slide
						if (!$(slides[slideID]).hasClass('active')) {
							changeSlide(slides, slideID, settings);
						}
					});

					if (slides.length > 1) {
						// pause, prev, next
						$('#slidepause').click(function() {
							$this = $(this);
							if ($this.hasClass('paused')) {
								playSlides(slides, settings);
								$this.removeClass('paused');
							} else {
								pauseSlides(slides, settings);
								$this.addClass('paused');
							}

						});

						$('#slideprev').click(function() {
							var controlID = $('#slidenav > .active').prev().attr('id');
							if (controlID) {
								var slideID = controlID.match(/[0-9]+/, controlID)[0]; // find the id
							} else {
								var slideID = $('#slidenav > span:last').attr('id').match(/[0-9]+/, controlID)[0];
								//var slideID = controlID.match(/[0-9]/, controlID)[0]; // find the id
							}
							changeSlide(slides, slideID, settings);
						});

						$('#slidenext').click(function() {
							var controlID = $('#slidenav > .active').next().attr('id');
							if (controlID) {
								var slideID = controlID.match(/[0-9]+/, controlID)[0]; // find the id
							} else {
								var slideID = $('#slidenav > span:first').attr('id').match(/[0-9]+/, controlID)[0];
								//var slideID = controlID.match(/[0-9]/, controlID)[0]; // find the id
							}
							changeSlide(slides, slideID, settings);
						});
					} else {
						$('#slidepause, #slideprev, #slidenext').remove(); // we don't need these for only one image
					}



				}

				playSlides(slides, settings);

				// show first slide
				$(slides[0]).fadeTo(1, settings.fadeSpeed).addClass('active');
			});
		},
		// resumes playback
		play: function() {
			// get all the slides
			var slides = $(this).children();
			playSlides(slides, settings);
		}
	}

	$.fn.pxlCycle = function(method) {

		// if a method as the given argument exists
		if (methods[method]) {
			// call the respective method
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		// if an object is given as method OR nothing is given as argument
		} else if (typeof method === 'object' || !method) {
			// call the initialization method
			return methods.init.apply(this, arguments);
			// otherwise
		} else {
			// trigger an error
			$.error( 'Method "' +  method + '" does not exist in pluginName plugin!');
		}
	};

	// starts the slide show
	function playSlides(slides, settings) {
		// test if the first slide is half a screen
		var currentSlide = $(slides).filter('.active');
		if ($(currentSlide).attr('src')) {
			var imageURL = $(currentSlide).attr('src')
		} else {
			var imageURL = $(slides[0]).attr('src');
		}

		imageIsHalf(imageURL);

		// start the slide show loop
		runCycle = setInterval(function() {
			// are we at the end of the slide array? if so go to the start
			changeSlide(slides, null, settings);
		}, settings.speed);
	}

	// starts the slide show
	function pauseSlides(slides, settings) {
		clearInterval(runCycle);
		// get active slide
		var currentSlide = $(slides).filter('.active');
		var imageURL = $(currentSlide).attr('src');
		imageIsHalf(imageURL);
		/*runCycle = setInterval(function() {
			// are we at the end of the slide array? if so go to the start
			changeSlide(slides, null, settings);
		}, settings.speed);*/
	}

	// slide transitions
	function changeSlide(slides, slideID, settings) {
		// we are looping so the previous slide is really the last one in the array
		var currentSlide = $(slides).filter('.active');

		// are we going to a requested slide?
		if (slideID) {
			pauseSlides(slides, settings)
			$('#slidepause').addClass('paused');
			var nextSlide = $(slides[slideID]);
			var nextControl = $('#pxlcycle-show-'+slideID);
		} else { // find next slide and control
			if (currentSlide.next()[0]) {
				var nextControl = $('#slidenav > .active').next();
				var nextSlide = currentSlide.next();
			} else { // looping show
				var nextControl = $('#pxlcycle-show-0');
				var nextSlide = $(slides[0]);
			}
		}

		// change highlighting of controls
		$('#slidenav > .active').removeClass('active');
		nextControl.addClass('active');

		// set slide z-index to be higher than the last one in the group so it can fade in
		nextSlide.css({
			'z-index': slides.length
		});

		// fade the next slide in
		nextSlide.fadeIn(settings.fadeSpeed, function() {
			// hide previous slide
			$(currentSlide).hide().removeClass('active');

			// flag the active slide
			$(this).addClass('active');

			// now reset the z-index so the next slide will appear above it
			nextSlide.css({
				'z-index': 0
			});

		});

		var imageURL = $(nextSlide).attr('src');
		imageIsHalf(imageURL);

	}

})(jQuery);
