$(document).ready(function() {
	var gallery = $('div.gallery ul');
	if(gallery.length) {
		gallery.gallery({
			maxWidth :'.body > .inner',
			classes : ['oneCol','twoColLeft','twoColRight','threeCol','threeCol','threeCol','twoColLeft1','twoColLeft2'],
			beforeMaximise : function(galleryObject,maximisedImage,listItem) { 
				$(this).css({'opacity' : 0.1 });
			},
			afterMaximise : function(galleryObject,maximisedImage,listItem) {
				var self = galleryObject;
				$('.galleryStyles',maximisedImage).css('display','block');
				maximisedImage.animate({
					padding : '+=10px',
					margin : '-=10px'
				},{ duration: 'fast', complete: function(){
					var desc = $('.'+self.options.descriptionClass,maximisedImage);
				
					if(desc.text().replace(/\s/g,'').length > 0) {
						desc.animate({ 'opacity' : 0.6 });
					}
				}});
			},
			beforeMinimise : function(galleryObject,maximisedImage,listItem) {
				var self = galleryObject;
				$('.galleryStyles',maximisedImage).remove();
				$('.'+self.options.descriptionClass,maximisedImage).fadeOut();
			
			},
			afterMinimise : function(galleryObject,maximisedImage,listItem) {
				if( !galleryObject.hasMaximised  ) { //$('.galleryBoxLarge').length <= 1
					$(this).css({'opacity' : 1 });
				}
			}
		
		});
	}
	
	var slide = $('> div.inner','div.slideshow');
	if(slide.length) {
		slide.cycle({ 
		    fx:    'fade', 
		    pause:  1 
		});
	}
		
	$('input.text','div.browseTests').quickSearch({ 
		url : '/od/rd_assets/_rd_module_data/search/analyses.js', 
		parent : function() {
			return $(this).parents('div.browseTests').children('div.inner:first');
		},
		template : function(data) {
			data = $.extend({
				'title' : '',
				'description' : ''
			},data);
			
			var titleDescription = data.description.replace(/<(.*?)>/gi,'');
//				titleDescription = data.description.replace(clearHTML,'')
			
			return '<div class="item"><div class="inner"><h4 class="title"><a title="'+titleDescription+'" href="'+data.href+'">'+data.title+'</a></h4><p class="description">'+data.description+'</p></div></div>';
		},
	//	items : ['div.item'],
		fields : ['title','description'] //selectors
	//	fields : ['h4.title','p.description'] //selectors
	});
	
	var subpages = $('div.subpages'),
		articles = $('div.articles',subpages),
		active = $('div.active','div.subpages');
	
	if(active.length) {	articles.scrollTo(active);}
	
});

$.time = function(name,args) {
	var self = $.time;
	self.timers = self.timers || {};
	self.timers[name] = new Date().valueOf();
	self.timers[name].args = args || '';
};
$.timeEnd = function(name,args) {
	var self = $.time;
	self.timers = self.timers || {};
	args = args || self.timers[name].args || '';
	var time = name+'\n'+(new Date().valueOf() - self.timers[name])/1000;
	
	if(window.console) { console.log('\t'+time + '(' + args+')');}
	//else {$('body').append('<p>'+time+': '+args+'</p>');}
	
	self.timers[name] = 0;
};

$.queue = function(obj,fn,params) {
	if(!obj.queue) { obj.queue = []; }
	
	if(params) {
		if(params.constructor == Array) {fn.params = params;} }
		
	if(!fn.params) { fn.params = [];}
	
	obj.queue.push(fn);	
	(function(obj) {
		obj.queue.check = function() {		
			if(!obj.queue.processing) {
				var next = obj.queue.shift();
				if(next) {
					obj.queue.processing = true;
					
					var params = next.params,self = obj,args = [];
					
					for (var i = params.length - 1; i >= 0; i--){
						var param = params[i];
						if(i===0) {self = param;}
						else { args.push(param); }
						
					};					
					next.apply(self,args.reverse());
				}			
			}
		};
		obj.queue.done = function() {			
			obj.queue.processing = false;
			obj.queue.check();
		};
		
	})(obj);
	obj.queue.check();	
};

String.prototype.sanitise = function() {
	var self = this.toLowerCase();
	return self.replace(/^\s*|\s*$/g,'')
				.strip('_')
				.replace(/\W/g,'')
				.replace(/_/g,' ');
};

String.prototype.strip = function(c) {
	var self = this;
	return self.replace(/\s/g, c || '');
};

jQuery.fn.quickSearch = function(o) {
	var options = $.extend({},{
		timeout : 600,
		maxResults : 25,
		ignoreWordsLessThan : 2,
		parent : function() {return $(this).parent();},
		ignoreWords : ['and']
	},o);

	$.quickSearch = $.quickSearch || {};
	
	log = function(a) {
		var d = new Date().valueOf();
		var d3 = (log.d2) ? d - log.d2 : d;
		if(window.console) {
			console.log(d3+'\n\t'+a);
		} else {
			$('body').append('<p>'+d3+': '+a+'</p>');
			
		}
		log.d2 = d;
		
	};
	
	quickSearch = function (e) {
		var self = this;
		
		this.self = $(e);
		
		if( !this.self.val().length && dataStore('quickSearchValue').hasData()) {
			this.self.val(dataStore('quickSearchValue').data);	}
		
		this.self.parents('form:first').submit(function() {return false;});
		
		this.timer = undefined;
		
		this.options = {};
		
		this.dataArray = [];
			
		this.results = {};
		
	 	for(var i in options) { self.options[i] = options[i];  };
		
		if(typeof self.options.parent == 'function') {
			self.options.parent = self.options.parent.apply(e);
		} else if (typeof self.options.parent == 'string') {
			self.options.parent = self.self.parents(self.options.parent).eq(0);
		} else {
			throw new Error('Parent must either be a selector string or a function that returns a DOM element','');
		}
		
		self.wrapper = $('<div class="quickSearch"/>').hide();
		
		$('<div class="msg"/>').appendTo(self.wrapper).hide();
		
		
		if(!self.options.parent.length) {
			throw new Error('No parent element found'); return this;}
		
		self.wrapper.appendTo(self.options.parent);
		
		self.resultsArea = $('<div class="quickSearchInner"/>').appendTo(self.wrapper);
		
		$.quickSearch[new Date().valueOf()] = self;
				
		return self;
	};
	
	quickSearch.prototype.getData = function() {
		if(!this.options.url){return this;}		
		(function() {
			var self = this,
				url = self.options.url,
				fields = self.options.fields || [],
				//dataFields = self.dataFields,
				ignoreLessThan = self.options.ignoreWordsLessThan,
				ignoreLessThanRegExp = new RegExp('\\b\\w{1,'+ignoreLessThan+'}\\b','gi'),
				ignoreWords = self.options.ignoreWords,
				ignoreWordsRegExp = (function() {
					if(ignoreWords.length===0) { return false; }
					var words = (ignoreWords.length == 1) ? ignoreWords[0] : ignoreWords.join('|');
					return new RegExp('\\b'+words+'\\b','gi');
				})(),
				parent = self.options.parent;
			
			self.self.addClass('loading');
			
			var makeDataArray = function(data) {
				var dataItems = data.items;
				
				$.time('dataArray')
								
				$.each(dataItems, function(index,item){
					var itemParsed = {};
			
					itemParsed.index = index;
					itemParsed.item = item;
					itemParsed.fields = {};
			
					for (var i = fields.length - 1; i >= 0; i--){
						var field = fields[i],
							itemField = item[field],
							itemValue = (itemField && typeof itemField == 'string')
											? itemField.toLowerCase() : false;
						
						if(!itemValue){continue;}
						
						if(ignoreLessThan && ignoreLessThan !== 0 && !isNaN(ignoreLessThan)) {
							itemValue = itemValue.replace(ignoreLessThanRegExp,'');}
			
						if(ignoreWordsRegExp) {
							itemValue = itemValue.replace(ignoreWordsRegExp,'');}

						itemParsed.fields[field] = itemValue;
					};
					
					self.dataArray.push(itemParsed);
				});
				
				$.timeEnd('dataArray',dataItems.length+' items')
				
				setTimeout(function() {
					self.self.trigger('keyup',[{keyCode:13}]);	}, 0);			
				
				quickSearch.queue.done();
			};
			
			if(dataStore('quickSearchData').hasData()) {
				makeDataArray(dataStore('quickSearchData').data);
			} else {
				$.ajax({
					type : 'get',
					url: url,
					cache: true,
					success: function(response) {
						response = response.replace(/(\}|\]),\s*(\]|\})/g,'$1$2');
						response = eval('('+response+')');
						dataStore('quickSearchData',response);				
						makeDataArray( dataStore('quickSearchData').data );
					}
				});
			}
		
		}).apply(this);
		return this;
	};
	
	quickSearch.prototype.bindEvents = function() {
		var self = this,
			e = self.self;
		
		(function(self) {	
			e.keyup(function(event,event2) {				
				event = event2 || event; 
				
				var keyCode = event.keyCode,
					which = String.fromCharCode(keyCode),
					validCodes = [ 
						8, // backspace
						46, // delete
						32, // space
						13 // return
					];
						
				if(!which.match(/\w/) && $.inArray(keyCode,validCodes) == -1 ) {return;}
							
				if(self.timer) {clearTimeout(self.timer); }				
				
				self.timer = setTimeout(function() {
					clearTimeout(self.timer);
					self.timer = undefined;
					e.addClass('loading');
					self.doCheck();
					e.removeClass('loading');
				},self.options.timeout);
			
			});
		})(self);
		
		return this;
	};

	quickSearch.prototype.doCheck = function() {
		var self = this,
			e = self.self,			
			value = e.val(),
			msg = $('div.msg',self.wrapper).hide();
		
		if(!self.dataArray || !self.dataArray.length){ return; }
		
		self.wrapper.hide();
		self.resultsArea.hide();
		$('[data-quick-search]',self.resultsArea).remove();

		value = value.sanitise();
		
		dataStore('quickSearchValue', value );
		
		if(!value || !value.length || !value.strip().length) { return; }
					
		var storage = self.results[value] = self.results[value] || [],
			dataArray = self.dataArray;
		
		var doCheck = function(value,input) {
			var inputArray = input.split(' '),
				r = value.indexOf(input);
			
			if (r == -1) {
				for (var i = inputArray.length - 1; i >= 0; i--){
					var word = inputArray[i],
						wordIndexOf = value.indexOf(word);
				
					if(wordIndexOf > -1) {
						r = wordIndexOf; break;
					}
				
				};
			}
			return r;	
		};
		
		var doRelevance = function(itemClone,value,input) {
			var indexOf = value.indexOf(input),
				valueLength = value.length,
				inputLength = input.length,
				inputArray = input.split(' '),
				valueArray = value.split(' '),
				weight = 0;
						
		 	if(value == input) { weight += 200; }
			
		// If value begins with the specified input
		// e.g. 'hello' in 'hello world'
			if(value.substr(0,inputLength) == input) { weight += 100; }
			
		//	var weightedWords = 0;
			for (var i = inputArray.length - 1; i >= 0; i--){
				var word = inputArray[i],
					wordLength = word.length,
					wordIndexOf = value.indexOf(word);
				
				if(wordIndexOf == -1) { continue; }
				
			// If value begins with the specified input
			// e.g. 'hello' in 'hello world'
				if(value.substr(0,wordLength) == word) { weight += 90; }
			
				if(wordIndexOf < value.length/5 ) { weight += 70;  }
				else if(wordIndexOf < value.length/4 ) { weight += 50;}
				else if(wordIndexOf < value.length/3 ) { weight += 40;}
				else if(wordIndexOf < value.length/2 ) { weight += 25;}
			
				
				weight += 20;
			};
			
			if(indexOf > -1) {
				if(indexOf < value.length/5 ) { weight += 70;  }
				else if(indexOf < value.length/4 ) { weight += 50;}
				else if(indexOf < value.length/3 ) { weight += 40;}
				else if(indexOf < value.length/2 ) { weight += 25;}
			}
			return weight;
		};
		
		var checkItemStorage = function(item) {
			var _return;
			
			$.each(storage,function(index,storedItem) {		
				if(item.item == storedItem.item) { _return = index; return false; }
			});

			return _return;
		};
			
		var processData = function() {
			for (var i = dataArray.length - 1; i >= 0; i--){
				var item = dataArray[i],
					itemClone = $.extend({},item),
					fieldWeight = 0; // fields specified first have greatest importance (weight)	
				
				itemClone.weight = 0;
				for(var k in item.fields) {
					var field = item.fields[k];
					
					if(typeof field != 'string'){continue;}
					
					var	check = doCheck(field,value);
										
					if(check > -1) {
						var itemStoredIndex = checkItemStorage(item);
							
						itemClone.weight += doRelevance(itemClone,field,value) + fieldWeight;
																	
					// Avoid storing and showing an item more than once
						if(itemStoredIndex === undefined) { storage.push(itemClone); }
					// If item already stored, add some weight
						else { storage[itemStoredIndex].weight += 25; }
					}

					fieldWeight += 100; 
				}
			
				
			};
		};
		
		if(storage.length === 0){
			$.time('processData')
			processData();
				
			storage = storage.sort(function(a,b) {
				return a.weight-b.weight; }).reverse();
			
			$.timeEnd('processData',storage.length+' items')
			
			self.results[value] = storage;
		}
		
		if(storage.length === 0){
			msg.html('No results found for <strong>\''+value+'\'<\/strong>').show(); }
		else { 
			if($.scrollTo) { self.resultsArea.scrollTo(0); } }
		
		var storageLength = (storage.length > self.options.maxResults)
								? self.options.maxResults : storage.length,
			storageHTML = [],
			valueArray = value.split(' ');
		
		$.time('displayData')
		
		for (var i = storageLength - 1; i >= 0; i--){			
			var e = storage[i],
				eItem = $.extend({},e.item),
				storageFields = e.fields;
			
			if(!e.parsedHTML) { // it should always have this, but check anyway
				for(var field in eItem) {
					if(storageFields[field]) {
						eItem[field] = eItem[field].replace(new RegExp('('+valueArray.join('|')+')','gi'),
							'<em class="highlight">$1</em>'); }	};
				
				e.parsedHTML = storage[i].parsedHTML = self.options.template(eItem);
			}
			
			storageHTML.push( e.parsedHTML );
		};
				
		if(storage.length) {
			$(storageHTML.join('')).prependTo(self.resultsArea).attr('data-quick-search',true).show();
			self.resultsArea.show(); }
			
		$.timeEnd('displayData',storageHTML.length+' items')
		self.wrapper.show();
		
		if($.browser.msie) {
			setTimeout(function() {
				$('body').toggleClass('rebuild').toggleClass('rebuild');
			}, 0);
		}
		
		return this;
	};
	
	return this.each(function() {	
		$.queue(quickSearch,function() {
			new quickSearch(this).getData().bindEvents();
		},[this]);
	});
};