var Denham = {
	gridManager: null,
	cardStack: null,
	resizeTimeout: null,
	config: {
		container: 'container',
		pageSize: 20,
		insertDomId: 'insert-dom',
		cssTransClass: 'csstrans',
		closedInnerWidth: 220,
		closedOuterWidth: 222,
		closedInnerHeight: 330,
		closedOuterHeight: 332
	},

	initialize: function () {
		var container = document.id(Denham.config.container);
		container.empty(); // empty the container. Contents will be refreshed

		// Create an invisible element to convert HTML strings to DOM structures
		var insertDomElm = new Element('div', {'id': Denham.config.insertDomId})
		$$('body')[0].grab(insertDomElm);

		// When CSS animations are present use them instead of JS animations
		var tempDiv = new Element('div', {'style': '-webkit-transition: top 1s'});
		$$('body')[0].grab(tempDiv);

		var webkitStyle = tempDiv.getStyle('-webkit-transition');
		var mozStyle    = tempDiv.getStyle('-moz-transition');
		var w3cStyle    = tempDiv.getStyle('transition');
		var operaStyle  = tempDiv.getStyle('-o-transition');
		var msStyle     = tempDiv.getStyle('-ms-transition');

		var webkitTrans = (webkitStyle != '' && webkitStyle != 'null' && webkitStyle != 'undefined' && webkitStyle != undefined);
		var mozTrans    = (mozStyle != '' && mozStyle != 'null' && mozStyle != 'undefined' && w3cStyle != undefined);
		var w3cTrans    = (w3cStyle != '' && w3cStyle != 'null' && w3cStyle != 'undefined' && w3cStyle != undefined);
		var operaTrans  = (operaStyle != '' && operaStyle != 'null' && operaStyle != 'undefined' && operaStyle != undefined);
		var msTrans     = (msStyle != '' && msStyle != 'null' && msStyle != 'undefined' && msStyle != undefined);

		if (webkitTrans || mozTrans || w3cTrans || operaTrans || msTrans) {
			$$('body')[0].addClass(Denham.config.cssTransClass);
		}

		tempDiv.dispose();

		// Get an relationship between section ids and slugs
		var sections = new Hash();
		$$('#descriptions p').each(function (el) {
			if (!el.get('id')) return el;

			var idChunks = el.get('id').match(/section\-([0-9]+)\-([^"]+)/);
			sections.set(idChunks[1], idChunks[2]);
		});

		Denham.sections = sections;

		// Rewrite all the section filters to AJAX urls
		Denham.sections.each(function (sectionSlug, sectionId) {
			var sectionFilter1 = document.id('section-' + sectionId + '-filter1');

			if (sectionFilter1) {
				sectionFilter1.getElements('a').each(function (link) {
					var filter = link.getParent().get('id').split('-')[0];
					link.set('href', '/#/' + sectionSlug + '/' + filter + '/all/1/');
				});
			}

			var sectionFilter2 = document.id('section-' + sectionId + '-filter2');

			if (sectionFilter2) {
				sectionFilter2.getElements('a').each(function (link) {
					var filter = link.getParent().get('id').split('-')[0];
					link.set('href', '/#/' + sectionSlug + '/all/' + filter + '/1/');
				});
			}
		});

		$$('#submenu form')[0].addEvent('submit', function (e) {
			var query = document.id('q').get('value');
			e.stop();
			document.location.href = '/#/cards/search/1/' + query + '/';
		});

		if (Browser.Plugins.Flash.version > 0 && Browser.Plugins.Flash.build)
			new Swiff('/flash/denham-scissors.swf', {'container': 'animation', 'width': '180', 'height': '120'});

		// Determine the dimensions of the cards (used in the GridManager)
		var gridManagerOptions = {
			closedInnerWidth: Denham.config.closedInnerWidth,
			closedOuterWidth: Denham.config.closedOuterWidth,
			closedInnerHeight: Denham.config.closedInnerHeight,
			closedOuterHeight: Denham.config.closedOuterHeight
		}

		// Initialize the gridmanager
		Denham.gridManager = new GridManager(container, gridManagerOptions);

		// Create the card stack	
		Denham.cardStack = new CardStack();

		// Add an handler to the resize function to reflow the cards
		window.addEvent('resize', function () {
			window.clearTimeout(Denham.resizeTimeout);
			Denham.resizeTimeout = window.setTimeout(function () {
				Denham.gridManager.distribute.bind(Denham.gridManager)();
			}, 100);
		});

		// Function attached as eventhandler to SWFAddress events
		// Handles only external changes and initial settings.
		// Opening of a card by clicking on it is handled in the container clickhandler
		var urlChangeHandler = function (e) {
			if (e.pathNames[0] != 'card') { // Page of cards
				var options = {};
				options.pageSize = Denham.config.pageSize;

				if (e.pathNames[1] == 'search') { // Search page
					options.page     = e.pathNames[2];
					options.query    = e.pathNames[3] || '';

				} else { // Regular page
					options.section  = e.pathNames[0] || 'all';
					options.category = e.pathNames[1] || 'all';
					options.filter   = e.pathNames[2] || 'all';
					options.page     = parseInt(e.pathNames[3]) > 0 ? e.pathNames[3] : '1';
				}

				// determine the menu item
				var section;
				if (e.pathNames[0] == 'all' || e.pathNames[1] == 'search') {
					section = 'home';
				} else {
					section = e.pathNames[0];
				}

				section = section || 'home';

				var selectedLink = $$('#nav-' + section + ' a')[0];

				Denham.showPage(options);

			} else { // Detail view of a card
				if (Denham.gridManager.cards.length == 0) {
					var options = {
						section: 'all',
						category: 'all',
						filter: 'all',
						page: '1',
						pageSize: Denham.config.pageSize
					}

					Denham.showPage(options);
				}

				var selectedLink = $$('#nav-home a')[0];
				Denham.showCard('card-' + e.pathNames[1]);
			}

			Menu.show(selectedLink);
			Menu.setSelected(selectedLink);

			Denham.gridManager.distribute.delay(200, Denham.gridManager);
		}

		SWFAddress.addEventListener(SWFAddressEvent.INTERNAL_CHANGE, urlChangeHandler); //somehow needed for IE
		SWFAddress.addEventListener(SWFAddressEvent.EXTERNAL_CHANGE, urlChangeHandler);
		SWFAddress.addEventListener(SWFAddressEvent.INIT, urlChangeHandler);

		// Add a click delegate on the container. Opens the card or switches the large image in a gallery
		container.addEvent('click', function (e) {
			var target = document.id(e.target);

			//check if the close button was clicked
			if (target.hasClass('close-btn')) {
				Denham.gridManager.openCard = '';
				Denham.gridManager.distribute.delay(200, Denham.gridManager);

			// check if the thumb in an image gallery was clicked
			} else if (target.get('id') && target.get('id').match(/^small\-[0-9]+/) && target.get('tag') == 'img') {
				target.getParent('ul').getElements('li').removeClass('active');
				target.getParent().addClass('sticky');
				target.getParent().addClass('active');

				target.getParent('.mod-gallery').getElement('.view').getElements('.bigimage').addClass('hide');
				var largeId = target.get('id').replace('small-', 'large-');
				document.id(largeId).getParent().removeClass('hide');

			} else if (!target.hasClass('section-overview')) {
				var card = target.getParent('.card');
			
				if(!card.hasClass('custom-url')){
					if (card && Denham.gridManager.openCard != card.id) {
						var deeplink = card.getElement('.readmore a').get('href');
						
						if (deeplink.match(/^http/))
							deeplink = deeplink.replace('http://' + document.location.hostname, '');
	
						if ('#' + deeplink == document.location.hash) {
							Denham.showCard(card.id);
							Denham.gridManager.distribute();
						} else {
							SWFAddress.setValue(deeplink);
						}
	
					}
				}
			}
		});

		container.addEvent('mouseover', function (e) {
			var target = document.id(e.target);

			if (target.get && target.get('id') && target.get('id').match(/^small\-[0-9]+/) && target.get('tag') == 'img') {
				if (!target.getParent('.mod-gallery').getElement('.sticky')) {
					target.getParent('.mod-gallery').getElement('.view').getElements('.bigimage').addClass('hide');
					var largeId = target.get('id').replace('small-', 'large-');
					document.id(largeId).getParent().removeClass('hide');

					target.getParent('ul').getElements('li').removeClass('active');
					target.getParent('li').addClass('active');
				}
			}
		});
	},


	/**
	 * Handles the switch to another page
	 * @param {Object} options
	 */
	showPage: function (options) {
		// Compare both selections and take out the elements that are not in the new selection
		var oldSelection = Denham.gridManager.cards;
		var newSelection = Denham.cardStack.getSelection(options);

		// Remove the cards from the old selection that are not in the new selection
		oldSelection.each(function (card) {
			if (!newSelection.contains(card))
				card.removeFromDom();
		});

		// Place all the cards from the new selection in the container
		newSelection.each(function (card) {
			card.placeInDom();
		});

		// Update the gridmanager with the new cards and distribute them
		Denham.gridManager.openCard = '';
		Denham.gridManager.cards = newSelection;

		// Based on the new selection build a new pagination footer
		var footer   = document.id('footer');
		var numPages = Denham.cardStack.pagesForSelection;
		footer.empty();

		var url;
		for (var page=1; page<numPages+1; page++) {
			if (options.query) {
				url = '/#/cards/search/' + page + '/' + options.query +'/'; 
			} else {
				url = '/#/' + options.section + '/' + options.category + '/' + options.filter + '/' + page + '/';
			}

			if (page == options.page) {
				footer.grab(new Element('span', {'text': page}));
			} else {
				footer.grab(new Element('a', {'href': url, 'text': page}));
			}
		}

		// Set the page title
		if (options.query) {
			document.title = 'Search results for: "' + options.query + '"'
		} else {
			var title = 'Overview for "' + options.section + '"';

			if (options.category != 'all' && options.filter != 'all') {
				title += ' filtered on "' + options.category + '" and "' + options.filter + '"';
			} else if (options.category != 'all') {
				title += ' filtered on "' + options.category + '"';
			} else if (options.filter != 'all') {
				title += ' filtered on "' + options.filter + '"';
			}

			document.title = title;
		}
	},


	/**
	 * Opens a card
	 */
	showCard: function (cardId) {
		var cardOnPage = false;
		for (var i=0; i<Denham.gridManager.cards.length; i++) {
			if (Denham.gridManager.cards[i].id == cardId) {
				cardOnPage = true;
				break;
			}
		}

		// if the card is not on the page, make sure that it will be
		if (!cardOnPage) {
			if (!Denham.cardStack.cards[cardId]) {
				(new Request({
					url: document.location.href.split('#')[1],
					async: false,
					method: 'get',
					evalScripts: true,
					onComplete: function (responseText) {
						var insertDom = document.id(Denham.config.insertDomId);
						insertDom.innerHTML = responseText;

						var cardTitle = insertDom.getFirst().getElement('h1').get('text');
						var cardSubTitle = insertDom.getFirst().getElement('h2').get('text');

						var card = new Card(insertDom.getFirst(), document.id(Denham.config.container));
						card.title = cardTitle;
						card.subTitle = cardSubTitle;
						card.removeFromDom();
						card.placeInDom();
						Denham.cardStack.cards[cardId] = card;
					}
				})).send();
			}

			// Set the options for the surrounding cards
			var pageOptions = {
				section: 'all',
				category: 'all',
				filter: 'all',
				page: 1,
				pageSize: 20
			};

			var cardToShow = Denham.cardStack.cards[cardId];
			if (cardToShow.element.hasClass('brand')) {
				pageOptions.section = 'brand';
			} else if (cardToShow.element.hasClass('collection')) {
				pageOptions.section = 'collection';
			} else if (cardToShow.element.hasClass('garment-library')) {
				pageOptions.section = 'garment-library';
			} else if (cardToShow.element.hasClass('reports')) {
				pageOptions.section = 'reports';
			} else if (cardToShow.element.hasClass('cutters-council')) {
				pageOptions.section = 'cutters-council';
			}

			// Fetch all the cards for the first page of the home view.
			Denham.showPage(pageOptions);

			//Do a final check to see if the open card is not also in the other cards
			Denham.gridManager.cards.each(function (card, index, cards) {
				if (card && card.id == cardId)
					cards.splice(index, 1);
			});

			//Remove the open spot left by the splice action
			Denham.gridManager.cards = Denham.gridManager.cards.clean();

			// Place the card to open at the beginning of the array
			Denham.gridManager.cards.unshift(cardToShow);

		} else {
			var card = Denham.cardStack.cards[cardId];
			var deeplink = card.element.getElement('.readmore a').get('href');

			if (deeplink.match(/^http/)) {
				deeplink = deeplink.replace('http://' + document.location.hostname, '');
			}

			SWFAddress.setValue(deeplink);
		}

		Denham.gridManager.openCard = cardId;

		var title = Denham.cardStack.cards[cardId].title;
		title += ', ' + Denham.cardStack.cards[cardId].subTitle;

		document.title = title;
	},


	/**
	 * Creates one or more cards from a string of HTML (might want to rewrite the header replacing bit using regexp & innerHTML)
	 * @param {Object} string
	 */
	createCardsFromHTML: function (string) {
		var insertDom  = document.id(Denham.config.insertDomId);
		var cardOffset = Denham.gridManager.options.margin;
		var container  = document.id(Denham.config.container);

		insertDom.innerHTML = string;

		if (addthis) {
			addthis.button($$('.add_this a'), {ui_click: true});
		}

		insertDom.getElements('.footer a.section-overview').each(function (link) {
			var url = link.get('href');
			var ajaxURL  = '';
			var matches  = url.match(/([0-9]+)-([0-9]+)/);
			var offset   = matches[1];
			var pagesize = matches[2];
			var page = (offset / pagesize) + 1;

			ajaxURL = url.replace(/^\/cards\//, '/#/');
			ajaxURL = ajaxURL.replace(/([0-9]+)-([0-9]+)/, page);
			
			link.set('href', ajaxURL);
		});

		insertDom.getElements('.card').each(function (cardNode) {
			// Replace the <h1> and <h2> with a flash header

			var h1       = cardNode.getElement('h1');
			var h2       = cardNode.getElement('h2');
			var header   = cardNode.getElement('.header');
			var title    = h1.get('text');
			var subTitle = h2.get('text');

			if (Browser.Plugins.Flash.version > 0 && Browser.Plugins.Flash.build > 0) {
				var h1Node = h1.dispose();
				var h2Node = h2.dispose();

				var flashParams = {
					wMode: 'opaque',
					bgcolor: '#FFFFFF'}

				var flashVars = {
					cardTitle: title,
					cardSubtitle: subTitle}

				if (cardNode.hasClass('garment-library') || cardNode.hasClass('special')) {
					flashVars.titleHex = '#FFFFFF';
					flashParams.wMode  = 'transparent';
				}

				new Swiff('/flash/card-small-title.swf', {container: header, width: 200, height: 30, params: flashParams, vars: flashVars});

				$$(h1Node, h2Node).addClass('hide');
				header.adopt(h1Node, h2Node);
			}

			// Set the card on the top left so that it animates when it is shown
			cardNode.setStyles({'top': cardOffset, 'left': cardOffset});

			// Create a card element and place it on the stack
			var card = new Card(cardNode, container);
			card.removeFromDom();
			card.title = title;
			card.subTitle = subTitle;
			Denham.cardStack.cards[card.id] = card;
		});
	},

	showNoCardsMessage: function () {
		if (document.id('nocards')) {
			document.id('nocards').setStyle('display', 'block');
		} else {
			var holder  = new Element('div', {'id': 'nocards'});
			var message = new Element('p', {'text': 'There are no cards for your selection. We will show the homepage.'});
			var button  = new Element('a', {'href': '/#/all/all/all/1/', 'text': 'OK'});

			holder.adopt(message, button);
			$$('body')[0].grab(holder);
		}
	},
	
	hideNoCardsMessage: function () {
		if (document.id('nocards'))
			document.id('nocards').setStyle('display', 'none');
	}
}

window.addEvent('domready', Denham.initialize);