TP.ProductStore = Class.create({
	
	linkContainer: null,
	currentFilters: null,
	currentPage: null,
	defaultSettings: {
		twoCol: 'auto',
		normal: '76.5%'
	},
	moreInfoHolder: null,
	moreOptions: false,
	notificationArea: null,
	running: false,
	notifVisible: false,
	prevOption:null,
	notificationClicked: false,
	
	rightHidden: false,
	leftHidden: false,
	
	/**
	 * Creates the notification area popup
	 */
	setupNotificationArea: function() {
		this.notificationArea = new Element('div');
		this.notificationArea.addClassName('filter-notify');
		this.notificationArea.hide();
		var content = new Element('p');
		content.innerHTML = '<a href="#" class="button">update results &raquo;</a>';

		//content.show();
		this.notificationArea.insert(content);
		$$('body').first().insert(this.notificationArea);	

		this.notificationArea.style.left = TP.findLocation($('rightmenu')).x + 'px';
		//this.notificationArea.style.height = '510px';
		this.notificationArea.style.bottom = '0';
		this.notificationArea.style.top = 'auto';			
		
		content.select('a').first().observe('click', function(event){
			this.notificationClicked = true;
			this.notificationArea.addClassName('loading');
			this.updateFilters(event);
		}.bind(this));
		
	},
	
	/** 
	 * Constructor
	 */
	initialize: function() {
		
		this.setupNotificationArea();	
		
		if (typeof ie6Settings != 'undefined') {
			this.defaultSettings = ie6Settings;
			this.defaultSettings.ie6init();
		}
	
		var matches = location.href.toString().match(/page=([0-9]+)/);
		if(matches == null)
			this.currentPage = 1;
		else
			this.currentPage = matches[1];

		$$('p.hide-left a, p.show-left a').first().observe('click', this.toggleLeftPanel.bindAsEventListener(this));
		
		if($('leftmenu').select('.left-nav-product').first().style.display == 'none') {
			this.leftHidden = true;
		}

		$('leftmenu').style.position = 'relative';
		$('leftmenu').style.cssFLoat = 'left';
		//$('leftmenu').select('.left-nav-product').first().style.position = 'relative';
		//$('leftmenu').select('.left-nav-product').first().style.top = '0';
		
		if(this.leftHidden) {
			$$('p.hide-left a').first().innerHTML = 'Show the left column';
			$$('p.hide-left').first().addClassName('show-left');
			$$('p.hide-left').first().removeClassName('hide-left');

			$('leftmenu').select('.left-nav-product').first().style.position = 'relative';
			$('leftmenu').select('.left-nav-product').first().style.left = '-' + ($('leftmenu').getWidth()+20) + 'px';
			
			$('leftmenu').select('.left-nav-product').first().hide();
		}
		
		/**
		 * Creates a copy of the selected filters
		 * This is used to query the server for the current url.
		 */
		this.currentFilters = Form.fastSerialize($$('form.filters').first());
		
		this.setup($('more-new-containers'));
		
		this.setupResults();

	},
	
	/**
	 * Creates the more info box default
	 */
	setupMoreInfo: function(){
		
		if(this.moreInfoHolder != null)
			this.moreInfoHolder.remove();
		
		this.moreInfoHolder = new Element('div');
		this.moreInfoHolder.className = 'more-info-wrapper';
		this.moreInfoHolder.style.zIndex = 6000;
		
		var div = new Element('div');
		div.className = 'more-info';
		
		var p = new Element('p');
		p.className = 'loading';
		
		p.innerHTML = '<strong>Loading...</strong> Please wait';
		
		div.insert(p);
		
		this.moreInfoHolder.insert(div);
	},
	
	/**
	 * Performs setup on root supplied
	 */
	setup: function(root) {

		/**
		 * Update filter button
		 */
		root.select('form.filters div.update a').each(function(ele){
			ele.observe('click', this.updateFilters.bindAsEventListener(this));
		}.bind(this));
		
		/**
		 * Enable hidden javascript buttons
		 */
		root.select('.js_required').each(function(ele){
			ele.style.display = 'block';
		});
		
		root.select('.js_required_inline').each(function(ele){
			ele.style.display = 'inline';
		});
			
		/**
		 * Hide JS fallback buttons
		 */
		root.select('.js_fallback').each(function(ele){
			ele.hide();
		});
		
		if(this.moreOptions == true) {
			root.select('ul[id="fewer-options"]').invoke('hide');
			root.select('ul[id="more-options"]').invoke('show');				
		} else {
			root.select('ul[id="fewer-options"]').invoke('show');
			root.select('ul[id="more-options"]').invoke('hide');
		}
		
		/**
		 * Default menu setup - all hidden
		 */
		var openSection = location.href.toString().match(/open=([A_Za-z\ \+]+)/);
		root.select('form.filters ul.right-nav.filters li.major-filter-open, form.filters ul.right-nav.filters li.minor-filter-open').each(function(ele){
			var type = ele.className.match(/^((major)|(minor))\-/);	
			
			var hide = true;
			var regex = new RegExp(ele.id + '([\[=]+)');
			if(decodeURI(this.currentFilters).match(regex)){
				hide = false;
			}
			
			// This stops forms with selected options being hidden
			if(hide) {
				if(openSection == null || openSection[1] != ele.id){	
					ele.removeClassName(type[1]+'-filter-open');
					ele.addClassName(type[1]+'-filter');
					ele.select('fieldset').invoke('hide');
				}
			}
			
			ele.select('a').first().observe('click', this.menuClickEvent.bindAsEventListener(this, ele, type));
		}.bind(this));

	}, 
	
	/**
	 * Left notification
	 */
	showNotification: function(event){
		
		this.notificationClicked = false;
		
		var scrolled = TP.getScrollPosition();	
		var loc = TP.findLocation($$('div.update').first());

		var updateBottom = loc.y+$$('div.update').first().offsetHeight;				
		var size = TP.getSize();

		this.notificationArea.style.left = TP.findLocation($('rightmenu')).x + 'px';
		this.notificationArea.style.width = $('rightmenu').getWidth() + 'px';
		
		if((scrolled + size.height) < updateBottom){
			if(this.notifVisible)
				return;
		
			this.notifVisible = true;
			
			if(typeof ie6Settings != 'undefined')
				ie6Settings.ie6NotificationFix(this.notificationArea);
				
			TP.setOpacity(this.notificationArea, 0);
			this.notificationArea.show();
			
			TP.fadeIn(this.notificationArea, function(){ 
				setTimeout(function(){
					
					if(!this.notificationClicked){		
						TP.fadeOut(this.notificationArea, function(){
							this.notificationArea.hide();
							this.notifVisible = false;
						}.bind(this));
					}
				}.bind(this), 5000);
			}.bind(this));
		} 
		
	},
	
	/**
	 * Loads more filters and inserted into left menu
	 */
	loadMoreFilters: function(event, ele){
		event.stop();
		
		if(this.running)
			return;
		this.running = true;
		
		ele.addClassName('loading');
		var type = ele.href.match(/\#([A-Za-z\ \+]+)/)[1];
						
		new Ajax.Request(ele.href, {
			method:'post',
			parameters: this.currentFilters +'&menu_load=1', 
			onSuccess: function(transport) {

				var temp = new Element('div');
				temp.innerHTML = transport.responseText;
				
				type = type.replace('+', '');
				var list = temp.select('li[id="'+type+'"]').first();
				
				Effect.SlideUp($(type).select('fieldset').first(), {duration:0.5, afterFinish:function(){
					$(type).select('fieldset').first().innerHTML = list.select('fieldset').first().innerHTML;
					Effect.SlideDown($(type).select('fieldset').first(), {duration:0.5, afterFinish: function(){
						this.running = false;
						this.setup($(type));
						
						//rebind the event
						$(type).select('a.more-filters, a.less-filters').each(function(ele){
							ele.observe('click', this.loadMoreFilters.bindAsEventListener(this, ele));
						}.bind(this));
					}.bind(this)});
				}.bind(this)});						
			}.bind(this)
		});	
	},
	
	menuClickEvent: function(event, ele, type) {				
		event.stop();
		
		if(this.running)
			return false;
		
		this.running = true;
		
		if(ele.select('fieldset').first().visible() == false)
			this.menuItemDown(event, ele, type);
		else
			this.menuItemUp(event, ele, type);
	},
	
	/***
	 * Setup next/prev links, more info and scratchpad
	 */
	setupResults: function() {
		
		/**
		 * Show all options
		 */
		$('rightmenu').select('a.more-filters, a.less-filters').each(function(ele){
			ele.observe('click', this.loadMoreFilters.bindAsEventListener(this, ele));
		}.bind(this));		
	
		
		if($('fewer-options')!= null) {
			$('fewer-options').select('li.next-ten a, li.last-ten a').each(function(ele){
				ele.observe('click', function(event){
					event.stop();
					this.paginationInsert(ele.href);
				}.bind(this));
			}.bind(this));
			
			$('fewer-options').select('li.more-options a').each(function(ele){
				ele.observe('click', function(event){
					event.stop();
					this.moreOptions = true;
					$('fewer-options').hide();
					$('more-options').show();
				}.bind(this));
			}.bind(this));
		}
		
		if($('more-options') != null){
			$('more-options').select('li.fewer-options a').each(function(ele){
				ele.observe('click', function(event){
					event.stop();
					this.moreOptions = false;
					$('more-options').hide();
					$('fewer-options').show();						
				}.bind(this));
			}.bind(this));
			
			$('more-options').select('li a').each(function(ele){
				if(!ele.up().hasClassName('fewer-options')){
					ele.observe('click', function(event){
						event.stop();
						this.paginationInsert(ele.href);				
					}.bind(this));
				}
			}.bind(this));
		}
				
		if($('search-results')!= null) {
			$('search-results').select('li.info').each(function(ele) {
				var parent = ele.up().up().up();
				ele.down().observe('click', this.getMoreInfo.bindAsEventListener(this, ele.down(), parent));	
			}.bind(this));
		}
		
		this.prevOption = null;
		
		$$('div.list_header ul li.option').each(function(ele){
			ele.down('div').select('ul li').each(function(li){
				li.down('a').observe('click', this.changeView.bindAsEventListener(this, ele, li));
			}.bind(this));
			
			ele.down('div').down('a').observe('click', this.toggleViewOptions.bindAsEventListener(this, ele));
		}.bind(this));
		
		Lightview.updateViews();		
	},
	
	toggleViewOptions: function(event, ele){
		event.stop();

		var list = ele.down('div').down('ul');

		if(this.prevOption != null && this.prevOption != list)
			this.prevOption.hide();
		
		this.prevOption = list;
		list.toggle();
		
	},
	
	changeView: function(event, ele, li){
		event.stop();
		
		if(this.running)
			return;
		
		this.running = true;
		
		ele.down('div').down('a').addClassName('loading');

		
		var name = li.up().up().up().className.toString().match(/(^[^\ ]+)/)[1];
		
		var option;
		if(name == 'show') {
			option = li.down('a').innerHTML.replace(/([^0-9]+)/,'');
		} else {
			option = li.className;
		}
		
		new Ajax.Request('/preferences.html?'+name+'=' + option, {
			onSuccess:function(transport){
				this.running = false;
				this.prevOption.hide();
				this.prevOption = null;
				this.paginationInsert(li.down('a').href);
			}.bind(this)
		});
	},
	
	/**
	 * Gets more info about a product
	 */
	getMoreInfo: function(event, ele, parent){
		event.stop();
		
		if(this.running)
			return
		this.running = true;
		
		if(parent.hasClassName('active')){
			this.moreInfoHolder.remove();
			this.moreInfoHolder = null;
			parent.removeClassName('active');
			$('search-results').style.marginBottom = '0px';
			this.running = false;
		} else {
			var contentBottom = TP.findLocation($('content')).y + $('content').getHeight();
			
			if(this.moreInfoHolder != null) {
				this.moreInfoHolder.up().removeClassName('active');
				this.moreInfoHolder.remove();
				this.moreInfoHolder = null;	
				$('search-results').style.marginBottom = '0px';
			}
			
			parent.up().style.zIndex = 1000;
			
			parent.addClassName('active');
			var id = ele.href.match(/variant_id=([0-9]+)$/)[1];		
			this.setupMoreInfo();
			parent.insert(this.moreInfoHolder);
			
			
			var miBottom = TP.findLocation(this.moreInfoHolder).y + this.moreInfoHolder.getHeight();
			var diff = miBottom-contentBottom;

			if(diff > 0) {
				$('search-results').style.marginBottom = diff+10 + 'px';
			}
			
			var contentBottom = TP.findLocation($('search-results')).y + $('search-results').getHeight();
			
			new Ajax.Request(location.href.toString(), {
				method:'POST',
				parameters:'more_info='+id,
				onSuccess: function(transport){
					this.moreInfoHolder.select('div.more-info').first().innerHTML = transport.responseText;
					
					this.moreInfoHolder.select('p.close').first().observe('click', function(event){
						this.getMoreInfo(event, ele, parent);
						
					}.bind(this));
					
					var miBottom = TP.findLocation(this.moreInfoHolder).y + this.moreInfoHolder.getHeight();
					var diff = miBottom-contentBottom;

					if(diff > 0) {
						$('search-results').style.marginBottom = diff+10 + 'px';
					}
					
					this.running = false;
					Lightview.updateViews();
					Scratchpad.initCheckBoxes();
					Scratchpad.updatePageCheckBoxes();
					
				}.bind(this)
				
			});	
		}
	},
	
	/**
	 * Creates the containers for the link box
	 */
	createLinkContainer: function() {
		var container = new Element('span');
		container.addClassName('link_details');
		var textBox = new Element('input');
		textBox.type = 'text';
		textBox.value = 'Loading...';
		container.appendChild(document.createTextNode('You can select the link below and copy it for use elsewhere.'));
		container.appendChild(textBox);
		
		return {
			container: container,
			textbox: textBox
		};
	},
	
	/**
	 * Update store filters and perform search
	 * TODO: Transition Effects
	 */
	updateFilters: function(event) {
		event.stop();
		
		if(this.running)
			return
			
		this.running = true;

		$$('div[id="rightmenu"] div.update').first().addClassName('loading');

		this.currentFilters = Form.serialize($$('form.filters').first());

		this.currentPage = 1;
		var location = new String(document.location.href);
		
		new Ajax.Request(location,{
			method: 'post',
			parameters: this.currentFilters + '&filter_submit=true',
			onSuccess: function(transport) {

				/**
				 * Adds the response text to the DOM so we can manipulate it 
				 * before inserting it into the page.
				 */
			
				var tempEle = new Element('div');
				tempEle.innerHTML = transport.responseText;
				this.setup(tempEle);		
				
				
				tempEle.select('div.update').first().addClassName('loading');
				/**
				 * Swaps the current menu with the new data
				 */
				
				var menu = $$('ul.right-nav.filters').first();
				menu.insert({after:tempEle.select('div[id="rightmenu"] ul.right-nav.filters').first()});
				menu.remove();

				
				var content = $('content');
				var toInsert = tempEle.select('div[id="content"]').first();
				
				this.insertAndSlide(content, toInsert, function(){
					$$('div[id="rightmenu"] div.update').first().removeClassName('loading');
					this.running = false;
					
					if(this.notificationClicked == true) {
						TP.fadeOut(this.notificationArea, function(){
							this.notificationArea.hide();
							this.notifVisible = false;
							this.notificationClicked = false;
							this.notificationArea.removeClassName('loading');
						}.bind(this));
					}
				}.bind(this));
								
			}.bind(this)
		});
		
	},	
	
	/**
	 * Inserts content and slides the content to the left
	 */
	insertAndSlide: function(content, toInsert, callback) {
		if(this.moreInfoHolder != null){
			this.moreInfoHolder.remove();
			this.moreInfoHolder = null;
			$('content').style.marginBottom = '0px';
		}
		
		var trueWidth = content.getWidth();
		var padding = content.getStyle('padding-left');

		if(padding.match(/%/)){
			padding = (trueWidth/100)*parseInt(padding);
		} else {
			padding = parseFloat(padding);
		}
		
		var width = trueWidth - (padding*2);
		
		var origContentWidth = content.style.width;
		
		content.style.padding = padding + 'px';
		content.style.width = width + "px";
		
		content.up().style.width = '5000px';
		content.up().up().style.width = trueWidth + 'px';
		content.up().up().style.overflowX = 'hidden';	
		
		content.up().up().up().style.width = trueWidth + 'px';
		content.up().up().up().style.cssFloat = 'left';
		content.up().up().up().style.styleFloat = 'left';
		content.up().up().up().style.height = content.getHeight() + 'px';
		
		//bad bad bad
		if(Prototype.Browser.IE) {
			content.up().up().style.position = 'absolute';
		}
		
		toInsert.style.padding = padding + 'px';
		toInsert.style.width = width + 'px';
		toInsert.style.cssFloat = 'left';
		
		content.insert({after:toInsert});
		
		if(toInsert.getHeight() > content.getHeight()){
			content.up().up().up().style.height = toInsert.getHeight() + 'px';
		}

		new Effect.Parallel([
			new Effect.Move(content, { x:-trueWidth, y:0, mode:'absolute'}),
			new Effect.Move(toInsert, { x:-trueWidth, y:0, mode:'absolute'})
		], {duration: 1, afterFinish: function(){ 
			
			var body = document.getElementsByTagName('body')[0];
			
			content.up().up().style.overflowX = '';
			content.up().up().style.cssFloat = '';
			content.up().up().up().style.height = '';
			content.up().up().up().style.width = '';
			content.up().up().up().style.cssFloat = '';
			content.up().up().style.position = '';
			content.up().up().style.width = '';
			
			content.up().style.width = '';
			toInsert.style.width = origContentWidth;
			toInsert.style.left = '0';
			toInsert.style.padding = '';
			content.remove();
			
			this.setupResults();
			
			Scratchpad.initCheckBoxes();
			
			(new TP.PageScroller(toInsert)).scrollEvent();
			
			if(typeof callback != 'undefined')
				callback();
		}.bind(this)});		
	},
	
	/**
	 * Slide the menu section down
	 */
	menuItemDown: function(event, ele, /*scroller,*/ type) {
		type = type[1];
		ele.removeClassName(type+'-filter');
		ele.addClassName(type+'-filter-open');
		Effect.SlideDown(ele.select('fieldset').first(), {duration:0.5 , afterFinish: function(){
			//scroller.scrollEvent();
			this.running = false;
		}.bind(this)});
	},
	
	/**
	 * Slide the menu item up
	 */
	menuItemUp: function(event, ele, type) {	
		type = type[1];
		ele.removeClassName(type+'-filter-open');
		ele.addClassName(type+'-filter');
		Effect.SlideUp(ele.select('fieldset').first(), {duration:0.5, afterFinish: function(){
			this.running = false;
		}.bind(this)});
	},
	
	/**
	 * Toggle the left menu
	 */
	toggleLeftPanel: function(event, callback) {
		event.stop();	
		
		if(this.running)
			return;
		
		this.running = true;
		
		var move = $('leftmenu').getWidth()+20;
		
		$('leftmenu').style.overflowX = 'hidden';
		
		if(!this.leftHidden) {	

			new Effect.Move($('leftmenu').select('.left-nav-product').first(), { x:-move, y:0, mode:'relative', afterFinish: function(){
				$$('p.hide-left a').first().innerHTML = 'Show the left column';
				$$('p.hide-left').first().addClassName('show-left');
				$$('p.hide-left').first().removeClassName('hide-left');	
				
				$('leftmenu').select('.left-nav-product').first().hide();
				$('container_new').style.width = '100%';
				
				if(this.rightHidden)
					$('rightmenu').style.left = ($('rightmenu').getWidth()+20) + 'px';
				
				this.leftHidden = true;
				
				$('leftmenu').style.overflowX = '';
				this.running = false;
			}.bind(this)});
		} else {
			$('container_new').style.width = '';
			$('container_new').style.margin = '';
			$('leftmenu').select('.left-nav-product').first().show();	

			new Effect.Move($('leftmenu').select('.left-nav-product').first(), { x:move, y:0, mode:'relative', afterFinish: function(){
				$$('p.show-left a').first().innerHTML = 'Hide the left column';
				$$('p.show-left').first().addClassName('hide-left');
				$$('p.show-left').first().removeClassName('show-left');		
				
				if(this.rightHidden)
					$('rightmenu').style.left = ($('rightmenu').getWidth()+20) + 'px';
				
				this.leftHidden = false;
				
				$('leftmenu').style.overflowX = '';
				this.running = false;
			}.bind(this)});
			
		}
		
	},
	
	/**
	 * Loads more content based on pagination
	 */
	paginationInsert: function(loc) {
		
		if(this.running)
			return;
		
		this.running = true;
		
		$$('ul[id="fewer-options"] li.loading, ul[id="more-options"] li.loading').each(function(ele){ele.style.display='block';});
		
		if(loc.match(/page=([0-9]+)/) != null) {
			this.currentPage = loc.match(/page=([0-9]+)/)[1];
		}
		
		new Ajax.Request(loc, {
			method:'get',
			onSuccess: function(transport) {
				var tempEle = new Element('div');
				tempEle.innerHTML = transport.responseText;
				this.setup(tempEle);				

				var menu = $$('ul.right-nav.filters').first();
				menu.insert({after:tempEle.select('div[id="rightmenu"] ul.right-nav.filters').first()});
				menu.remove();
				
				var content = $('content');
				var toInsert = tempEle.select('div[id="content"]').first();
				
				this.currentFilters = Form.serialize($$('form.filters').first());

				this.insertAndSlide(content, toInsert, function(){
					this.running = false;
				}.bind(this));
			}.bind(this)
		});		
	}

});

document.observe('dom:loaded', function(){	
	TP.Store = new TP.ProductStore();
});