var current_search_matches = {
	regex_match : Object(),
	regular_match : Object()
};

/**
* get near searched elements stored on current_search_matches
*
* @param string search_word
* @param boolean is_regex
* @return Object
*/
function getNearSearchedTarget(search_word, is_regex)
{
	// no key on current_search_matches
	if (search_word == '')
	{
		return null;
	}
	
	// remove last char (to find prev search)
	var subsearch_word = search_word.substr(0, search_word.length-1);
	if (current_search_matches.regex_match[subsearch_word] && is_regex)
	{
		return current_search_matches.regex_match[subsearch_word];
	}
	else if (current_search_matches.regular_match[subsearch_word])
	{
		return current_search_matches.regular_match[subsearch_word];
	}
	
	// recursive search
	return getNearSearchedTarget(subsearch_word, is_regex)
}

/**
* get match objects from search_target
*
* @param string search_word
* @param Object search_target
* @return Object
*/
function getMatchObjects(search_word, search_target)
{
	// nothing to search
	if (search_word == '')
	{
		return null;
	}
	
	// init values
	var matches = Object();
	search_word = search_word.toLowerCase();
	search_target_original = search_target;
	matches[search_word] = Array();
	var is_regex = true;
	var regex = new RegExp('^'+search_word);
	
	// existing keyword search_word matches
	if (current_search_matches.regex_match[search_word] && current_search_matches.regex_match[search_word].length > 0)
	{
		return current_search_matches.regex_match[search_word];
	}
	else if (current_search_matches.regular_match[search_word])
	{
		return current_search_matches.regular_match[search_word];
	}
	
	// check for near current_search_word_matches key to search_word in
	var near_searched_target = getNearSearchedTarget(search_word, is_regex);
	if (near_searched_target)
	{
		search_target = near_searched_target;
	}
	
	// iterate object for matches (regex)
	for (i in search_target)
	{
		if (search_target[i].ewire_name.toLowerCase().match(regex))
		{
			matches[search_word].push(search_target[i]);
		}
	}
	
	// if empty start match, search between words
	if (matches[search_word].length == 0)
	{
		is_regex = false;
		
		// check for near current_search_matches key to search_word in
		var near_searched_target = getNearSearchedTarget(search_word, is_regex);
		if (near_searched_target)
		{
			search_target = near_searched_target;
		}
		else
		{
			// if no nearkey in noreg history we use the initial search_target
			search_target = search_target_original;
		}
		
		// iterate object for matches (no regex)
		for (i in search_target)
		{
			if (search_target[i].ewire_name.toLowerCase().match(search_word))
			{
				matches[search_word].push(search_target[i]);
			}
		}
	}
	
	// add search_word key to current_search_matches
	if (is_regex && !current_search_matches.regex_match[search_word])
	{
		current_search_matches.regex_match[search_word] = matches[search_word];
	}
	else if (!current_search_matches.regular_match[search_word])
	{
		current_search_matches.regular_match[search_word] = matches[search_word];
	}
	
	// return matches
	return matches[search_word];
}

/**
* ewire search field keyup
*
* @param string search_word
* @param Object ewire_checkboxes
* @param Object search_target
* @return Object
*/
function ewireSearchOnKeyupHandler(search_word, ewire_checkboxes, search_target)
{
	var offset_top = -1 * ewire_checkboxes.position().top;
	
	if (search_word == '' || search_word == "Search")
	{
		// if empty search_word we remove highlight and we scroll to the first element
		var li_ewire = ewire_checkboxes.find('li:first');
		ewire_checkboxes.parent().scrollTop(li_ewire.position().top + offset_top);
		if (jQuery.fn.highlight)
		{
			ewire_checkboxes.removeHighlight();
		}
	}
	else
	{
		var match = getMatchObjects(search_word, search_target);
		if (match && match.length > 0)
		{
			var li_ewire = $('#li_ewire_checkboxes_' + match[0].ewire_id);
			
			// scroll to first match
			ewire_checkboxes.parent().scrollTop(li_ewire.position().top + offset_top);
			
			// remove previous highlights and we highlight the characters that it matches from current search_word
			if (jQuery.fn.highlight)
			{
				ewire_checkboxes.removeHighlight();
				li_ewire.find('label').highlight(search_word);
			}
		}
	}
}

/**
* get total checked ewires
*
* @return integer
*/
function getTotalCheckedEwires()
{
	return $('#ewire_checkboxes').find('input.checkbox:checked').length;
}

var prices = {};

/**
* ewire checkbox click event
*
* @param Object checkbox
* @param Object ewire_checkboxes
* @return Object
*/
function ewireOnClickHandler(checkbox, ewire_checkboxes)
{
	// validate "other" ewire
	if ($(checkbox).attr('id') != 'ewire_checkboxes_')
	{
		// hide - show, if exist extra data on page
		var ewire_id = $(checkbox).attr('id').match(/\d+/)[0];
		
		if ($(checkbox).is(':checked'))
		{
			if ($('#tr_quantity_'+ewire_id).length > 0)
			{
				// display existing fields
				$('#tr_quantity_'+ewire_id).show();
			}
			else
			{
				// create fields
				var default_quantity = 1000;
				
				var tr = $("#tr_quantity_"+ewire_id);
				if (!tr.length)
				{
					tr = '<tr id="tr_quantity_'+ewire_id+'">'+
									'<td axis="ewire" class="ewire">'+ewires[ewire_id].ewire_name+'</td>'+
									'<td axis="quantity" class="quantity">'+
										'<div class="container"><input type="text" class="text" id="quantity_'+ewire_id+'" name="quantity_'+ewire_id+'" value="'+default_quantity+'"/> x $0.25 = </div>'+
									'</td>'+
									'<td axis="price" class="price" id="price_'+ewire_id+'">$250.00</td>'+
								'</tr>';
					$('#ewires_extra table.extra').append(tr);
				}
				var quantity = $("#quantity_"+ewire_id);
				var price = $("#price_"+ewire_id);
				quantity.keyup(function(e){
						price.html("$" + (quantity.val() * 0.25).toFixed(2));
						updateTotals();
				});
				price.html("$" + (quantity.val() * 0.25).toFixed(2));
			}
		}
		else
		{
			// hide unchecked ewire extra data
			$('#tr_quantity_'+ewire_id).hide();
		}
		updateTotals();
	}
	
	var total_checked = getTotalCheckedEwires();
	if (total_checked > 0)
	{
		// show Selected Ewires container if at least one ewire is selected
		$('#ewires_extra').show();
	}
	else
	{
		$('#ewires_extra').hide();
	}
}

function updateTotals()
{
	var price = 0;
	var quantity = 0;
	var selectedCheckboxes = $("#ewire_checkboxes input:checked");
	selectedCheckboxes.each(function(index, element) {
			var ewire_id = $(element).attr('id').match(/\d+/)[0];
			price += $("#quantity_"+ewire_id).val() * 0.25;
			quantity += parseInt($("#quantity_"+ewire_id).val());
	});
	$("#total_price").html("$" + price.toFixed(2));
	$("#total_quantity").html(quantity);
}

/**
* "remove" link click event
*
* @param integer ewire_id
* @return false
*/
function removeEwireOnClickHandler(ewire_id)
{
	$('#ewire_checkboxes_'+ewire_id).attr('checked', false);
	$('#tr_quantity_'+ewire_id).hide();
	var total_checked = getTotalCheckedEwires();
	if (total_checked > 0)
	{
		// show Selected Ewires container if at least one ewire is selected
		$('#ewires_extra').show();
	}
	else
	{
		$('#ewires_extra').hide();
	}
	
	return false;
}

document.onready = function ()
{
	// checkboxes container
	var ewire_checkboxes = $('#ewire_checkboxes');
	var search_target = ewires;
	
	// search_word field
	$('#ewire_search').keyup(function(e){
		ewireSearchOnKeyupHandler(this.value, ewire_checkboxes, search_target);
	});
	if ($('#ewire_search').val() != '')
	{
		ewireSearchOnKeyupHandler($('#ewire_search').val(), ewire_checkboxes, search_target);
	}
	
	// ewire checkbox event
	ewire_checkboxes.find('input.checkbox').click(function(){
		ewireOnClickHandler(this, ewire_checkboxes);
	});
	ewire_checkboxes.find('input.checkbox').each(function(){
		ewireOnClickHandler(this, ewire_checkboxes);
	});
	
	// Link existing ewires
	$("#ewire_checkboxes input:checked").each(function(index, element) {
			var ewire_id = $(element).attr('id').match(/\d+/)[0];
			var quantity = $("#quantity_"+ewire_id);
			var price = $("#price_"+ewire_id);
			quantity.keyup(function(e){
					price.html("$" + (quantity.val() * 0.25).toFixed(2));
					updateTotals();
			});
			price.html("$" + (quantity.val() * 0.25).toFixed(2));
	});
	
}