// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults



function wopen_restricted(url, name, w, h)
{
	// Fudge factors for window decoration space.
	// In my tests these work well on all platforms & browsers.
	w += 32;
	h += 96;
	var win = window.open(url,
						  name, 
						  'width=' + w + ', height=' + h + ', ' +
						  'location=no, menubar=no, ' +
						  'status=no, toolbar=no, scrollbars=no, resizable=yes');
	win.resizeTo(w, h);
	win.focus();
}

function wopen_normal(url, name, w, h)
{
	// Fudge factors for window decoration space.
	// In my tests these work well on all platforms & browsers.
	w += 32;
	h += 96;
	var win = window.open(url,
						  name, 
						  'width=' + w + ', height=' + h + ', ' +
						  'location=yes, menubar=yes, ' +
						  'status=yes, toolbar=yes, scrollbars=yes, resizable=yes');
	win.resizeTo(w, h);
	win.focus();
}

function killIt(e)
{
	
	if (e.keyCode == 13)
	{
		return false;
	}
	
	return true;
}

//
// See public/README_INGREDIENTS_ENCODED for explanation 
// on how and why we encode ingredient names.
//
// NOTE: the alphabet and key below MUST be the same accross
//       all the encoding routines (check in application.rb).
//
function pc_encode_js(message)
{
	var alphabet, key, encoded_ing, decoded_ing, i, ch, index;
	
	alphabet = "abcdefghijklmnopqrstuvwxyz1234567890%(),";
	key =      "(%09)87654321xzycb,gfedhijklnmopqrstvwua";
	encoded_ing = ""
		
		// encode the ingredient
		for (i = 0; i < message.length; i++) 
		{        
			ch = message.charAt(i);                   
			index = alphabet.indexOf(ch);             
			
			if (index == -1) 
				encoded_ing = encoded_ing + ch;                   
			else 
				encoded_ing = encoded_ing + key.charAt(index); 
		}
	
	return encoded_ing;
}

//
// See public/README_INGREDIENTS_ENCODED for explanation 
// on how and why we encode ingredient names.
//
// NOTE: the alphabet and key below MUST be the same accross
//       all the encoding routines (check in application.rb).
//
function pc_decode_js(message)
{
	var alphabet, key, decoded_ing, i, ch, index;
	
	alphabet = "abcdefghijklmnopqrstuvwxyz1234567890%(),";
	key =      "(%09)87654321xzycb,gfedhijklnmopqrstvwua";
	decoded_ing = ""
		
		// encode the ingredient
		for (i = 0; i < message.length; i++) 
		{        
			ch = message.charAt(i);                   
			index = key.indexOf(ch);             
			
			if (index == -1) 
				decoded_ing = decoded_ing + ch;                   
			else 
				decoded_ing = decoded_ing + alphabet.charAt(index); 
		}
	
	return decoded_ing;
}


function remove_dashes_and_commas(message)
{
	var result = ""
	
	for (i = 0; i < message.length; i++) 
	{        
		ch = message.charAt(i);                   
		
		if (ch == '-' || ch == ',')
			result = result + ' ';
		else
			result = result + ch;
	}	
	
	return result;
}

//
// Click on a td element and it will get strikedthrough. click again
// and the strike will disappear. Currently used in shopping list.
//
function strikeThroughInOut(elem) {
    var tds = elem.getElementsByTagName("td");
    for (var i=0; i<tds.length; i++) {
        tds[i].style.textDecoration = (tds[i].style.textDecoration == '')? 'line-through': '';
    }
}

// This is a modified version of the local array autocompleter from
// script.aculo.us in controls.js. We call it Autocompleter.Pepperclip
// instead of Autocompleter.Local in order to be able to distinguish
// between the two. In the recipe form we use this version (Pepperclip
// autocompleter). 
//
// The main differences between the 2 versions are:
//
// 1. This one receives encoded ingredients as options and it encodes
//    the user string with the same logic and compares them. Then it 
//    displays the matches after decoding them (for viewing).
//
// 2. This version is optimized for better performance.
// 3. If there are more results than displayed in the autocomplete box
//    this version will display a message saying that.
//
// For actual documentation on how to use the specific options see
// autocompleter.Local in controls.js (we don't want to duplicate it here).
//
Autocompleter.Pepperclip = Class.create();
Autocompleter.Pepperclip.prototype = Object.extend(new Autocompleter.Base(), {
initialize: function(element, update, array, options) {
    this.baseInitialize(element, update, options);
    this.options.array = array;
},

getUpdatedChoices: function() {
    this.updateChoices(this.options.selector(this));
},

setOptions: function(options) {
    this.options = Object.extend({
	choices: 10,
	partialSearch: true,
	partialChars: 1,
	ignoreCase: true,
	fullSearch: false,
	selector: function(instance) {
	var ret       = []; // all matches
		  
	//
	// Get the user's input string. Since the big ingredient option
	// array includes lowercased and encoded ingredients we lowercase
	// and encode our input string as well so that they will match.
	//
	// we also take the opportunity to replace all '-' and ',' characters
	// with a space char ' '. So that, for example, "all-purpose" will
	// still match "all purpose" since it will count as two words.
	//
	var input_string = pc_encode_js(remove_dashes_and_commas(instance.getToken().toLowerCase()));
	
	var count     = 0;
	
	// The input from the user (array of words)
	var input_words = new Array();
	input_words = input_string.split(' ');
	
	//startd = new Date()
	//starts = startd.getSeconds()
	//startm = startd.getMilliseconds()
	
	// The current ingredient we are examining
	var db_ingredient;	
	
	// Array of indexes of matches into each input word.
	// (parallels the input_words array in size)
	var foundPos = new Array();
	
	// # of input words that match an ingredient
	var matches = 0;
	var i = 0;
	
	// 
	// Loop through all the ingredients from the ingredient table 
	// and see which ones match our input. Add the ones that match
	// to the drop down list.
	//
	for (i = 0; i < instance.options.array.length &&  ret.length < instance.options.choices ; i++) 
	{ 
		db_ingredient = instance.options.array[i];
		
		matches = 0;
		
		// for each input word see if there is a match. if yes, increment the
		// 'match' counter and move on to the next input word (if user typed 
		// more than one word).
		for(var j = 0; j < input_words.length ; j++)
		{
			// is there a match in *any* location?
			foundPos[j] = db_ingredient.indexOf(input_words[j]);  
			
			// if there is a match, check to see that it is in a beginning of a word
			if(foundPos[j] != -1)
			{
				var success = false;
				// while we have a match
				while (foundPos[j] != -1) 
				{
					if (foundPos[j] != -1) 
					{
						// test that the match is in a *beginning of a word*
						if (foundPos[j] == 0 || /\s/.test(db_ingredient.substr(foundPos[j] - 1, 1)))
						{
							success = true;
							break;
						}
					}
					
					//if the match wasn't in the beginning of a word look for 
					//another match starting from the next character.
					foundPos[j] = db_ingredient.indexOf(input_words[j], foundPos[j] + 1);
				}
				
				if(success)
					matches++;
				else
					break; //this input word doen't match. get outa' here...
			}
			else
				break; //this input word doen't match. get outa' here...
		}
		
		// If 'match' counter equals total entries -- bingo! 
		// add this ingredient to the drop down list
		if(matches == input_words.length)
			ret.push("<li>" + pc_decode_js(db_ingredient) + "</li>"); 
	}
	
	//if user typed more than 2 letters, sort the result by string length
	//to allow for probable results to show up first in the list. Sort
	//may be expensive so we do it only after 2 chars, not before
	//if (input_string.length > 2)
	//{
	//	ret.sort(sortLength);			
	//}
		
	//If we broke out of the loop because we got enough
	//results - tell the user that there are more
	if(i != instance.options.array.length)
		ret.push("<li>--------<br /><strong>Not all results are displayed. Type more words to narrow your search</strong></li>");
				
	//return all the matches inside an HTML list as a string
	return "<ul>" + ret.join('') + "</ul>";
}
    }, options || {});
}
});

//
// After used finished typing an ingredient name, we make
// sure that this ingredient name exists in our database.
//
function checkIngredientIsValid(el, input, ing_array)
{
	encoded_ing = pc_encode_js(input.toLowerCase());
	
	for(var i = 0 ; i < ing_array.length ; i++)
	{
		if(encoded_ing == ing_array[i])
			return; //ingredient is valid. we're done.
	}
	
	//this ingredient doesn't match any ingredient from the database.
	el.value = ""			
}

// function checkIngredientIsValid(el, input, ing_array)
// {
// 	var encoded_ing = pc_encode_js(input.toLowerCase());
// 	var errdiv_style = document.getElementById('bad_ingredient_warning').style;
// 	
// 	for(var i = 0 ; i < ing_array.length ; i++)
// 	{
// 		if(encoded_ing == ing_array[i])
// 		{
// 			//ingredient is valid. hide the error div
// 			//if it is showing and return. we're done.
// 			errdiv_style.display = "none";
// 			return true; 
// 		}
// 			
// 	}
// 	
// 	// reveal the error div
// 	errdiv_style.display = "block";
// 	
// 	//this ingredient doesn't match any ingredient from the database.
// 	//el.style.color = 'red';
// 	el.value = ""
// 	return false;
// }

