var HomepageCarousel = new function () {
	
	this.$imageCarousel;
	this.$infoCarousel;
	this.$navigation;
	
	var _numItems;
	var _currentIndex;
	var _interval;
	
	var self = this;
	
	this.init = function ($holder) {
		if(!$holder.length) return;
		
		self.$imageCarousel = $holder.find('.image .scrollable');
		self.$infoCarousel = $holder.find('.info .scrollable');
		self.$navigation = $holder.find('.navigation a');
		
		self.setupWidth();
				
		if(_numItems > 1) {
			self.setupCarousels();
			self.$navigation.click(self.onNavigationClicked);	
		}
		else {
			var $parent = self.$imageCarousel.parent();
			$parent.find('a.prev').remove();
			$parent.find('a.next').remove();
		}
	}
	
	this.setupWidth = function () {
		// auto sets the item container's width
		// rather than having to randomly hardcode a css value
		var $ul;
		
		$ul = self.$imageCarousel.find('ul');
		$li = $ul.children('li');
		$ul.width($li.length * $li.outerWidth(true));
		
		_numItems = $li.length;
		
		$ul = self.$infoCarousel.find('ul');
		$li = $ul.children('li');
		$ul.width($li.length * $li.outerWidth(true));
	}
	
	this.setupCarousels = function () {
		// If no previous or next buttons are defined for the info carousel
		// then it will find those for the image carousel and use those automatically
		// HOWEVER, this will break the sync if iPad swipes are used to navigate instead
		// so I created a hidden set for info and will sync manually:
		
		// scrollable's autoscroll seems a bit shit, need to make our own
		
		_currentIndex = 0;
		_paused = false;
		
		self.$imageCarousel.scrollable({
			easing:"easeInOutQuart",
			speed:600,
			onBeforeSeek:self.onBeforeSeek,
			onSeek:self.onSeek
		})
		
		self.$infoCarousel.scrollable({
			easing:"easeInOutQuart",
			speed:600,
			touch:false
		})
		
		// start autoscroll
		self.startAutoScroll(null);
		
		// pause if mouseover, restart if mouseout
		self.$imageCarousel.parent().bind('mouseover', self.stopAutoScroll).bind('mouseleave', self.startAutoScroll);
		self.$infoCarousel.parent().bind('mouseover', self.stopAutoScroll).bind('mouseleave', self.startAutoScroll);
		self.$navigation.parent().bind('mouseover', self.stopAutoScroll).bind('mouseleave', self.startAutoScroll);
	}
	
	this.onBeforeSeek = function (e, index) {
		self.$infoCarousel.data('scrollable').seekTo(index);
	}
	
	this.onSeek = function (e, index) {
		_currentIndex = index;
	}
	
	this.startAutoScroll = function (e) {
		if(_interval) return;
		
		_interval = setInterval(function () {
			self.autoScroll();
		}, 8000);
	}
	
	this.stopAutoScroll = function (e) {
		if(_interval) {			
			clearInterval(_interval);
			_interval = null;
		}
	}
	
	this.autoScroll = function () {
		var index = (_currentIndex + 1) % _numItems;
		self.seekTo(index);
	}
	
	this.onNavigationClicked = function (e) {
		e.preventDefault();
		self.seekTo(self.$navigation.index($(this)))
	}
	
	this.seekTo = function(index) {
		self.$imageCarousel.data('scrollable').seekTo(index);
	}
}

var GenericCarousel = new function () {
	
	this.$carousel;
	
	var _numItems;
	
	var self = this;
	
	this.init = function ($holder) {
		if(!$holder.length) return;
		
		self.$carousel = $holder.find('.scrollable');
		self.setupWidth();
		
		if(_numItems > 1) {
			self.setupCarousel();	
		}
		else {
			var $parent = self.$carousel.parent();
			$parent.find('a.prev').remove();
			$parent.find('a.next').remove();
		}
	}
	
	this.setupWidth = function () {
		var $ul = self.$carousel.find('ul');
		var $li = $ul.children('li');
		$ul.width($li.length * $li.outerWidth(true));
		
		_numItems = $li.length;
	}
	
	this.setupCarousel = function () {
		self.$carousel.scrollable({
			easing:"easeInOutQuart",
			speed:600
		});
	}
}

var ServiceLinks = new function () {
	
	var self = this;
	
	this.init = function () {		
		$('a.quickLink').click(self.onLinkClicked);
	}
	
	this.onLinkClicked = function (e) {
		e.preventDefault();
		// IE7 conveniently adds the URL to a hash link, extract:
		var href = $(this).attr('href');
		var hashIndex = href.indexOf('#');
		href = href.substring(hashIndex);
		
		var maxScrollTop = $(document).height() - $(window).height();
		var target = (href.length > 2) ? $(href).offset().top : 0;
		target = (target < maxScrollTop) ? target : maxScrollTop;
		$('html,body').animate({scrollTop:target}, 600, "easeInOutQuart");
	}
}

var Archive = new function () {
	
	this.$dropdowns;
	
	this.$clients;
	this.$services;
		
	this.$numResults;
	this.$pageNum;
	this.$numPages;
	
	this.numResults;
	this.pageNum;
	this.numPages;
	
	this.$previous;
	this.$next;
	
	this.$items;
	
	this.itemsCleared = 0;
	this.itemsUpdated = 0;
	this.itemsToUpdate;
	
	var self = this;
	
	this.init = function ($holder) {
		if(!$holder.length) {
			return;
		}
		
		self.$dropdowns = $holder.find('#archiveMenu');
		self.$clients = self.$dropdowns.find('select.clients');
		self.$services = self.$dropdowns.find('select.services');
		self.$numResults = $holder.find('#numResults');
		self.$pageNum = $holder.find('#pageNum');
		self.$numPages = $holder.find('#numPages');
		self.$previous = $holder.find('.pagination .previous');
		self.$next = $holder.find('.pagination .next');
		self.$items = $holder.find('li.item');
		
		self.numResults = parseInt(self.$numResults.text());
		self.pageNum = parseInt(self.$pageNum.text());
		self.numPages = parseInt(self.$numPages.text());
		
		$(window).bind('hashchange', self.clearItems);
		
		$holder.find('select.selectBox').selectBox().selectBox('disable').change(self.onSelectBoxChanged);
		
		$(window).trigger('hashchange');
	}
	
	this.enablePageLinkListeners = function () {	
		if(self.pageNum > 1) {
			self.$previous.bind('click', self.onPreviousClicked).removeClass('disabled');
		}
		
		if(self.pageNum < self.numPages) {
			self.$next.bind('click', self.onNextClicked).removeClass('disabled');	
		}
	}
	
	this.disablePageLinkListeners = function () {
		self.$previous.unbind('click').addClass('disabled');
		self.$next.unbind('click').addClass('disabled');
	}
	
	this.onPreviousClicked = function (e) {
		e.preventDefault();
				
		if(self.pageNum > 1) {
			--self.pageNum;
			self.setHash();
		}
	}
	
	this.onNextClicked = function (e) {
		e.preventDefault();
		
		if(self.pageNum < self.numPages) {
			++self.pageNum;
			self.setHash();
		}
	}
	
	this.onSelectBoxChanged = function (e) {
		self.pageNum = 1;
		self.setHash();
	}
	
	this.setPageNum = function (pageNum) {
		self.pageNum = pageNum;
		self.$pageNum.text(pageNum);
	}
	
	this.setNumPages = function (numPages) {
		self.numPages = numPages;
		self.$numPages.text(numPages);
	}
	
	this.setNumResults = function (numResults) {
		self.numResults = numResults;
		self.$numResults.text(numResults);
	}
	
	this.setSelectOptions = function (className, data, selectedValue) {
		self.$dropdowns.find('select.' + className).selectBox('options', data).selectBox('value', selectedValue);
	}
	
	this.setHash = function () {
		var params = {
			'client_id': self.$clients.val(),
			'service_id': self.$services.val(),
			'page': self.pageNum
		}
		
		window.location.href = $.param.fragment(window.location.href, params);
	}
	
	this.doAjaxCall = function () {
		var params = $.deparam.fragment();
		
		$.post('/archive/ajax', params, function(data) {		
			data = JSON.parse(data);
			
			self.setPageNum(data.pageNum);
			self.setNumPages(data.numPages);
			self.setNumResults(data.numResults);
			
			self.setSelectOptions('clients', data.clients, params.client_id);
			self.setSelectOptions('services', data.services, params.service_id);
						
			self.updateItems(data.items);
		});
	}
	
	// clear items triggers an animation which fires the ajax call on complete:
	
	this.clearItems = function (e) {
		self.itemsCleared = 0;
		self.$clients.selectBox('disable');
		self.$services.selectBox('disable');
		self.disablePageLinkListeners();
		
		var $item;
		
		self.$items.each(function (i) {
			$item = $(this);
			self.clearItem($item);
		});
	}
	
	this.clearItem = function ($item) {
		self.clearItemImage($item.find('img'));
		self.updateItemTitle($item.find('h3'), 'Loading...');
		self.updateItemLinks($item.find('a.thumbframe'), $item.find('a.archive_link'), '', '');
		self.updateItemText($item.find('p'), '', '');
	}
	
	this.clearItemImage = function ($img) {
		// if it's the first time the page has loaded, no need to animate
		if($img.hasClass('invisible')) {
			self.onClearImageComplete();
		}
		else {
			$img.animate({opacity:0}, 750, self.onClearImageComplete);	
		}
	}
	
	this.onClearImageComplete = function () {		
		$(this).addClass('invisible').attr('src', '');
		
		if(++self.itemsCleared == self.$items.length) {
			self.doAjaxCall();	
		}
	}
	
	this.updateItems = function (items) {
		var $item;
		var data;
		
		self.itemsUpdated = 0;
		self.itemsToUpdate = items.length;
		
		self.$items.each(function (i) {
			$item = $(this);
			data = items[i];
			self.updateItem($item, data);
		});
	}
	
	this.updateItem = function ($item, data) {
		if(data == undefined) {
			$item.addClass('hide');
			return;
		}
		else {
			$item.removeClass('hide');
		}
		
		self.updateItemImage($item.find('img'), data.thumb);
		self.updateItemTitle($item.find('h3'), data.title);
		self.updateItemLinks($item.find('a.thumbframe'), $item.find('a.archive_link'), data.link_href, data.link_text);
		self.updateItemText($item.find('p'), data.client_name, data.service_list);
	}
	
	this.updateItemTitle = function ($title, text) {
		$title.text(text);
	}
	
	this.updateItemLinks = function ($frameLink, $textLink, linkHref, linkText) {
		if(linkText.length && linkHref.length) {
			$frameLink.removeClass('disabledLink').attr('href', linkHref);
			$textLink.removeClass('invisible').attr('href', linkHref).text(linkText);
		}
		else {
			$frameLink.removeAttr('href');
			$frameLink.addClass('disabledLink');
			$textLink.addClass('invisible');
		}
	}
	
	this.updateItemText = function ($p, clientName, servicesList) {
		if(clientName.length && servicesList.length) {
			$p.removeClass('invisible');
			$p.find('.client').text(clientName);
			$p.find('.services').text(servicesList);
		}
		else {
			$p.addClass('invisible');
		}
	}
	
	this.updateItemImage = function ($img, src) {
		$img.bind('load', self.onImageLoaded).attr('src', '/uploads/images/' + src);
	}
	
	this.onImageLoaded = function (e) {
		var $img = $(e.target);
		$img.unbind('load');
		$img.css('opacity', 0).removeClass('invisible').animate({opacity:1}, 750, self.onUpdateImageComplete);
	}
	
	this.onUpdateImageComplete = function () {
		if(++self.itemsUpdated == self.itemsToUpdate) {
			self.$clients.selectBox('enable');
			self.$services.selectBox('enable');
			self.enablePageLinkListeners();	
		}
	}
}

function setupVideos() {
	$('#tjVideo').TJVideo({
		pathToNonverblaster:'/media/NonverBlaster.swf',
		autoplay:true
	});
}

function setupTableDragAndDrop() {
	$('table.dragndrop').tableDnD({
		onDragClass:"dragging",
		dragHandle:"draghandle"
	});
	
	var $draghandle = $('table.dragndrop .draghandle');
	
	$draghandle.mouseover(function (){
		$(this).addClass('active');
	});
	
	$draghandle.mouseout(function () {
		$(this).removeClass('active');
	})
}

function setupDeleteConfirm() {
	$('form .deleteSubmit').click(function (e) {
		var $delete = $(this).parents('form').find('input[name="deleteMe[]"]');
		
		// filter seems to fail if there is only one item?:
		if($delete.length > 1) {
			$delete = $delete.filter('[checked=true]');
		}
		else {
			$delete = ($delete.prop('checked') == true) ? $delete : [];
		}
		
		var len = $delete.length;
		
		if(len > 0) {
			var msg = (len > 1) ? "Are you sure you want to delete these " + len + " items?" : "Are you sure you want to delete this item?";
		
			if(!confirm(msg)) {
				e.preventDefault();
			}
		}
		else {
			e.preventDefault();
		}
	});
}

function log(msg) {
	if(window.console) {
		console.log(msg);
	}
}

function main() {
	HomepageCarousel.init($('#wrapper.index .carousel'));
	GenericCarousel.init($('.carousel:not(#wrapper.index .carousel)'));
	ServiceLinks.init();
	Archive.init($('#wrapper.archive'));
	setupTableDragAndDrop();
	setupDeleteConfirm();
	setupVideos();
}

$(main);
