(function($){
	var solrSearch = function(element, options) {		
		element = $(element);
		var obj = this;
		var template_str = '';
		var reg_exp_match = /\$\{(\w+)\}/g;
		var matches = [];
		var num_matches = 0;
		var url_var_map = {
			'cur_page' : 'p'
		};

		var settings = $.extend({
			query_url: '', 
			query_sort: 'score+desc',
			query: {}, // format should be {"field_name":"field_value","field_name":"field_value"} - send multiple values for an OR statement by using | to separate value options in the field_value
			facets: {items:[]}, // format should be {items:[{name:'facet-name',dd:1,top_text:'Shop By Size']}
			add_facets: {items:[]}, // format shoulg be {items:[{name:'facet-name',top_text:'Shop By Size',ops:[{'option_name':'option_val'}]]}
			facets_to: '.cat_nav',
			rt_fields: '', // comma delimited list of fields to get back from solr if there is a need to minimize response
			line_clear_code: '<div class="clear"><!-- --></div>',
			paging_prev_code: 'Previous',
			paging_next_code: 'Next',
			view_all_code: 'View All',
			paging_to: '.pages',
			product_listing: '#product_list',
			item_node_html: '/skin/frontend/default/lrg/js/item_template.jst',
			image_not_found: '/skin/frontend/default/lrg/images/no_image_cat.jpg',
			item_trans: {}, // format should be {'item_name':'p|i','another_item_name':'p|i'}
			suggestions: false,
			show_per_page: {},  // format should be {show_in:'.class_name',top_text:'Sort By',top_value:16,label:'',ops:[16,32,100]} if blank, nothing will be shown
			show_sort_by: {},  // format should be {show_in:'.class_name',top_text:'Sort By',top_value:'score+desc',label:'',ops:{'price':'price+asc','name':'name+asc'}} if blank, nothing will be shown
			total_items: 0,
			total_pages: 0,
			offset: 0,  
			per_page: 20,
			cur_page: 1,
			results_per_line: 4,
			reset_facet_dd: 1,
			success: '' // name of the function to send data results of the solr query back to. enables functions to be written to supplement functionality that's not built in
		}, options || {})

		var swap_json_key_val = function(input) {
			var one, output = {};
			for (one in input) {
				if (input.hasOwnProperty(one)) {
					output[input[one]] = one;
				}
			}
			return output;
		}

		var load_url_vars = function() {
			var url = window.location.href;
			if (url.indexOf('#') > 0) {
				var rev = swap_json_key_val(url_var_map);
				var s = url.split('#');
				var var_list = s[1].split('/');
				var len = var_list.length;
				for (var i = 0; i < len; i++) {
					var pair = var_list[i];
					var name = pair.substr(0,pair.indexOf('='));
					var val = pair.substr(pair.indexOf('=')+1);
					settings[rev[name]] = parseInt(val);
				}
			} else {
				settings.cur_page = 1;
			}
		}

		var update_url = function() {
			var url = window.location.href;
			var address = '', append = '';
			if (url.indexOf('#') > 0) {
				var s = url.split('#');
				address = s[0];
			} else {
				address = url;
			}

			append = url_var_map.cur_page + '=' + settings.cur_page;

			window.location = address + '#' + append;

			//if(($.browser.msie && $.browser.version < '8') || ($.browser.mozilla && $.browser.version <= '1.9.1.16')) {
				//$(window).trigger('hashchange');
			//}
		}

		
		this.load_page = function() {
			$.ajax({type:'get',
					async:false,
					url:settings.item_node_html,
					success: function(data) {
						template_str = data;
					}
			});
			matches = template_str.match(reg_exp_match);
			num_matches = matches.length;
			for (var i = 0; i < num_matches; i++) {
				matches[i] = matches[i].replace('${','').replace('}','');
			}
				
			//$(window).bind('hashchange', function(e) {
				//load_url_vars();
				//obj.run_search();
			//});

			$(window).hashchange( function(){
				load_url_vars();
				obj.run_search();
			});

			$(window).hashchange();

		}
		
		this.run_search = function() {
			$.getJSON(build_query(),
				function(data) {
					var item_code = '';
					var cnt = 1;
					if (data.response.numFound > 0) {
						
						if (settings.reset_facet_dd == 1) {
							add_facet_dropdowns(data.facet_counts)
						}
						
						$.each(
							data.response.docs,
							function(i, item) {
								item_code += get_product_node_html(item);
								if (cnt == settings.results_per_line) {
									item_code += settings.line_clear_code;
									cnt = 0;
								}
								cnt++;
							});
						
						settings.total_items = data.response.numFound;
						settings.total_pages = Math.ceil(settings.total_items / settings.per_page);
						
						$(settings.facets_to).show();
						$(settings.product_listing).html(item_code);
						
						page_links();
						
						settings.reset_facet_dd = 0;
						
						if (settings.success.length > 0) {
							eval(settings.success + '(data.response.docs);');
						}
						
					} else {
						if (settings.reset_facet_dd == 1) {
							$(settings.facets_to).hide();
						}

						$(settings.product_listing).html('<p>No Products Found</p>');
						
						page_links();
						
						settings.reset_facet_dd = 0;
					}					
				});
		}
		
		this.go_to_page = function(page_num) {
			settings.cur_page = parseFloat(page_num);
			//obj.run_search();
			update_url();
		}

		this.view_all = function() {
			settings.per_page = settings.total_items;
			settings.cur_page = 1;
			//obj.run_search();
			update_url();
		};

		
		this.dropdown_select = function() {
			settings.cur_page = 1;
			obj.run_search();
		}
		
		var add_facet_dropdowns = function(facets) {
			$(settings.facets_to).html('');
		
			if (obj.isdefined(facets)) {
				var fields = facets.facet_fields;
				
				if (settings.facets.items.length > 0) {
					var facet_items = settings.facets.items;
					var f_length = facet_items.length;
					for (var i = 0; i < f_length; i++) {
						if (facet_items[i].dd == 1) {
							var facet_name = facet_items[i].name;
							var item_length = fields[facet_name].length;
							$(settings.facets_to).append('<select id="' + facet_name + '" class="dd_select select"></select>');
							$('#' + facet_name).append('<option value="0">' + facet_items[i].top_text + '</option>');
							for (var j = 0; j < item_length; j++) {
								if (fields[facet_name][j+1] > 0) { //check count of facet
									$('#' + facet_name).append('<option value="' + fields[facet_name][j] + '">' + fields[facet_name][j] + '</option>');
								}
								j++; // skip over the "count" of products per each item in facet
							}
						}
					}				
				}
			}
			
			if (settings.add_facets.items.length > 0) {
				var facet_items = settings.add_facets.items;
				var f_length = facet_items.length;
				for (var i = 0; i < f_length; i++) {
					var facet_name = facet_items[i].name;
					$(settings.facets_to).append('<select id="' + facet_name + '" class="dd_select select"></select>');
					$('#' + facet_name).append('<option value="0">' + facet_items[i].top_text + '</option>');
					$.each(facet_items[i].ops, function(key,value) {
						$('#' + facet_name).append('<option value="' + value + '">' + key + '</option>');
					});
				}				
			}
			
			if (obj.isdefined(settings.show_per_page.show_in)) {
				var ops = settings.show_per_page.ops;
				if (obj.isdefined(settings.show_per_page.label)) {
					$(settings.show_per_page.show_in).append(settings.show_per_page.label);
				}
				$(settings.show_per_page.show_in).append('<select id="per_page_select" class="spec_select select"></select>');
				if (obj.isdefined(settings.show_per_page.top_text)) {
					$('#per_page_select').append('<option value="' + settings.show_per_page.top_value + '">' + settings.show_per_page.top_text + '</option>');
				}
				$.each(ops, function(key,value) {
					$('#per_page_select').append('<option value="' + value + '">' + value + '</option>');
				});
			}
			
			if (obj.isdefined(settings.show_sort_by.show_in)) {
				var ops = settings.show_sort_by.ops;
				if (obj.isdefined(settings.show_sort_by.label)) {
					$(settings.show_sort_by.show_in).append(settings.show_sort_by.label);
				}
				$(settings.show_sort_by.show_in).append('<select id="sort_by_select" class="spec_select select"></select>');
				if (obj.isdefined(settings.show_sort_by.top_text)) {
					$('#sort_by_select').append('<option value="' + settings.show_sort_by.top_value + '">' + settings.show_sort_by.top_text + '</option>');
				}
				$.each(ops, function(key,value) {
					$('#sort_by_select').append('<option value="' + value + '">' + key + '</option>');
				});
			}
			
			$('.dd_select').change(obj.dropdown_select);
			$('.spec_select').change(obj.dropdown_select);
		}
		
		this.isdefined = function(variable) {
			return (typeof(variable) !== "undefined") ? true : false;
		}
		
		this.format_price = function(price) {
			price = price.toFixed(2) + '';
			x = price.split('.');
			x1 = x[0];
			x2 = x.length > 1 ? '.' + x[1] : '';
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1)) {
				x1 = x1.replace(rgx, '$1' + ',' + '$2');
			}
			return '$' + x1 + x2;
		}
		
		this.empty_image = function(image) {
			if (obj.isdefined(image)) {
				return image;
			}
			
			return settings.image_not_found;
		}
		
		var get_product_node_html = function(item) {			
			var html_code = template_str;		
			var output;				
			for (var i = 0; i < num_matches; i++) {
				output = item[matches[i]];
				if (obj.isdefined(settings.item_trans[matches[i]])) {
					if (settings.item_trans[matches[i]] == 'p') output = obj.format_price(item[matches[i]]);
					else if (settings.item_trans[matches[i]] == 'i') output = obj.empty_image(item[matches[i]]);
				}
				html_code = html_code.replace('${'+matches[i]+'}',output);
			}

			return html_code;
		}
		
		var build_query = function() {
			if (obj.isdefined(settings.show_per_page.show_in) && $('#per_page_select').length > 0) {
				settings.per_page = $('#per_page_select').val();
			}
			
			if (obj.isdefined(settings.show_sort_by.show_in) && $('#sort_by_select').length > 0) {
				settings.query_sort = $('#sort_by_select').val();
			}
			
			settings.offset = (settings.cur_page - 1) * settings.per_page;
			
			var query = settings.query_url;
			
			if (settings.query_sort.length > 0) {
				query += '&sort=' + settings.query_sort;
			}
			
			query += '&start=' + settings.offset + '&rows=' + settings.per_page;
			
			var empty_search = true;
			query += '&q=';
			
			$.each(settings.query, function(key,value) {
				if (value.toString().indexOf('|') > -1) {
					query += (!empty_search ? '+AND+' : '') + '(';
					var search_options = value.split('|');
					for (var so_cnt = 0; so_cnt < search_options.length; so_cnt ++) {
						query += (so_cnt > 0 ? '+OR+' : '') + key + ':' + search_options[so_cnt];
					}
					query += ')';
				} else {
					query += (!empty_search ? '+AND+' : '') + key + ':' + value;
				}
				empty_search = false;
			});	
			
			$('.dd_select').each(function() {
				if ($(this).val() != '0') {
					query += (!empty_search ? '+AND+' : '') + $(this).attr('id') + ':' + $(this).val();
					empty_search = false;
				}
			});
				
			if (empty_search) {
				query += '*:*';
			}
			
			if (settings.facets.items.length > 0) {
				var f_length = settings.facets.items.length;
				//query += '&facet=true';
				query += '&facet=';
				for (var i = 0; i < f_length; i++) {
					//query += '&facet.field=' + settings.facets.items[i].name;
					query += settings.facets.items[i].name;
					if (i + 1 < f_length) query += '|';
				}
			}
			
			if (settings.rt_fields.length > 0) {
				query += '&fl=' + settings.rt_fields;
			}
			
			return query;
		};
		
		var page_links = function () {
			var page_code = '';
			if (settings.total_items > 0) {
				var count_start = 1, count_end = 5, print_end = true;
			
				if (settings.total_pages > 1 && settings.cur_page > 1) {
					page_code += '<span class="prev_next_nav"><a href="#" class="paging_link" id="prev_' + (settings.cur_page-1).toString() + '">' + settings.paging_prev_code + '</a></span>';
				} else {
					page_code += '<span class="prev_next_nav">&nbsp;</span>';
				}
				
				if (settings.cur_page > 5) {
					page_code += '<span class="pl"><a href="#" class="paging_link" id="pl_1">1</a></span> <span class=\"dots\">...</span> ';
					count_start = settings.cur_page - 2;
					count_end = settings.cur_page + 2;
				}
				
				for (var i = count_start; i <= count_end; i++) {
					if (i == settings.cur_page) {
						page_code += '<span class="pl"><a class="current">' + i + '</a></span> ';
					} else if (i <= settings.total_pages) {
						page_code += '<span class="pl"><a href="#" class="paging_link" id="pl_' + i + '">' + i + '</a></span> ';
					}
				}
				
				if (settings.total_pages - settings.cur_page > 3 && settings.total_pages > 5) {
					page_code += ' <span class="dots">...</span> <span><a href="#" class="paging_link" id="pl_' + settings.total_pages + '">' + settings.total_pages + '</a></span> ';
				}
			
				if (settings.cur_page < settings.total_pages) {
					page_code += '<span class="prev_next_nav"><a href="#" class="paging_link" id="next_' + (settings.cur_page+1).toString() + '">' + settings.paging_next_code + '</a></span>';
				} else {
					page_code += '<span class="prev_next_nav">&nbsp;</span>';
				}
				
				if (settings.total_pages > 1 && settings.view_all_code.length > 0) {
					page_code += '<span><a href="#" class="view_all_link">' + settings.view_all_code + '</a></span>';
				}
			}
			
			$(settings.paging_to).html(page_code);
			
			$('.paging_link').click(function(e) {
				e.preventDefault();
				var page_num = $(this).attr('id').split('_');
				obj.go_to_page(page_num[1]);
			});
			
			$('.view_all_link').click(function(e) {
				e.preventDefault();
				obj.view_all();
			});
		}
   };

   $.fn.solrsearch = function(options)
   {
       return this.each(function() {
           var element = $(this);
          
           // Return early if this element already has a plugin instance
           if (element.data('solrsearch')) return;

           // pass options to plugin constructor
           var solrsearch = new solrSearch(this, options);

           // Store plugin object in this element's data
           element.data('solrsearch', solrsearch);
       });
   };
})(jQuery);

/*
* jQuery hashchange event - v1.3 - 7/21/2010
* http://benalman.com/projects/jquery-hashchange-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){r||l(a());n()}).attr("src",r||"javascript:0").insertAfter("body")[0].contentWindow;h.onpropertychange=function(){try{if(event.propertyName==="title"){q.document.title=h.title}}catch(s){}}}};j.stop=k;o=function(){return a(q.location.href)};l=function(v,s){var u=q.document,t=$.fn[c].domain;if(v!==s){u.title=h.title;u.open();t&&u.write('<script>document.domain="'+t+'"<\/script>');u.close();q.location.hash=v}}})();return j})()})(jQuery,this);
