$(document).ready(function(){
	$("#promo_code").focus(function(e){
		if($(this).val() == 'ENTER'){
			$(this).val('');
		}
	});
	
	$("#promo_code").keypress(function(e){
		if(e.which == 13){
			$(this).attr('disabled','disabled');
			
			$.getJSON("/controller.php",
				{"controller":"promos","action":"validate_code","promo_code":$(this).val()},
				function(data){
					$("#promo_code").attr('disabled',false);

					if(data.error){
						alert(data.error_message);
						$("#promo_code").focus();
					}else if(data.success){
						alert(data.success_message);
						window.location.reload(true);
					}
				}
			);
		}
	});
});

/*----------------------------------------------------------------------------
 * jQuery HashSlice
 * ---------------------------------------------------------------------------
 * jQuery:  1.2.x compatible
 * Keyword: hashslice, hash slice, hash to array
 *
 * Author:  Stephen Blum
 * Twitter: stephenlb
 *
 * GitHub:  git://github.com/stephenlb/jquery-hashslice.git
 *
 * Files:   jquery.hashslice.js      ## Source
 *          jquery.hashslice.min.js  ## Minified hashslice JS lib
 *          jquery.hashslice.test.js ## Tests and Example Usage
 *          minify.pl                ## Perl JS Minifier 
 *                                   ## ./minify.pl code.js > min.js
 *
 * Summary: The great and first Hash slice JavaScript implementation. A hash
 *          is also an Object, the two are interchangeable. This hashslice
 *          method allows quick syntax for grabbing an array of hash elements.
 *          Also, as in Perl, hashslice can be used to join new elements
 *          between two hashes. Perl provides a much preferred interface to
 *          hash slicing.
 * 
 * ---------------------------------------------------------------------------
 * USAGE TYPE 1: Single string with whitespace delimiters. **** FAVORITE ****
 * ---------------------------------------------------------------------------
 * var list = $.hashslice( hash, 'apples berries pies' );
 *
 * ---------------------------------------------------------------------------
 * USAGE TYPE 2: Single string with multiple delimiters.
 * ---------------------------------------------------------------------------
 * var list = $.hashslice( hash, 'apples, berries, pies' );
 * var list = $.hashslice( hash, 'apples | berries | pies' );
 *
 * ---------------------------------------------------------------------------
 * USAGE TYPE 3: Array argument.
 * ---------------------------------------------------------------------------
 * var list = $.hashslice( hash, ['apples', 'berries', 'pies'] );
 *
 * ---------------------------------------------------------------------------
 * USAGE TYPE 4: Hash Augmentation / Update.
 * ---------------------------------------------------------------------------
 * $.hashslice( hash, 'sans salts', { sans : 'fluffy', salts : 'white' } );
 *
 * ---------------------------------------------------------------------------
 * EXAMPLE 1: Using favorite method shown in Usage Type 1.
 * ---------------------------------------------------------------------------
 * var hash = {
 *         candy   : 'okay',
 *         apples  : 2,
 *         berries : 'yes',
 *         pies    : 'flavor',
 *         sand    : { bead : [5, 2] }
 *     };
 *
 * var list = $.hashslice( hash, 'apples berries pies' );
 *
 * ---------------------------------------------------------------------------
 * EXAMPLE 2: Hashslicing inward to add new elements or update old ones.
 * ---------------------------------------------------------------------------
 * var hash = {
 *         candy   : 'okay',
 *         apples  : 2,
 *     },
 *     update = {
 *         candy : 'merged',
 *         canes : 'yes'
 *     };
 *
 * //           hash <------<------< update (leftward merge)
 * $.hashslice( hash, 'candy canes', update );
 *
 * hash.candy == 'merged'; // true
 * hash.canes == 'yes';    // true
 *
 *----------------------------------------------------------------------------
 */
// jQuery.hashSlice = function( hash, elements, update ) {
//     var list = jQuery.extend( true, [], update || hash ), // deep copy
//         elms = typeof elements === 'string' ?             // is str list?
//                elements.
//                replace(/^\W+|\W+$/g, '').                 // trim
//                split(/\W+/) :                             // arrayify
//                elements;                                  // else default
// 
//     jQuery.each( elms, function(elm) {                    // itterate
//         var e = elms[elm];
//         if (update) hash[e] = list[e] || list[elm];       // slice in
//         else if(list[e])       list.push(list[e]);                   // slice out
//     } );
// 
//     return update ? hash : list;                          // return in or out
// };
// 
// /* return the keys of a hash as an array */
// jQuery.hashKeys = function(hash){
// 	var r = [];
// 	jQuery.each(hash, function(k){ r.push(k); });
// 	return r;
// }
// 
// /* return the properties that exist in both hashes */
// jQuery.hashOverlap = function(hash1, hash2){
// 	return $.hashSlice(hash1, $.hashKeys(hash2));
// }
// 
// /* return the properties from h2 that are not found in h1 */
// jQuery.hashDiff = function(h1, h2){
// 	var r = {};
// 	
// 	tryNext:
// 	for(var k1 in h1){
// 		for(var k2 in h2){
// 			if(h2[k2] === h1[k1]){
// 				continue tryNext;
// 			}
// 		}
// 		r[k1] = h1[k1];
// 	}
// 	return r;
// }
// 
// /* returns all of the items from a2 that are not found in a1 */
// jQuery.arrayDiff = function(a1, a2){
// 	var r = [];
// 	
// 	tryNext:
// 	for(var k1 in a1){
// 		for(var k2 in a2){
// 			if(a2[k2] === a1[k1]){
// 				continue tryNext;
// 			}
// 		}
// 		r.push(a1[k1]);
// 	}
// 	return r;
// }

function filterParts(){
	var current = getFilterHash();
	
	$.each(filter['parts2attributes'], function(part_id, part){
		if(partPassesFilter(current, part)){
			$('#'+part_id).show();
			$('#'+part_id).parent().parent().show();
		}else{
			$('#'+part_id).hide();
			
			/* This hides the part group table if all of the parts within are hidden. There might be a way to optomize this */
			if($('#'+part_id).siblings().filter('.filter_parts:hidden').length == $('#'+part_id).siblings().filter('.filter_parts').length){
				$('#'+part_id).parent().parent().hide();
			}
		}
	});
	
	
	var dontDisableThese = {};
	
	/* Now do whatif's on all of the unchecked checkboxes. */
	var unchecked = $("#filter .filter_eq").not(':checked');
	unchecked.map(function(){
		/* create a copy of the current filter */
		whatIf = $.extend(true, {}, current);
		/* Now modify it so that the current unchecked box is included */
		var attribute_id = $(this).parent().parent().attr('id');
		if(!whatIf['eq'].hasOwnProperty(attribute_id)) whatIf['eq'][attribute_id] = {};
		whatIf['eq'][attribute_id][$(this).val()] = $(this).val();
		
		var numberOfPartsToHide = 0;
		var totalNumberOfParts = $('.filter_parts').length;
		
		for(var part_id in filter['parts2attributes']){
			var part = filter['parts2attributes'][part_id];
			var partWouldNotHide = partPassesFilter(whatIf, part);
			
			if(!partWouldNotHide) numberOfPartsToHide++;
			
			if($('#'+part_id).is(':visible') != partWouldNotHide){
				dontDisableThese[this.id] = this.id;
			}
			
			if(numberOfPartsToHide == totalNumberOfParts){
				delete dontDisableThese[this.id];
			}
		}
	});
	
	/* disable all the checkboxes */
	$("#filter .filter_eq").not(':checked').parent().addClass('disabled');
	
	/* enable all the ones that will cause the product list to change */
	$.each(dontDisableThese, function(av){
		$('#'+av).parent().removeClass('disabled');
	});
	
	/* Restripe the part rows */
	$(".filter_parts:visible").each(function(i, row){
		i%2 ? $(row).removeClass('odd') : $(row).addClass('odd');
	});
}

function getFilterHash(){
	/* There are three types of filter attributes:
	eq = the part attribute is a string and must be equal to the selected checkbox
	in = the part attribute is an array and the value of the checkbox must be in it
	between = the part attribute is a numeric range and the filter has a min / max text box to specify the filter range */
	var r = {eq: {}, 'in': {}, between: {}};
	
	$("#filter .filter_eq:checked").map(function(){
		/* The UL's id is the attribute ID */
		var attribute_id = $(this).parent().parent().attr('id');
		
		/* */
		if(!r['eq'].hasOwnProperty(attribute_id)) r['eq'][attribute_id] = {};
		
		r['eq'][attribute_id][$(this).val()] = $(this).val();
	});
	
	$("#filter .filter_between").each(function(i, ul){
		r['between'][i] = {'min':{'value':null,'attribute_id':null}, 'max':{'value':null,'attribute_id':null}};
		
		$(".filter_min", ul).each(function(j, test){
			r['between'][i]['min']['attribute_id'] = test.id;
			r['between'][i]['min']['value'] = $(test).val() === '' || isNaN($(test).val()) ? null : $(test).val();
		});
		
		$(".filter_max", ul).each(function(j, test){
			r['between'][i]['max']['attribute_id'] = test.id;
			r['between'][i]['max']['value'] = $(test).val() === '' || isNaN($(test).val()) ? null : $(test).val();
		});
	});

	// console.log(r);
	// console.log('-');

	return r;
}

function partPassesFilter(filter, part){
	/* Check against the equals portion of the filter */
	for(var attribute_id in filter['eq']){
		if(!filter['eq'][attribute_id].hasOwnProperty(part[attribute_id])){
			return false;
		}
	}
	
	/* Check against the between portion of the filter. */
	for(var i in filter['between']){
		var part_min_value = part[filter['between'][i]['min'].attribute_id];
		var min_value = filter['between'][i]['min'].value;
		var part_max_value = part[filter['between'][i]['max'].attribute_id];
		var max_value = filter['between'][i]['max'].value;
		
		/* if we're comparing two different attribute ids (such as min wind and max wind) then its range */
		if(filter['between'][i]['min'].attribute_id != filter['between'][i]['max'].attribute_id){
			/* if a min value is set in the filter and is numeric */
			if(min_value != null){
				/* if the part's attribute is NaN or is greater than the min_value, return false */
				if(part_min_value === '' || isNaN(part_min_value) || parseInt(part_min_value) > parseInt(min_value) || parseInt(part_max_value) < parseInt(min_value)) return false;
			}
		
			/* if a max value is set in the filter and is numeric */
			if(max_value != null){
				/* if the part's attribute is NaN or is greater than the min_value, return false */
				if(part_max_value === '' || isNaN(part_max_value) || parseInt(part_max_value) < parseInt(max_value) || parseInt(part_min_value) > parseInt(max_value)) return false;
			}
		}else{
			/* otherwise just do a normal comparison */
			if(min_value != null){
				/* if the part's attribute is NaN or is greater than the min_value, return false */
				if(part_min_value === '' || isNaN(part_min_value) || parseInt(part_min_value) < parseInt(min_value)) return false;
			}
		
			/* if a max value is set in the filter and is numeric */
			if(max_value != null){
				/* if the part's attribute is NaN or is greater than the min_value, return false */
				if(part_max_value === '' || isNaN(part_max_value) || parseInt(part_max_value) > parseInt(max_value)) return false;
			}
			
		}
	}
	return true;
}