/*
 * Resource : /javascript/global/search/search.controller.js
 */



	(function()
	{
			  
		// global variables
			  
		var 
			query               = "",
			selectionIndex	    = -1,
			contacts			= {},
			contactsNum			= -1,
			suggestions         = [],
			hideClassName       = 'hidden',
			profileCoreUrl		= "/profile/",
			offLineMode		    = true,
			myTimeout           = "undefined"
		;
		
		// helpers
		
		
		
		function selectSuggestion(direction)
		{
				var ul                      = $('suggestionsList');
				var ulChild                 = ul.childElements();
				var numberLi                = ulChild.length;
				
				var 
					selectionLimit	 		= numberLi - 1,
					selectedMemberId 		= null	
				;
				
				selectionIndex   = parseInt(selectionIndex + direction, 10);
				
					if      ( selectionIndex < 0)                    { selectionIndex = 0; }/* Over the top limit */
					else if ( selectionIndex > selectionLimit)       { selectionIndex = selectionLimit;}  /* Over the bottom limit */
					else    { document.fire('ctrl:selectSuggestion', { index : selectionIndex});}
	
		}
		
		// Returns contacts full list. Query matching will be handled by suggestion module
		// along with string formatting.
		function fillContactsList(contacts, query)
		{
			currentSuggestions = [];
			
			for(var i=0; i<contacts.length; i++){
				currentSuggestions.push(contacts[i]);
			}
				
			return currentSuggestions;
		}
		

		function nativeSubmit()
		{
			if (!query.empty())
			{ 
				if (selectionIndex>-1)
				{
					var memberId = $('suggestionsList').down('li.selected').readAttribute('rel');
					  
					window.location = profileCoreUrl + memberId;
				}
				else { document.fire('ctrl:nativeSubmit'); }
			}
			document.fire('ctrl:closeSuggestions');
		}
		
		function escapeApp()
		{
			selectionIndex = -1;
			document.fire('ctrl:closeSuggestions');
		}

		// custom events listeners
		
		document
			.observe('ui:searchField:typing', function(event)
			{
				query 			= event.memo.value;
				withoutSuggestions = event.memo.withoutSuggestions;
				selectionIndex 	= -1;
				
				var callback = function()
				{
					if (!query.empty() && withoutSuggestions == false) // withoutSuggestions for AB testing
					{  
						// Get contacts list to send to suggestion module
						suggestions = fillContactsList(contacts, query);
						if (suggestions.length > 0 && !query.empty())
						{
							document.fire('ctrl:updateSuggestions', { suggestions : suggestions, query : query }); 
						}
						else { document.fire('ctrl:closeSuggestions'); }
					}
					else { document.fire('ctrl:closeSuggestions'); }
				}

				
				if(offLineMode == false && !query.empty() && withoutSuggestions == false){
					var request = function(){
						new Ajax.Request('/r/contacts/proposal', {
							parameters : {prefix: query},
							onSuccess : function(response)
							{
								var jsonResponse = response.responseJSON;
								contacts 	     = jsonResponse.contacts;
								contactsNum      = jsonResponse.nb;
								callback();	
							}
						});
					}
				} 
				else { document.fire('ctrl:closeSuggestions'); }
				
				

			var createTimeout = function()
			{
       			myTimeout = window.setTimeout(request, 300);
    		}

    		var destroyTimeout = function ()
			{
        		if (typeof myTimeout != "undefined") { window.clearTimeout(myTimeout); }
   			}


			if (offLineMode == true) { callback(); }
			else {
					destroyTimeout();
					createTimeout();
			}
		})
		.observe('ui:searchField:selectDown', function(){ selectSuggestion(1); })
		.observe('ui:searchField:selectUp'  , function(){ selectSuggestion(-1); })
		.observe('ui:searchField:escape', function(){ escapeApp(); })
		.observe('ui:wrapper:escape', function(){ escapeApp(); })
		.observe('ui:searchField:submit', function(event) { nativeSubmit();})
		.observe('ui:nativeSubmitSearch:submit',function(event){ nativeSubmit();})
		.observe('ui:suggestions:submit', function(event)
		{
			window.location = profileCoreUrl + event.memo.memberId;	
			document.fire('ctrl:closeSuggestions');
		})
		.observe('ui:advancedSearch:submit',function()
		{
			var searchfieldValue = !query.empty() ? query : null;
			document.fire('ctrl:goToAdvSearch', { searchfieldValue : searchfieldValue });						   
		})
		.observe('ui:searchField:start', function(event)
		{
			var withoutSuggestions = event.memo.withoutSuggestions;
			// populate contact list informations
			if(contactsNum == -1 && withoutSuggestions == false){
					new Ajax.Request('/r/contacts/proposal', {
						parameters : {prefix: ''},
						onSuccess : function(response)
						{
							var jsonResponse = response.responseJSON;
							contacts 	     = jsonResponse.contacts;
							contactsNum      = jsonResponse.nb;
							
							if (contacts.length == 0 && contactsNum != 0 ){ offLineMode = false;}
						}
				}); 
			}

			// remove default values
			var query        = event.memo.value;
			var defaultValue = event.memo.defaultValue;

			if(query == defaultValue){ document.fire('ctrl:removeDefaultValue'); };
			query = "";
		})
		.observe('ui:searchField:leave', function(event)
		{								  
			defaultValue = event.memo.value;
			if(query == ""){ document.fire('ctrl:putDefaultValue', {defaultValue : defaultValue}); };
		})
		.observe('dom:loaded', function()
		{
			document.fire('ctrl:putDefaultValue');
		})
	;
	Event.observe(window, 'unload', function()
	{
		document.fire('ctrl:removeDefaultValue');	
		document.fire('ctrl:clearAdvSearchValue');
	});
	
}());
/*
 * Resource : /javascript/global/search/searchField.module.js
 */


	// module-searchField
	
	(function(){
	
		// dom mapping
		
		var	module = $('module-searchField') || false;
		if (typeof module == "undefined" || !module)
		{
			return false;
		}
		var searchField = module.down("input");
		if (typeof searchField == "undefined" || !searchField)
		{
			return false;
		}
		
		var 
			defaultValue          = searchField.value,
			withoutSuggestions    = module.hasClassName('without_suggestions')  // for AB testing
		;
			
		// native listeners
			searchField
				.observe('focus', callbackFocus)
				.observe('blur', callbackBlur)
				.observe('keyup', callbackKeyup)
			;
			module.observe('submit', callbackSubmit);
			
		// custom events reporting
		
			function getFieldValue(){ return searchField.value; }
			
			function callbackFocus(){ document.fire('ui:searchField:start', { value : getFieldValue(), defaultValue : defaultValue, withoutSuggestions : withoutSuggestions });  }
			
			function callbackBlur() { document.fire('ui:searchField:leave', { defaultValue : defaultValue });  }
			
			function callbackSubmit(event)
			{
				event.preventDefault();
				document.fire('ui:searchField:submit');
			}
			
			function callbackKeyup(event){
				
				switch (event.keyCode)
				{
					case Event.KEY_DOWN : 
						document.fire('ui:searchField:selectDown');
						break;
						
					case Event.KEY_UP :
						document.fire('ui:searchField:selectUp');
						break;
						
					case Event.KEY_RIGHT :
						break;
						
					case Event.KEY_LEFT	:
						break;
						
					case Event.KEY_RETURN :
						break;
						
					case Event.KEY_ESC :
						document.fire('ui:searchField:escape');
						break;
						
					default :
						// FIXME : lorsque l'on appuie sur "enter" et quon le surseur est sur une suggestion
						// on ne devrait pas valider le formulaire de recherche
						// mais aller vers le lien de la suggestion
						// FIXME : vérifier que getFieldValue fonctionne
						document.fire('ui:searchField:typing', {value : getFieldValue(), withoutSuggestions : withoutSuggestions});
						break;
				}
			}
			
		// custom events listener

		document
			.observe('ctrl:nativeSubmit', function()
			{
				module.stopObserving('submit');
				module.submit();
			})
			.observe('ctrl:removeDefaultValue', function()
			{	
				searchField.value = "";
				searchField.removeClassName('default');
			})
			.observe('ctrl:putDefaultValue', function(event)
			{
				searchField.value = defaultValue;
				searchField.addClassName('default');
		});	
		
	}());
/*
 * Resource : /javascript/global/search/autosuggest.module.js
 */


	(function(){
			  
		var nodeId = $('autosuggest');
	
		if(nodeId){
			var node = "autosuggest";
			nodeId.observe('click', function(event){
				if((typeof event.findElement("#" + node) == "undefined") ? true : false) {document.fire("ui:wrapper:escape");}
			});
		}
	}());
/*
 * Resource : /javascript/global/search/click.module.js
 */


	(function(){
	
		document.observe('mouseup', function(event){
			var
				target 		= event.findElement('#autosuggest'),
			 	isOutSide 	= (typeof event.findElement('#autosuggest') == "undefined") ? true : false
			;
			if(isOutSide) {document.fire("ui:wrapper:escape");}
		});
	
	}());


/*
 * Resource : /javascript/global/search/nativeSubmitSearch.module.js
 */


	(function(){
			  
		// dom mapping
		
			var module = $('module-nativeSubmitSearch');
			if(typeof module == "undefined" || !module)
			{
				return false;
			}
			module.observe('click', function(){document.fire('ui:nativeSubmitSearch:submit')});
	}());
/*
 * Resource : /javascript/global/search/submitAdvancedSearch.module.js
 */


	(function(){
			  
		// dom mapping
		
			var module = $('module-submitAdvancedSearch');
			if(typeof module == "undefined" || !module)
			{
				return false;
			}
			var	field  = module.down('input');
			if(typeof field == "undefined" || !field)
			{
				return false;
			}
		
			field.value = "";
		
			module.observe('click', function(event){
				Event.stop(event);							 
				document.fire('ui:advancedSearch:submit');
			});
			document
				.observe('ctrl:goToAdvSearch',function(event){
					searchfieldValue = event.memo.searchfieldValue;
					if(searchfieldValue != null) {field.value = searchfieldValue;}
					module.submit();
				})
				.observe('clearAdvSearchValue',function(){
					field.value = "";
				})
	}());
/*
 * Resource : /javascript/global/search/suggestions.module.js
 */


	(function(){
			  
		// dom mapping
		var module = $('module-suggestions');
		if(typeof module == "undefined" || !module)
		{
			return false;
		}
			var
				list	            = module.down("ul"),
				hideClassName       = "hidden", 
				maxLength	        = 5,  // maximum number of suggestions displayed
				text                = module.down("p"),
				suggestionPattern 	= module.down("textarea").value,
				suggestionTemplate 	= new Template(suggestionPattern),
				timestamp			= (new Date()).getTime()
			;
		// native listeners
		list.observe("mouseup", function(event){
									
			var memberId = event.findElement(".contact").getAttribute("rel");
			if (typeof memberId != "undefined") {
			document.fire("ui:suggestions:submit", {memberId : memberId});
			}
		});
		// custom events listener
		
		document
			.observe('ctrl:updateSuggestions', updateSuggestions.bind(this))
			.observe('ctrl:closeSuggestions', closeSuggestions.bind(this))
			.observe('ctrl:selectSuggestion', selectSuggestion.bind(this))
		;
		
		// methods
		
		function updateSuggestions(event){
			
			var 
				suggestions 		    = event.memo.suggestions,
				suggestionsLength 	    = suggestions.length,
				validSuggestionsCounter = 0,
				suggestionsIndex 	    = 0,
				maxSuggestionsLength    = (suggestionsLength > maxLength) ? maxLength : suggestionsLength,
				query 				    = event.memo.query,
				html 				    = "",
				maxCarac				= 18
			;
			
			closeSuggestions();
			
			while (validSuggestionsCounter < maxLength && suggestionsIndex < suggestionsLength)
			{
				var htmlFullName = highlightSuggestions(query, (suggestions[suggestionsIndex].fullName), maxCarac);
				
				
				
				
				if (htmlFullName != null)
				{
					
					if((suggestions[suggestionsIndex].fullName).length > maxCarac) { htmlFullName += "..."; }
					
					if((suggestions[suggestionsIndex].headline).length > maxCarac) { 
						suggestions[suggestionsIndex].headline = suggestions[suggestionsIndex].headline.substr(0,maxCarac)+ "...";
					}
					
					// To show suggestions header
					module.removeClassName(hideClassName);
				
					html += suggestionTemplate.evaluate({
						memberId 	: suggestions[suggestionsIndex].memberId,
						fullName 	: htmlFullName,
						headline	: (suggestions[suggestionsIndex].headline),
						timestamp 	: timestamp
					});
															
					validSuggestionsCounter++;
				}
				suggestionsIndex++;
			}
	
			list.innerHTML = html;
			
			list.select("li").each(function(ele,index){				
				ele
					.observe('mouseenter', function(){
						if(currentLi){
							currentLi.removeClassName("selected");
						}
						this.addClassName('selected');
						currentLi = this;
					})
					.observe('mouseleave', function(){
						this.removeClassName('selected');
					});
			});
			
		}
		
		var currentLi = null;
		
		
		
		function selectSuggestion(event){
			var selectedIndex = event.memo.index;
			list.select('.contact').each(function(contact, index){
				contact[(index == selectedIndex) ? 'addClassName' : 'removeClassName']("selected");
				if(index == selectedIndex){
					currentLi =contact;
				}
			});
		}
		
		function closeSuggestions(){
			module.addClassName(hideClassName);
			list.update('');
		}
	
		// Process detailed string validation from query string. Returns index of found string
		function QueryMatchingString(query, stringToControl)
		{
			var
				normQuery					= normalizeString(query),
				normString					= normalizeString(stringToControl),
				foundIndex					= -1
			;

			if (normString.startsWith(normQuery)) { return 0; }
				
			foundIndex = normString.indexOf("_" + normQuery); // is it the beginning of a word? (the "_" is a " " or a "-" in the original string)
			
			if (foundIndex >= 0) {  return (foundIndex + 1); } // Shift 1 character to skip the "_" found in string 
			// String found nowhere => return -1
			return -1;
		}
			
		// Returns contact full name, formatted with query string in bold char.
		function highlightSuggestions(query, fullName, maxCarac)
		{
			var
				normQuery			= normalizeString(query),
				normName			= normalizeString(fullName),
				queryLen			= normQuery.length,
				queryIndex			= -1,
				left             	= fullName.length - queryIndex - queryLen
			;

			var fullNameCut = fullName.substr(0,maxCarac);
			
			// Control query corresponds to string. QueryMatchingString handles the main validation of string.
			queryIndex = QueryMatchingString(query, fullName);
			
			if (queryIndex >= 0 ){
				return fullNameCut.substr(0, queryIndex) +
				'<b>' + fullNameCut.substr(queryIndex, queryLen) + '</b>' +
				fullNameCut.substr(queryIndex + queryLen, left) ;
			}
			return null;
		}
		
		function normalizeString(s)
		{
			var r = s.toLowerCase();
			r = r.replace(new RegExp("( )", "g"),"_");     
			r = r.replace(new RegExp("(-)", "g"),"_");
			r = r.replace(/[\u0028\u0029\u0027]/g, "_"); // r = "(", ")", " ' "
			
			r = r.replace( new RegExp("\\s", "g"),"");
			r = r.replace(/[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5]/g, "a"); 
			r = r.replace(/[\u00e6]/g ,"ae");
			r = r.replace(/[\u00e7]/g ,"c");                         
			r = r.replace(/[\u00e8\u00e9\u00ea\u00eb]/g, "e");   
			r = r.replace(/[\u00ec\u00ed\u00ee\u00ef]/g, "i");
			r = r.replace(/[\u00f1]/g ,"n");                         
			r = r.replace(/[\u00f2\u00f3\u00f4\u00f5\u00f6]/g, "o");   
			r = r.replace(/[\u0153]/g ,"oe");
		    r = r.replace(/[\u00f9\u00fa\u00fb\u00fc]/g, "u");       
			r = r.replace(/[\u00fd\u00ff]/g, "y");  		 
			return r;
		}
		
		function normalizeArray(array){
			var normArray = [];
			for(var i = 0; i < array.length; i++){normArray[i] = normalizeString(array[i]);}
			return normArray;
		}
			 
	}())

