jQuery(function($) {
	// constants of sorts
	var pages = {
		1: './',
		2: 'about.php',
		3: 'services.php',
		4: 'showcase.php',
		5: 'team.php',
		6: 'careers.php',
		7: 'blog.php',
		8: 'contact.php',
		9: 'terms.php'
	};
	var subs = {
		1: 'page',
		2: 'page',
		3: 'page',
		4: 'page',
		5: 'member',
		6: 'page',
		7: 'blog',
		8: 'page',
		9: 'page'
	};
	// these are worked out as (content width + content padding (40px)) - 27, fyi
	var hiderpositions = {
		1: 300,
		2: 273,
		3: 273,
		4: 273,
		5: 273,
		6: 273,
		7: 551,
		8: 273,
		9: 273
	};
	var sidebarwidth     = 105;
	var sidebarblogextra = 60;
	var scrollAmount     = 345;

	// caching goodness
	var body        = $('body');
	var side        = $('#side');
	var nav         = $('#nav');
	var main        = $('#main');
	var subnav      = $('#subnav');
	var content     = $('#content');
	var hider       = $('<div id="content-hider"><span>Click to minimise</span></div>').click(minimise);
	var overlay     = $('<div id="overlay" class="loading">');
	var backgrounds = $('<div id="backgrounds">').prependTo(main);
	var background_divs;

	var bgWidth  = 0;
	var bgHeight = 0;
	var bgRatio  = 0;

	var slideshow = {
		num : 0,
		cur: 0,
		timeout: null,
		setup: false
	};

	var overlayOn = false;


	// resizing of stuff on window resize
	$(window).resize(function () { rejig; setTimeout(rejig, 100); }); // for desktop browsers
	$(window).bind('orientationchange', function () { rejig; setTimeout(rejig, 100); }); // for mobile devices
	rejig(); // once on page load
	setTimeout(rejig, 100); // and once just after page load

	// no subnav found in dom? create one for later use
	if (!subnav.length) {
		subnav = $('<div id="subnav">').hide();

		content.before(subnav);
	}

	// make nav work
	nav.find('a').click(function() {
		this.blur();
		var page = $(this).parent().data('page');

		// blgo is special, grr!
		if (page == 7) {
			var sub = $(this).parent().data('sub');
			if (history.pushState)
				history.pushState({ page: page, sub: sub }, '', pages[page] + '?' + subs[page] + '=' + sub);
			changeSubPage(page, sub);
		} else {
			if (history.pushState)
				history.pushState({ page: page }, '', pages[page]);
			changePage(page);
		}
		return false;
	});
	$('#terms-link').click(function() {
		this.blur();
		if (history.pushState)
			history.pushState({ page: 9 }, '', pages[9]);
		changePage(9);
		return false;
	});
	subnav.delegate('a', 'click', function() {
		this.blur();
		var page = $(this).parent().data('page');
		var sub = $(this).parent().data('sub');
		if (history.pushState)
			history.pushState({ page: page, sub: sub }, '', pages[page] + '?' + subs[page] + '=' + sub);
		changeSubPage(page, sub);
		return false;
	});

	// navigation changes
	if (history.replaceState) {
		if (CC.state.sub) {
			history.replaceState({ page: CC.state.page, sub: CC.state.sub }, '', pages[CC.state.page] + '?' + subs[CC.state.page] + '=' + CC.state.sub);
		} else {
			history.replaceState({ page: CC.state.page }, '', pages[CC.state.page]);
		}
	}

	$(window).bind('popstate', function(e) {
		if (history.state.sub)
			changeSubPage(history.state.page, history.state.sub);
		else
			changePage(history.state.page);
	});

	if (overlayOn)
		body.append(overlay);

	// add content hider
	if (content.hasClass('no-subnav'))
		hider.css({ left: hiderpositions[CC.state.page] });
	else
		hider.css({ left: hiderpositions[CC.state.page] + sidebarwidth + ((CC.state.page == 7) ? sidebarblogextra : 0) });

	if (CC.state.page == 8) {
		backgrounds.css({ cursor: 'pointer' }).click(function() {
			window.open('http://maps.google.co.uk/maps?q=72+Francis+Rd,+Edgbaston,+Birmingham,+B16+8SP,+UK&hl=en&sll=53.800651,-4.064941&sspn=2.923225,8.399048&z=16');
		});
	}

	if (CC.state.page == 1) {
		hider.find('span').show();
	} else {
		hider.find('span').hide();
	}

	if (CC.state.page == 7) {
		generateBlogNav();
		addBlogMore();
	}

	main.append(hider);

	// sort out any background images
	if (typeof(ims) != 'undefined')
		setupSlideshow(ims);


	// chnage the page's content
	function changePage(pageid, noContent) {
		// first bring in the main content
		subnav.css({ left: -760 });
		content.css({ left: -655 });
		hider.css({ left: -340 });

		if (overlayOn)
			overlay.css({ display: 'block', opacity: 1 });

		// now get the content for the new page
		$.getJSON('__page.php', { page: pageid }).success(function(data) {
			CC.state.page = pageid;
			CC.state.sub  = null;
			CC.state.cat  = null;

			var hasSubnav = !!data.subnav.length;
			var isBlog = (pageid == 7 && data.categories);

			if (isBlog)
				subnav.width(153);
			else
				subnav.width(93);

			// does the new page have a subnav?
			if (hasSubnav) {
				// if so, then we need to clear the existing subnav
				subnav.empty();

				var subnavul = $('<ul id="subnav-container" class="clean">');
				$.each(data.subnav, function(idx, item) {
					var subnavitem = $('<li data-page="' + pageid + '" data-sub="' + item.id + '"' + (item.category_id ? ' data-category="' + item.category_id + '"' : '') + '>');
					if (isBlog)
						subnavitem.append('<div class="blog-date">' + item.date + '</div>');
					subnavitem.append('<a href="' + pages[pageid] + '?' + subs[pageid] + '=' + item.id + '" title="' + item.title + '">' + item.title + '</a>');
					subnavul.append(subnavitem);
					if (isBlog)
						subnavul.append('<li data-category="' + item.category_id + '"><div class="hr large"><hr></div></li>');
				});

				subnav.append(subnavul);

				if (isBlog) {
					CC.blog = {};
					CC.blog.categories = data.categories;
					generateBlogNav(subnavul);
				}

				subnav.show();
			} else {
				// if not, we need to remove any existing subnav from the DOM
				subnav.empty();
				subnav.hide();
			}

			// update main content
			content.removeClass().addClass('page-' + pageid);
			if (!hasSubnav) content.addClass('no-subnav');

			// special handling?
			if (!noContent) {
				if (pageid == 1) {
					// special wrapper div for home page + tweets
					content.html('<h1>' + data.page.title + '</h1><div class="hr large"><hr></div><div id="home-content">' + data.page.content + '</div>');

					// sort out tweets
					var tweets = $('<div id="tweets"><h1>Latest Tweets</h1><div class="hr"><hr></div></div>');

					// add tweets in
					$.each(data.tweets, function(idx, item) {
						tweets.append('<div>' + item.content + '<br><a href="https://twitter.com/' + item.user + '/statuses/' + item.id + '">' + item.date + '</a></div>');
					});

					// stick them in content
					content.append(tweets);
				} else {
					content.html('<h1>' + data.page.title + '</h1><div class="hr large"><hr></div>' + data.page.content);
				}
			}

			if (pageid == 8) {
				backgrounds.css({ cursor: 'pointer' }).click(function() {
					window.open('http://maps.google.co.uk/maps?q=72+Francis+Rd,+Edgbaston,+Birmingham,+B16+8SP,+UK&hl=en&sll=53.800651,-4.064941&sspn=2.923225,8.399048&z=16');
				});
			} else {
				backgrounds.css({ cursor: 'auto' }).unbind('click');
			}

			// change backgrounds:

			// first fade out current backgrounds
			backgrounds.css({ opacity: 0 });
			// and clear any current timeout
			clearTimeout(slideshow.timeout);

			// see what to do
			if (data.backgrounds && data.backgrounds.length) {
				// add slideshow images
				setupSlideshow(data.backgrounds);
				// show backgrounds
				backgrounds.css({ opacity: 1 });
			} else {
				// kill next button
				$('#slideshow-next').hide();
			}

			// update nav
			nav.find('li').removeClass('selected').filter('[data-page=' + pageid + ']').addClass('selected');

			// now fly out the main content and subnav
			subnav.css({ left: 0 });
			content.css({ left: (hasSubnav ? (isBlog ? 165 : 105) : 0) });

			// content hider text
			if (pageid == 1)
				hider.find('span').show();
			else
				hider.find('span').hide();

			// slide out content hider
			if (hasSubnav)
				hider.css({ left: hiderpositions[pageid] + sidebarwidth + (isBlog ? sidebarblogextra : 0) }).removeClass('shower');
			else
				hider.css({ left: hiderpositions[pageid] }).removeClass('shower');

			if (overlayOn) {
				overlay.css({ opacity: 0 });
				// this is a bit dirty! wait for CSS tween to finish (500ms should do it, should
				// be 300ms long) then hide so it doesn't steal the clicks
				setTimeout(function() {
					overlay.css({ display: 'none' });
				}, 500);
			}
		}).error(function(data) {
			displayError(data.responseText);
		});
	}

	function changeSubPage(pageid, subid) {
		// slide in main content
		content.css({ left: -655 });
		hider.css({ left: -340 });

		if (overlayOn)
			overlay.css({ display: 'block', opacity: 1 });

		if (pageid != CC.state.page)
			changePage(pageid, true);

		// ajax the new content
		$.getJSON('__page.php', { page: pageid, sub: subid }).success(function(data) {
			CC.state.page = pageid;
			CC.state.sub  = subid;
			/*CC.state.cat  = subid;*/

			// update main content
			if (pageid != 7) {
				content.html('<h1>' + data.page.title + '</h1><div class="hr large"><hr></div>' + data.page.content);

				// backgrounds:

				// first fade out current backgrounds
				backgrounds.css({ opacity: 0 });
				// and clear any current timeout
				clearTimeout(slideshow.timeout);

				// now what do we do?
				if (data.backgrounds && data.backgrounds.length) {
					// add slideshow images
					setupSlideshow(data.backgrounds);
					// show backgrounds
					backgrounds.css({ opacity: 1 });
				} else {
					// kill next button
					$('#slideshow-next').hide();
				}
			} else {
				// blog's a bit special!
				var html = ''
				html += '<h1>' + data.page.title + '</h1><div class="hr large"><hr></div>';
				if (data.page.byline.length)
					html += '<div id="blog-byline">Posted by ' + data.page.byline + '</div>';
				html += '<div class="blog-date">' + data.page.date + '</div>';
				html += '<div id="blog-content" class="clearfix">';
				html += '<div id="blog-text">' + data.page.content + '</div>';
				html += '<div id="blog-image">';
				html += '<img src="media/image/blog/' + data.page.image + '" alt="' + data.page.title + '" title="' + data.page.title + '" width="185">';
				if (data.page.image_caption.length)
					html += '<br>' + data.page.image_caption;
				html += '</div>';
				html += '</div><div class="clearfix"><ul id="blog-actions" class="clean clearfix">';
				html += '<li><a href="blog.rss"><img src="images/blog-rss.png" alt="RSS" title="View RSS feed" width="43" height="16"></a></li>';
				html += '<li><a href="http://twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></li>';
				html += '<li><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fwww.wyattinternational.com%2Fblog.php?blog=' + data.page.id + '&amp;send=false&amp;layout=button_count&amp;width=47&amp;show_faces=true&amp;action=like&amp;colorscheme=light&amp;font=arial&amp;height=21" scrolling="no" frameborder="0" style="border: none; height: 21px; overflow: hidden; width: 47px;" allowTransparency="true"></iframe></li>';
				html += '<li><script type="in/share"></script><script type="text/javascript">if (typeof(IN) != \'undefined\') IN.parse(); //else document.write(\'<scri\' + \'pt type="text/javascript" src="http://platform.linkedin.com/in.js"></scri\' + \'pt>\');</script></li>';
				html += '</ul></div>';
				content.html(html);
				addBlogMore();

				// oh yeah, we don't do background on the blog!
			}

			// update nav
			subnav.find('li').removeClass('selected').filter('[data-sub=' + subid + ']').addClass('selected');

			// slide out main content
			content.css({ left: 105 + ((CC.state.page == 7) ? sidebarblogextra : 0) });

			// content hider text
			if (pageid == 1)
				hider.find('span').show();
			else
				hider.find('span').hide();

			// slide out content hider
			hider.css({ left: hiderpositions[pageid] + sidebarwidth + ((CC.state.page == 7) ? sidebarblogextra : 0) }).removeClass('shower');

			if (overlayOn) {
				overlay.css({ opacity: 0 });
				// this is a bit dirty!
				setTimeout(function() {
					overlay.css({ display: 'none' });
				}, 500);
			}
		}).error(function(data) {
			displayError(data.responseText);
		});
	}

	function minimise() {
		if (hider.hasClass('shower')) {
			if (content.hasClass('no-subnav')) {
				content.css({ left: 0 });
				hider.css({ left: hiderpositions[CC.state.page] }).removeClass('shower');
			} else {
				content.css({ left: 105 + ((CC.state.page == 7) ? sidebarblogextra : 0) });
				hider.css({ left: hiderpositions[CC.state.page] + sidebarwidth + ((CC.state.page == 7) ? sidebarblogextra : 0) }).removeClass('shower');
			}
			hider.find('span').html('Click to minimise');
		} else {
			content.css({ left: -655 });
			if (content.hasClass('no-subnav')) {
				hider.css({ left: 11 }).addClass('shower');
			} else {
				hider.css({ left: 116 + ((CC.state.page == 7) ? sidebarblogextra : 0) }).addClass('shower');
			}
			hider.find('span').html('Click to maximise');
		}
	}

	function generateBlogNav(subnavContainer) {
		subnav.width(153);
		content.css({ left: 165 });

		var catsdiv         = $('<div id="categories">');
		var catsdropdown    = $('<ul class="clean">');
		var catsheading     = $('<div id="current-category">').html('view by category');
		if (!subnavContainer)
			var subnavContainer = $('#subnav-container');

		// add "all" link in
		catsdropdown.append(
			$('<li>')
				.html('All')
				.click(function() {
					$('#current-category').html('view by category');
					subnavContainer
						.css({ top: 0 })
						.find('li')
						.show();
				})
		);

		// now add each category in which will filter the blog posts
		$.each(CC.blog.categories, function(idx, item) {
			catsdropdown.append(
				$('<li>')
					.html(item.name)
					.click(function() {
						$('#current-category').html(item.name);
						subnavContainer
							.css({ top: 0 })
							.find('li')
							.hide()
								.filter('[data-category=' + item.id + ']')
								.show();
					})
			);
		});

		// sort out the up/down scrolling

		// add the up/down buttons and their associated actions
		subnavContainer.before(
			$('<div id="subnav-scroll-up">')
				.html('See latest posts')
				.click(function() {
					scrollUp(subnavContainer);
				})
		);
		subnavContainer.after(
			$('<div id="subnav-scroll-down">')
				.html('See more posts')
				.click(function() {
					scrollDown(subnavContainer);
				})
		);

		// now put the blogs list into a fixed-height container
		var subnavHeightContainer = $('<div id="subnav-height-container">');
		subnavContainer.wrap(subnavHeightContainer).css({
			position: 'absolute',
			top: 0
		});

		// remove the non-JS version if it exists, as we've replaced it with the JS version
		$('#blog-hide').remove();
		// add the new category stuff to the DOM
		catsdiv.append(catsheading);
		catsdiv.append(catsdropdown);
		subnav.prepend(catsdiv);
	}

	function addBlogMore() {
		$('#blog-actions').before($('<div id="blog-less">Read less</div>').click(function () { scrollUp($('#blog-text')); }));
		$('#blog-actions').before($('<div id="blog-more">Read more</div>').click(function () { scrollDown($('#blog-text')); }));
	}

	/**
	 * Technically scrolls up, but to show more content that's *down*
	 */
	function scrollDown(element) {
		element.css({
			top: Math.min(Math.max(element.parent().height() - element.height(), parseInt(element.css('top')) - element.parent().height()), 0)
		});
	}

	/**
	 * Technically scrolls down, but to show more content that's *up*
	 */
	function scrollUp(element) {
		element.css({
			top: Math.min(0, parseInt(element.css('top')) + element.parent().height())
		});
	}

	function displayError(error) {
		if (overlayOn) {
			overlay.removeClass('loading').html('<div>' + error + '</div>').css({ display: 'block', opacity: 1 });
			content.css({ left: 105 });
			setTimeout(function() {
				overlay.html('').css({ opacity: 0 });
				setTimeout(function() {
					overlay.css({ display: 'none' }).addClass('loading');
				}, 500);
			}, 5000);
		}
	}


	// reposition and resize elements as the browser size changes
	function rejig() {
		var height = Math.max(500, $(window).height());
		var width  = Math.max(950, $(window).width());

		side.height(height);
		main.height(height);
		main.width(width - 198);    // width - side = width - (179 + 19)

		// resize the backgrounds div
		bgWidth  = width - 198;
		bgHeight = height;
		bgRatio  = bgWidth / bgHeight;

		backgrounds.width(bgWidth);
		backgrounds.height(bgHeight);

		/*
		background_divs && background_divs.width(bgWidth);
		background_divs && background_divs.height(bgHeight);
		*/

		// we now will also need to resize each individual image for ie 7 and 8
		if (CC.browser == 'classic') {
			// resize images here, otherwise they won't exist
			backgrounds.find('img').each(rejigImage);
		}
	}

	function rejigImage(e) {
		// turn off chatting by overriding global console in local scope. mwa ha ha ha...
		var console = false;

		var $this = $(this);

		console && console.log('Rejigging ' + $this.attr('src'));

		// image has now loaded, resize it to browser dimensions
		if ($this.data('loaded')) {
			imW = $this.data('w');
			imH = $this.data('h');
			imR = $this.data('r');
		} else {
			if (!e) return;

			var wasVis = $this.parent().is(':visible');

			console && console.log('Visible? ' + wasVis);

			if (!wasVis)
				$this.parent().show();

			var imW = $this.width();
			var imH = $this.height();
			var imR = imW / imH;

			if (!wasVis)
				$this.parent().hide();

			$this.data({
				loaded: true,
				w: imW,
				h: imH,
				r: imR
			});
		}

		if (imW == 0 || imH == 0)
			return;

		// /*
		console && console.log('Rejigging ' + $this.attr('src'));

		console && console.log('Im: ' + imW     + ' x ' + imH      + ' (' + imR     + ')');
		console && console.log('BG: ' + bgWidth + ' x ' + bgHeight + ' (' + bgRatio + ')');
		// */

		if (bgRatio > imR) {
			$this.width(bgWidth);
			$this.height(Math.ceil(bgWidth / imR));
			console && console.log('Chosen: ' + bgWidth + ' x ' + Math.ceil(bgWidth / imR));
		} else {
			$this.width(Math.ceil(bgHeight * imR));
			$this.height(bgHeight);
			console && console.log('Chosen: ' + Math.ceil(bgHeight * imR) + ' x ' + bgHeight);
		}

		// now show it
		$this.show();
	}

	// set up the slideshow
	function setupSlideshow(ims) {
		// do we have a slideshow already set up?
		if (!slideshow.setup) {
			// first get rid of any background images on the main content area
			main.css({ backgroundImage: 'none' });
			// add slideshow next button
			slideshow.nextbutton = $('<div id="slideshow-next">').hide().click(slideshowTick).appendTo(body);
			// and say we're ready to go for next time
			slideshow.setup = true;
		}

		// get rid of/reset old slideshow bits
		backgrounds.empty();
		clearTimeout(slideshow.timeout);
		slideshow.cur = 0;

		// okay add images to slideshow
		if ((typeof(ims) != 'undefined') && ims.length) {
			// add the actual images in
			for (var i in ims)
				backgrounds.append($('<div>').css({ backgroundImage: 'url(' + ims[i] + ')', opacity: 0, display: (CC.browser == 'classic' ? 'none' : 'block') }));

			// remember the images for classic browsers!
			if (CC.browser == 'classic') {
				// add images to divs here, maybe take off the bg images too to be nice?
				backgrounds.find('div').each(function() {
					$(this).append($('<img src="' + $(this).css('backgroundImage').slice(5, -2) + '">').hide().load(rejigImage)).css({ backgroundImage: 'none' });
				});
			}

			// set the first one to visible
			background_divs = backgrounds.find('div');
			background_divs.eq(0).css({ opacity: 1, display: 'block' });

			slideshow.num = ims.length;

			if (slideshow.num == 1) {
				// hide next button if it's shown:
				slideshow.nextbutton.hide();
			} else {
				// start the slideshow up
				slideshow.timeout = setTimeout(slideshowTick, 10000);
				slideshow.nextbutton.show();
			}
		} else {
			slideshow.num = 0;
			// hide next button if it's shown:
			slideshow.nextbutton.hide();
		}
	}

	// turn slideshow to next image
	function slideshowTick() {
		clearTimeout(slideshow.timeout);

		// just make sure we don't bother if there's only one image
		if (slideshow.num == 1) return;

		// modern browsers should still keep opacity as it's a CSS3 animation!
		background_divs.eq(slideshow.cur).css({ opacity: 0, display: (CC.browser == 'classic' ? 'none' : 'block') });
		++slideshow.cur;
		if (slideshow.cur >= slideshow.num) slideshow.cur = 0;
		background_divs.eq(slideshow.cur).css({ opacity: 1, display: 'block' });

		slideshow.timeout = setTimeout(slideshowTick, 10000);
	}
});

