(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 default_sort = '';
		this.main_query_result_data;
		
		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',insert_in:'.location']}
			add_facets: {items:[]}, // format should be {items:[{name:'facet-name',top_text:'Shop By Size',insert_in:'.location',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: '.blank',
			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: {items:[]},  // format should be {items:[{name:'sort-name',show_in:'#new_sort',type:'check',top_text:'Sort By',top_value:'score+desc'},{name:'sort-name2',show_in:'#best_sell_sort',type:'check',top_text:'Sort By',top_value:'score+desc'},{show_in:'.class_name',type:'dd',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,
			update_facets_options_on_select: 0, // update facet dropdowns on change. ONLY updates the facets in the "facets" dropdown
			per_page: 2000,
			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 || {})
		
		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('}','');
			}
			default_sort = settings.query_sort;
			obj.run_search();
		}
		
		this.reset_original = function () {
			settings.query_sort = default_sort;
			settings.reset_facet_dd = 1;
			obj.run_search();			
		}
		
		this.run_search = function() {
			$.getJSON(build_query(settings.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);
						} else if (settings.update_facets_options_on_select == 1) {
							update_facet_dropdowns(data.facet_counts);
						}*/
						//alert(data.facet_counts.category_id[0]+":"+data.facet_counts.category_id[1]);
						
						//krFilter.updateFacetCounts(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);');
						}
						
						obj.main_query_result_data = data;
						
						krFilter.updateFacetCounts();
						
					} else {
						/*if (settings.reset_facet_dd == 1) {
							$(settings.facets_to).hide();
						}*/

						$(settings.product_listing).html('<div class="error-msg left" style="margin-left: 0pt; padding-bottom: 7px; padding-left: 50px; width: 300px;"><p>NO PRODUCTS WERE FOUND. PLEASE TRY AGAIN</p></div>');
						
						page_links();
						
						settings.reset_facet_dd = 0;
					}					
				});
		}
		
		this.go_to_page = function(page_num) {
			settings.cur_page = parseFloat(page_num);
			obj.run_search();
		}
		
		this.view_all = function() {
			settings.per_page = settings.total_items;
			settings.cur_page = 1;
			obj.run_search();
			createCookie('view_all_onload', 'true');//create a session cookie so all pages loads with view call
		};
		
		this.dropdown_select = function() {
			settings.cur_page = 1;
			obj.run_search();
		}
		
		var update_facet_dropdowns = function(facets) {
			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++) {
					
						var facet_name = facet_items[i].name;
						var top_text = facet_items[i].top_text;
						var current_val = $('#' + facet_items[i].name).val();
						var item_length = fields[facet_name].length;
						
						if ($('#' + facet_items[i].name).val() != '0') {
							top_text = 'Reset ' + top_text; 							
						}
					
						$('#' + facet_name).html('');
						$('#' + facet_name).append('<option value="0">' + top_text + '</option>');
						
						for (var j = 0; j < item_length; j++) {
							if (fields[facet_name][j+1] > 0) { //check count of facet
								var html_code = '<option value="' + fields[facet_name][j] + '"';
								if (fields[facet_name][j] == current_val) {
									html_code += ' selected';
								}
								html_code += '>' + fields[facet_name][j].toUpperCase() + '</option>'
								$('#' + facet_name).append(html_code);
							}
							j++; // skip over the "count" of products per each item in facet
						}
					}				
				}
			}
		}
		
		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;
					
					// clear out specific facet insert_in
					for (var i = 0; i < f_length; i++) {
						if (obj.isdefined(facet_items[i].insert_in)) {
							$(facet_items[i].insert_in).html('');
						}
					}
					
					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;
							
							//Only show facet with filter options
							if (fields[facet_name][1] > 0) {
								if (obj.isdefined(facet_items[i].insert_in)) {
									$(facet_items[i].insert_in).html('<select id="' + facet_name + '" size="1" class="dd_select"></select>');
								} else {
									$(settings.facets_to).append('<select id="' + facet_name + '" size="1" class="dd_select"></select>');
								}
								$('#' + facet_name).append('<option value="0">' + facet_items[i].top_text + '</option>');
								
								var counter = 0;
								var facetArrayValue = new Array();
                                for (var j = 0; j < item_length; j++) {
                                	if (fields[facet_name][j+1] > 0) { //check count of facet
                                		facetArrayValue[counter] = fields[facet_name][j].toUpperCase();
                                		counter++;
                                	}
                                	j++; // skip over the "count" of products per each item in facet
                                }

                                var facetPriority = null;
                                if(facetPriorityArray != null) {
	                                $.each(facetPriorityArray, function(k, v) {
	                                	if(k == facet_name) {
	                                		facetPriority = v;
	                                	}
	                                });
                                }
	                                
                                if(facetPriority != null) {
                                	facetArrayValue.sort(function(a,b) {
                                		var indexA = facetPriority.indexOf("'" + a + "'");
                                		var indexB = facetPriority.indexOf("'" + b + "'");
                                		return indexA - indexB;
                                	})
                                }

                                $.each(facetArrayValue, function(index, value) {
                                	var html_code = '<option value="' + value.toLowerCase() + '"';
                                	if(facet_name == 'facet_size') {
                                		html_code += '>' + value.toUpperCase().replace("K", "") + '</option>'
                                	} else {
                                		html_code += '>' + value.toUpperCase() + '</option>'
                                	}
                                	$('#' + facet_name).append(html_code);
                                });
							}
						}
					}				
				}
			}
			
			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++) {
					if (obj.isdefined(facet_items[i].insert_in)) {
						$(facet_items[i].insert_in).html('');
					}
				}
				for (var i = 0; i < f_length; i++) {
					var facet_name = facet_items[i].name;
					// For some reason, KR's jNice requires the onchange attribute to be printed out as is, it won't work with $('.dd_select').change(obj.dropdown_select);
					if (obj.isdefined(facet_items[i].insert_in)) {
						$(facet_items[i].insert_in).append('<select id="' + facet_name + '" class="dd_select select" onchange="solrsearch.dropdown_select()"></select>');
					} else {
						$(settings.facets_to).append('<select id="' + facet_name + '" class="dd_select select" onchange="solrsearch.dropdown_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.toUpperCase() + '</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" onchange="solrsearch.dropdown_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 (settings.show_sort_by.items.length > 0) {
				var sort_items = settings.show_sort_by.items;
				var s_length = sort_items.length;
				
				for (var i = 0; i < s_length; i++) {
					if (obj.isdefined(sort_items[i].show_in)) {
						$(sort_items[i].show_in).html('');
					}
				}
				
				for (var i = 0; i < s_length; i++) {
					var sort_name = sort_items[i].name;
					if (sort_items[i].type == 'dd') {
						$(sort_items[i].show_in).append('<select id="' + sort_name + '" size="1" class="spec_select"></select>');
						if (obj.isdefined(sort_items[i].top_text)) {
							$('#' + sort_name).append('<option value="' + sort_items[i].top_value + '">' + sort_items[i].top_text + '</option>');
						}
						$.each(sort_items[i].ops, function(key,value) {
							$('#' + sort_name).append('<option value="' + value + '">' + key + '</option>');
						});
					}
					if (sort_items[i].type == 'check') {
						$(sort_items[i].show_in).append('<input type="checkbox" class="spec_select" id="' + sort_items[i].name + '" name="' + sort_items[i].name + '" value="' + sort_items[i].top_value + '"> <label for="' + sort_items[i].name + '" class="opt">' + sort_items[i].top_text + '</label>');
					}
				}
			}
			
			/*plug in doesn't have filter built in, hard code this for now*/
			$('#days_created_range').html('');
			$('#days_created_range').append('<input type="checkbox" value="true" id="days_created" class="spec_select"/><label class="opt" for="days_created">NEW</label>');
			
			/*
			$('.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 gd = jQuery.cookie("gd");
			
		var getSpecialOutput = function(match, item){
			var output = '';
			if(match == 'holder_list_price'){
				if(item.price && item.list_price && item.price != item.list_price){
					output = '<span class="item-sale-price">(was '+obj.format_price(item.list_price)+')</span>';
				}
			}else if(match == 'holder_discounted_price'){
				if(gd && jQuery('.dprice').length == 0) {
					var dprice = (item.price * ((100- gd) / 100));
					//output = '<span itemprop="price" class="item-price-amount">'+obj.format_price(dprice)+'</span>';
					
					output = '<span class="item-discounted-price">'+obj.format_price(dprice)+'</span>';
				}
			}else if(match == 'holder_price_line_through'){
				if(!gd){
					output = 'style="text-decoration: none;"';
					//output = 'style="color: #EC008C;"';
				}
			}else if(match == 'holder_artist_link'){
				var link='';
				if(item.artist_status == 'live'){
					if(!isStaticLinking){
						link = item.dynamic_artist_url;
					}else{
						link = '/'+item.static_artist_url;
					}
					output = '<a href="'+link+'">'+item.brand+'</a>';
				}else{
					output = item.brand;
				}
				
			}else if(match == 'holder_artist_color'){
				if(item.artist_status == 'live'){
					output = '';
				}else{
					output = 'style="color:#5F6062"';
				}
			}
			return output;
		};
		
		var get_product_node_html = function(item) {			
			var html_code = template_str;		
			var output;				
			for (var i = 0; i < num_matches; i++) {
				if(matches[i].indexOf('holder_') == 0){
					output = getSpecialOutput(matches[i], item);
				}else{
					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]]);
					}
					
					if(typeof(output) == 'undefined' || output == 'undefined'){
						output = '';
					}
				}
				html_code = html_code.replace('${'+matches[i]+'}',output);
			}

			return html_code;
		};
		
		var build_query = function(filter_query, rt_fields, facet_name) {
			if (obj.isdefined(settings.show_per_page.show_in) && $('#per_page_select').length > 0) {
				settings.per_page = $('#per_page_select').val();
			}
			
			settings.offset = (settings.cur_page - 1) * settings.per_page;
			
			var query = settings.query_url;			
			
			query += '&start=' + settings.offset + '&rows=' + settings.per_page;
			
			var empty_search = true;
			query += '&q=';
			
			if(filter_query != ''){
				query += filter_query;
			}else{
				query += '*:*';
			}
			
			/*
			if(settings.query != ''){
				query += settings.query;
			}else{
				query += '*:*';
			}
			
			$.each(settings.query, function(key,value) {
				if(value.toString().indexOf('^') > -1){
					query += '+'+key + ':"' +escape(value.substring(0,value.toString().indexOf('^')))+'"'+escape(value.substring(value.toString().indexOf('^')));
					//query += '+'+key + ':"' + escape(value) + '"';
					//query += '+'+key + ':' + escape(value);
				}else if(value.toString().charAt(0) == '(' && value.toString().charAt(value.toString().length - 1) == ')'){
					query += '+%2B' + key + ':' + escape(value);
				} else if (value.toString().indexOf('|') > -1) {
					query += '+%2B' + '(';
					var search_options = value.split('|');
					for (var so_cnt = 0; so_cnt < search_options.length; so_cnt ++) {
						query += (so_cnt > 0 ? '+OR+' : '') + key + ':"' + escape(search_options[so_cnt]) + '"';
					}
					query += ')';
				} else {
					query += '+%2B' + key + ':"' + escape(value) + '"';
				}
				empty_search = false;
			});	
			
			if (empty_search) {
				query += '*:*';
			}*/
			
			/*
			var new_sort = '';
			if (settings.reset_facet_dd != 1) {
				$('.dd_select').each(function() {
					if ($(this).val() != '0') {
						query += '+%2B' + $(this).attr('id') + ':"' + escape($(this).val()) + '"';
						empty_search = false;
					}
				});		
				if ($('#facet_size').length>0 && $('#facet_width').length>0 && $('#facet_size').val() != '0' && $('#facet_width').val() != '0'){
					// get size_width, replace space with \+, size_with starts with 'sw'
					// size_width value looks like: sw 9.5_b / medium, 10_b / medium, ......
					// var piece looks like sw*10_b\+/\+medium*
					var size_width = escape($('#facet_size').val().replace(/ /g, '\\+')+'_'+$('#facet_width').val().replace(/ /g, '\\+'));
					var piece = '+%2B' + 'size_width:sw*' + size_width + '*';
					query += piece;
				}
				
				if (settings.show_sort_by.items.length > 0) {
					var sort_items = settings.show_sort_by.items;
					var s_length = sort_items.length;
					
					for (var i = 0; i < s_length; i++) {
						if ($('#' + sort_items[i].name).length > 0) {
							if (sort_items[i].type == 'dd' && $('#' + sort_items[i].name).val().length > 0) {
								new_sort += $('#' + sort_items[i].name).val() + ',';
							}
							if (sort_items[i].type == 'check' && $('#' + sort_items[i].name).is(':checked')) {
								new_sort += $('#' + sort_items[i].name).val() + ',';
							}
						}
					}
					
					new_sort = new_sort.substring(0,new_sort.length-1);
				}
				if ($('#days_created').attr("checked") == true){
					query += '+%2B' + 'days_created:[0 TO 30]';
				}
			}
			
			if (new_sort.length > 0) {
				settings.query_sort = new_sort;
			}*/
			
			if (settings.query_sort.length > 0) {
				query += '&sort=' + settings.query_sort;
			}
			
			if(facet_name){
				query += '&facet=true&facet.field=' + facet_name;
			}else 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(rt_fields){
				query += '&fl=' + rt_fields;
			}else 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 = 4, print_end = true;
				
				page_code += '<ul class="filter-pagination">';
			
				if(settings.cur_page > 2) {
					page_code += '<li><a href="#" class="paging_link" id="pl_1">1</a></li>';
					
					if(settings.cur_page - 2 > 1) {
						page_code +=  '<li class="ellipsis">...</li>';
					}

					count_start = settings.cur_page - 1;
					count_end = settings.cur_page + 2;
					
					if(count_end > settings.total_pages) {
						count_end = settings.total_pages;
					}
					
				} else if(count_end > settings.total_pages) {
					
					count_end = settings.total_pages;
				}
				
				for (var i = count_start; i <= count_end; i++) {
					
					if (i == settings.cur_page) {
						page_code += '<li class="active">';
					} else if (i <= settings.total_pages) {
						page_code += '<li class="paging_link" id="pl_' + i + '">';
					}
					/*
					if (i == count_start && i >= 3) {
						page_code += '<li class="last '+activeClass+'">';
					} else { 
						page_code += '<li class="'+activeClass+'">';
					}*/
					
					page_code += '<a href="javascript:void(0)">' + i + '</a></li> ';
					/*
					if (i == settings.cur_page) {
						page_code += '<a href="#">' + i + '</a></li> ';
					} else if (i <= settings.total_pages) {
						page_code += '<a href="#" class="paging_link" id="pl_' + i + '">' + i + '</a></li> ';
					}*/
				}
				
				if(count_end < settings.total_pages) {
					
					if(settings.cur_page + 3 < settings.total_pages) {
						page_code +=  '<li class="ellipsis">...</li>';
					}
					page_code += '<li class="paging_link" id="pl_' + settings.total_pages + '">';
/*
					if(count_end != (settings.total_pages - 1)) {
						page_code += '<li class="last">';
					} else {
						page_code += '<li>';
					}*/
					page_code += '<a href="javascript:void(0)">' + settings.total_pages + '</a></li> ';
				}
				
				page_code += '</ul>';

				if (settings.total_pages > 1 && settings.view_all_code.length > 0) {
					page_code += ' | <a href="#" class="view-all">' + settings.view_all_code + '</a>';
				}
			}
			
			$(settings.paging_to).html(page_code);
			
			$('.paging_link').click(function(e) {
				e.preventDefault();
				var page_num = $(this).attr('id').split('_');
				if(typeof search_page != "undefined" && search_page) {
					_gaq.push(['_trackEvent', 'Search', 'Page', page_num[1]]);
				}
				obj.go_to_page(page_num[1]);
			});
			
			$('.view-all').click(function(e) {
				e.preventDefault();
				obj.view_all();
			});
		}
		
		this.getQueryUrl = function(){
			return settings.query_url;
		};
		
		this.sort = function(sortBy){
			settings.query_sort = sortBy;
			cur_page = 1;
			obj.run_search();
		};
		
		this.getSortBy = function(){
			return settings.query_sort;
		};
		
		this.searchByQuery = function(theQuery){
			settings.query = theQuery;
			obj.run_search();
		};
		
		this.queryAndUpdateCount = function(filter_query, facet_name){

			$.getJSON(build_query(filter_query, 'id', facet_name),
				function(data) {
					if (data.response.numFound > 0) {
						
						krFilter.updateFacetCountsBy(data.facet_counts, facet_name);
						
					} 				
				});
		}
   };

   $.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);
