/*
 * jQuery plugin: autoCompletefb(AutoComplete Facebook)
 * @requires jQuery v1.2.2 or later
 * using plugin:jquery.autocomplete.js
 *
 * Credits:
 * - Idea: Facebook
 * - Guillermo Rauch: Original MooTools script
 * - InteRiders <http://interiders.com/> 
 *
 * Copyright (c) 2008 Widi Harsojo <wharsojo@gmail.com>, http://wharsojo.wordpress.com/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

var defaultEmails = '';
var autocompleteJSON = function(raw) {
	var json= typeof(raw) === "array" ? raw : raw.payload;
	var parsed = [];
	for (var i=0; i <json.length; i++) {
	   var row =json[i];
	   parsed.push(row);
	}
	return parsed;
}; 

var initAddressBookAC = function(containerIdentifier) {
var returnValue = jQuery(containerIdentifier).autoCompletefb({
		urlLookup:"/addressbook",
		fetchAllUpfront: true,
		hiddenInput: ".hidden-input",
		inLineTip: "",
		defaultEntries: defaultEmails,
		isValid: function (entry) {
			var emailRe = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/ ;
			return (emailRe.test(entry)) ;
		},
		acOptions: {
			multiple: true,
			multipleSeparator:",",
			matchContains: true,
			dataType: "json",
			parse: autocompleteJSON,
			formatResult: function(row) {return ((row.n && row.n.length>0)?row.n:row.e)},
			formatItem: function(row) {return row.e + (row.n ? ' ('+row.n+')' : '' )}
		}
	}) ;
return returnValue ;
};

 
jQuery.fn.autoCompletefb = function(options) 
{
	var tmp = this;
	var separatorRe = /[,; ]/g;
	var settings = 
	{
		ul         : tmp,
		urlLookup  : [""],
		acOptions  : {},
		foundClass : ".acfb-data",
		inputClass : ".acfb-input",
		hiddenInput: ".hidden-input",
		inLineTip	: "Separate each email address with a comma.",
		defaultEntries : [],
		fetchAllUpfront: false,
		isValid	:	function(entry) {return true ;}
	}
	if(options) jQuery.extend(settings, options);
	
	var acfb = 
	{
		params  : settings,
		getData : function()
		{	
			var result = '';
		    jQuery(settings.foundClass,tmp).each(function(i)
			{
				if (i>0)result+=',';
			    result += jQuery('.hiddenData',this).html();
		    });
			return result;
		},
		clearData : function()
		{	
		    jQuery(settings.foundClass,tmp).remove();
			jQuery(settings.inputClass,tmp).focus();
			return tmp.acfb;
		},
		removeFind : function(o){
			jQuery(o).unbind('click').parent().remove();
			jQuery(settings.inputClass,tmp).focus();
			return tmp.acfb;
		},
		setHiddenInput : function() {
			jQuery(settings.hiddenInput,tmp).get(0).value = acfb.getData();
		},
		setEntry: function(ObjectEntry) {
			if (ObjectEntry) {
				jQuery(settings.inputClass,tmp).trigger("result",[ObjectEntry]) ;
			}
		},
		cleanup: function() {
			jQuery(tmp)
				.find('li').remove().end()
				.find(settings.hiddenInput).val('').end()
				.find(settings.inputClass).val('') ;
		},
		showItems: function() {
			jQuery(tmp).find('li').show();
		},
		setFocus: function() {
			jQuery(settings.inputClass,tmp).focus();
		}
	}
	
	

	
//Define behavior when a new item (email) is added (to recipient list)
	jQuery(settings.inputClass,tmp).result(function(e,d,f){
		var f = settings.foundClass.replace(/\./,'');
		var formatFunc = settings.acOptions.formatResult ;
		var v = '<li class="'+f+'" style="display: none"><span>'+(formatFunc ? formatFunc(d) : d.e)+'</span> <span class="hiddenData">'+d.e+'</span><img class="p" src="/img/delete.gif"/></li>';
		var x = jQuery('ul',tmp).append(v);
		jQuery('.p',x[0]).click(function(){
			acfb.removeFind(this);
			acfb.setHiddenInput() ;
		});
		acfb.setHiddenInput() ;
		jQuery(settings.inputClass,tmp).val('').focus();
		setTimeout(acfb.showItems,300);
	});

//Define behavior for evaluating a text entry
	var tokenize = function(event,d,f){

		var tokens  = [] ;
		var residuals = [] ;
		var valids = [] ;
		if (event.target.value == event.target.title)
			return ;
		tokens = event.target.value.split(separatorRe) ;
		for (var c=0;c<tokens.length;c++)	{
			if (tokens[c].length>0){
				if (settings.isValid(tokens[c])) {
					valids.push({n: null,e: tokens[c]}) ;
				} else {
					residuals.push(tokens[c]) ;
				}
			}
		}
		if (valids.length>0)
			jQuery(event.target).trigger("result",valids) ;
		if (residuals.length>0)
			event.target.value = residuals.join(',');
		else 
			event.target.value = '' ;
	};

//Define inline tip behavior, look & feel
	jQuery(tmp).after('<div class="inputTip"><span>'+settings.inLineTip+'</span></div>');
	jQuery('div.inputTip',tmp).css('width',jQuery(tmp).css('width'));
	jQuery(settings.inputClass,tmp).bind('focus',function(event){jQuery(event.target).parents('form').children('div.inputTip').show()});
	jQuery(settings.inputClass,tmp).bind('blur',function(event){jQuery(event.target).parents('form').children('div.inputTip').hide()});
	
//Define addition behavior for the input box for handling free text entries
	if (!settings.acOptions.mustMatch) {
		var evalExtEntry = function (event) {
			//				debugger ;
			var KEY = {
				COMMA: 188,
				SEMICOLON: 59,
				SPACE: 32,
				ENTER: 13
			};
			var CHAR = {
				COMMA: 44,
				SEMICOLON: 59,
				SPACE: 32,
				ENTER: 13
			};

			switch(event.charCode || event.keyCode) {
				case CHAR.COMMA:
				case CHAR.SEMICOLON:
				case CHAR.SPACE:
				case CHAR.ENTER:
					jQuery(event.target).trigger('evaluate') ;
					var inStr = event.target.value;
					event.target.value=inStr.replace(/^ ;,/,'').replace(/ ;,$/,'') ;
					event.preventDefault() ;
				break;
				}
		}
		
		jQuery(settings.inputClass,tmp).bind('blur',tokenize);
		jQuery(settings.inputClass,tmp).bind('evaluate',tokenize);	
		jQuery(settings.inputClass,tmp).keypress(evalExtEntry);	
		jQuery(settings.inputClass,tmp).bind('change',function(event){event.target.value = event.target.value.replace(/^[ ,;]*/,'').replace(/[ ,;]*$/,'')});	
		jQuery(settings.inputClass,tmp).bind('keyup',function(event){event.target.value = event.target.value.replace(/^[ ,;]*/,'').replace(/[ ,;]*$/,'')});	
	}
	
//Define standard behavior	
	jQuery(settings.foundClass+" img.p").click(function(){
		acfb.removeFind(this);
		acfb.setHiddenInput() ;
	});
	
	if (settings.fetchAllUpfront && typeof settings.urlLookup == "string") {
		jQuery.getJSON(settings.urlLookup, function (data) {
				jQuery(settings.inputClass,tmp).autocomplete(settings.acOptions.parse(data),settings.acOptions);
			}) ;
	} else {
		jQuery(settings.inputClass,tmp).autocomplete(settings.urlLookup,settings.acOptions);
	}
	
		
	//set default values if passed with options
	for (var i=0;i<settings.defaultEntries.length;i++) {
		var emailEntry = jQuery.trim(settings.defaultEntries[i]) ;
		if (emailEntry.length>0)
			acfb.setEntry({n:"",e: emailEntry}) ;
	}
	return acfb;
}

