﻿/*
Script: TextboxList.Autocomplete.js
	TextboxList Autocomplete plugin

	Authors:
		Guillermo Rauch
	
	Note:
		TextboxList is not priceless for commercial use. See <http://devthought.com/projects/jquery/textboxlist/>
		Purchase to remove this message.
*/

(function(){
	
$.TextboxList.Autocomplete = function(textboxlist, _options){
	
  var index, prefix, method, container, list, values = [], searchValues = [], results = [], placeholder = false, current, currentInput, hidetimer, doAdd, currentSearch, currentRequest;
	var options = $.extend(true, {
		minLength: 1,
		maxResults: 10,
		insensitive: true,
		highlight: true,
		highlightSelector: null,
		mouseInteraction: true,
		onlyFromValues: false,
		queryRemote: false,
    remote: {
			url: '',
			param: 'search',
			extraParams: {},
			loadPlaceholder: 'Please wait...'
    },
		method: 'standard',
		placeholder: 'Type to receive suggestions'
	}, _options);
	
	var init = function(){
		textboxlist.addEvent('bitEditableAdd', setupBit)
			.addEvent('bitEditableFocus', search)
			.addEvent('bitEditableBlur', hide)
			.setOptions({bitsOptions: {editable: {addKeys: false, stopEnter: false}}});
		if ($.browser.msie) textboxlist.setOptions({bitsOptions: {editable: {addOnBlur: false}}});
		prefix = textboxlist.getOptions().prefix + '-autocomplete';
		method = $.TextboxList.Autocomplete.Methods[options.method];
		container = $('<div class="'+ prefix +'" />').width(textboxlist.getContainer().width()).appendTo(textboxlist.getContainer());
		if (chk(options.placeholder)) placeholder = $('<div class="'+ prefix +'-placeholder" />').html(options.placeholder).appendTo(container);		
		list = $('<ul class="'+ prefix +'-results" />').appendTo(container).click(function(ev){
			ev.stopPropagation(); ev.preventDefault();
		});
	};
	
	var setupBit = function(bit){
		bit.toElement().keydown(navigate).keyup(function(){ search(); });
	};
	
	var search = function(bit){
		if (bit) currentInput = bit;
		if (!options.queryRemote && !values.length) return;
		var search = $.trim(currentInput.getValue()[1]);
//		if (search.length < options.minLength) showPlaceholder();
		if (search == currentSearch) return;
		currentSearch = search;
		list.css('display', 'none');
		if (search.length < options.minLength) return;
		if (options.queryRemote){
			if (searchValues[search]){
				values = searchValues[search];
			} else {
				var data = options.remote.extraParams;
				data[options.remote.param] = search;
				if (currentRequest) currentRequest.abort();
				currentRequest = $.ajax({
					url: options.remote.url,
					data: data,
					dataType: 'json',
					success: function(r){
						searchValues[search] = r;
						values = r;
						showResults(search);
					}
				});
			}
		}
		showResults(search);
	};
	
	var showResults = function(search){
		var results = method.filter(values, search, options.insensitive, options.maxResults);
		if (textboxlist.getOptions().unique){
			results = $.grep(results, function(v){ return textboxlist.isDuplicate(v) == -1; });		
		}
		hidePlaceholder();
		//if (!results.length) return;
		/* added */
		if (!results.length){
			var jsobj = cvn.GetData();
			var core = ConvenoCore.prototype;
			var app_name = core.GetString( jsobj.app[ConvenoConst.APP.NAME_SID], jsobj.app[ConvenoConst.APP.NAME] );
			if(search != GetString("txtsearch")+' '+app_name) showPlaceholder();
			return;
		}
		
		blur();
		list.empty().css('display', 'block');
		$('<li><div id="search-result-wrapper"><ul></ul></div></li>').appendTo(list);
		$.each(results, function(i, r){ addResult(r, search); });
		
		if(totalResults>options.maxResults){
			//list.find('li div ul li').slice(10).addClass("hidden");
			if(showAll===true){
				list.find('li div').css({"height": "330px", "overflow-y": "hidden", "overflow-x": "hidden"});
				if($('#search-result-wrapper').length){
					//if(!(BrowserDetect.browser.toLowerCase()=="explorer" && parseInt(BrowserDetect.version)<=7)){
						$('#search-result-wrapper').jScrollPane({
							showArrows:true
							//,verticalDragMinHeight: 76
							//,verticalDragMaxHeight: 76
							//,horizontalDragMinWidth: 76
							//,horizontalDragMaxWidth: 76
						});
					//}
					
					if($.browser.msie){
						$('#search-result-wrapper').mousedown(function(ev){
							ev.stopPropagation();
							ev.preventDefault();
							clearTimeout(hidetimer);
							onMouseDown=true;
						});
						
						/*$('#search-result-wrapper').unbind("mousedown");
						$('#search-result-wrapper').bind("mousedown", function(ev){
							ev.stopPropagation(); 
							ev.preventDefault();
							clearTimeout(hidetimer);
							onMouseDown=true;
						});
						$('#search-result-wrapper').unbind("mouseup");
						$('#search-result-wrapper').bind("mouseup", function(ev){
							ev.stopPropagation(); 
							ev.preventDefault();
							$('.textboxlist input').focus();
						});
						
						/*$('#search-result-wrapper .jspVerticalBar').unbind("mouseleave");
						$('#search-result-wrapper .jspVerticalBar').bind("mouseleave", function(ev){
							ev.stopPropagation(); 
							ev.preventDefault();
							//$('.textboxlist input').focus();
						});*/
					}
				}
			} else {
				var show_all_el = $('<li id="show-all-results" class="textboxlist-autocomplete-result">'+GetString("txtshowallresults")+' &gt;&gt;</li>');
				show_all_el.insertAfter(list.find('li div ul li:eq('+(parseInt(options.maxResults)-1)+')'));
				
				if (options.mouseInteraction){
					show_all_el.css('cursor', 'pointer').hover(function(){ focus(show_all_el); }).mousedown(function(ev){
						ev.stopPropagation(); 
						ev.preventDefault();
						clearTimeout(hidetimer);
						onMouseDown=true;
						doAdd = true;
					}).mouseup(function(){
						if (doAdd){
							showAll = true;
							var search = $.trim(currentInput.getValue()[1]);
							showResults(search);
						}
					});
					if (!options.onlyFromValues) show_all_el.mouseleave(function(){ if (current && (current.get(0) == show_all_el.get(0))) blur(); });	
				}
			}
		}
		if (options.onlyFromValues) focusFirst();
		results = results;
	};
	
	var addResult = function(r, searched){
		var element = $('<li class="'+ prefix +'-result" />').html(r[3] ? r[3] : r[1]).data('textboxlist:auto:value', r);
		element.appendTo(list.find('li div ul'));
		if (options.highlight) $(options.highlightSelector ? element.find(options.highlightSelector) : element).each(function(){
			if ($(this).html()) method.highlight($(this), searched, options.insensitive, prefix + '-highlight');
		});
		if (options.mouseInteraction){
			element.css('cursor', 'pointer').hover(function(){ focus(element); }).mousedown(function(ev){
				ev.stopPropagation(); 
				ev.preventDefault();	
				clearTimeout(hidetimer);
				onMouseDown=true;
				doAdd = true;
			}).mouseup(function(){
				if (doAdd){
					addCurrent();
					currentInput.focus();
					search();
					doAdd = false;
				}
			});
			if (!options.onlyFromValues) element.mouseleave(function(){ if (current && (current.get(0) == element.get(0))) blur(); });	
		}
	};
	
	var hide = function(){
		hidetimer = setTimeout(function(){
			if(!onMouseDown){
				hidePlaceholder();
				list.css('display', 'none');
				currentSearch = null;
			} else {
				onMouseDown=false;
			}
		}, $.browser.msie ? 150 : 0);
	};
	
	var showPlaceholder = function(){
		if (placeholder) placeholder.css('display', 'block');		
	};
	
	var hidePlaceholder = function(){
		if (placeholder) placeholder.css('display', 'none');
	};
	
	var focus = function(element){
		if (!element || !element.length) return;
		blur();
		current = element.addClass(prefix + '-result-focus');
	};
	
	var blur = function(){
		if (current && current.length){
			current.removeClass(prefix + '-result-focus');
			current = null;
		}
	};
	
	var focusFirst = function(){
		return focus(list.find('li div ul li:first'));
	};
	
	var focusRelative = function(dir){
		if (!current || !current.length) return self;
		return focus(current[dir]());
	};
	
	var addCurrent = function(){
		if(!current) return false;
		
		var value = current.data('textboxlist:auto:value');
		if(value){
			var b = textboxlist.create('box', value.slice(0, 3));
			if (b){
				b.autoValue = value;
				if ($.isArray(index)) index.push(value);
				//currentInput.setValue([null, '', null]);
				currentInput.setValue([value.slice(1, 2), '', value.slice(1, 2)]);
				//b.inject(currentInput.toElement(), 'before');
				
				current_path_mode="std";
				if(typeof cvn!="undefined"){
					var item_type = value.slice(0, 1).join("").substring(0, 3).toUpperCase();
					var item_id = value.slice(0, 1).join("").substring(4);
					if(item_type=="CAT"){
						cvn.Display("ConvenoCategory", { cat_id: item_id }, current_caller);
						/*$("#tabs").tabs("select", 0);
						$(".Conveno_BtnMain1").removeClass("hidden");
						if(!$(".Conveno_ViewMenu").hasClass("hidden")){
							$("#Conveno_ViewBtn").addClass("Conveno_BtnOrdered").removeClass("Conveno_BtnList");
						}*/
					} else if(item_type=="PMK"){
						cvn.Display("ConvenoPlacemark", { pmk_id: item_id }, current_caller);
					}
				}
			}
			setTimeout(function(){ $('.textboxlist-autocomplete-results').css('display', 'none'); }, 10);
			blur();
		} else {
			showAll = true;
			var search = $.trim(currentInput.getValue()[1]);
			showResults(search);
			//$(".textboxlist-bit-editable-input").focus();
			//focusFirst();
		}
		return self;
	};
	
	var navigate = function(ev){
		var evStop = function(){ ev.stopPropagation(); ev.preventDefault(); };
		switch (ev.which){
			case 38:			
				evStop();
				(!options.onlyFromValues && current && current.get(0) === list.find('li div ul:first').get(0)) ? blur() : focusRelative('prev');
				break;
			case 40:			
				evStop();
				(current && current.length) ? focusRelative('next') : focusFirst();
				break;
			case 13:
				evStop();
				if (current && current.length) addCurrent();
				else if (!options.onlyFromValues){
					var value = currentInput.getValue();
					var b = textboxlist.create('box', value);
					if (b){
						//b.inject(currentInput.toElement(), 'before');
						//currentInput.setValue([null, '', null]);
						//alert(value);
						//submit form, show results box
						
						currentInput.setValue([value.slice(1, 2), '', value.slice(1, 2)]);
						current_path_mode="std";
						if(typeof cvn!="undefined"){
							var item_type = value.slice(0, 1).join("").substring(0, 3).toUpperCase();
							var item_id = value.slice(0, 1).join("").substring(4);
							if(item_type=="CAT"){
								cvn.Display("ConvenoCategory", { cat_id: item_id }, current_caller);
								/*$("#tabs").tabs("select", 0);
								$(".Conveno_BtnMain1").removeClass("hidden");
								if(!$(".Conveno_ViewMenu").hasClass("hidden")){
									$("#Conveno_ViewBtn").addClass("Conveno_BtnOrdered").removeClass("Conveno_BtnList");
								}*/
							} else if(item_type=="PMK"){
								cvn.Display("ConvenoPlacemark", { pmk_id: item_id }, current_caller);
							}
						}
					}
				}
		}
	};
	
	this.setValues = function(v){
		values = v;
	};
	
	init();
};

var onMouseDown=false;
var totalResults=0;
$.TextboxList.Autocomplete.Methods = {
	
	standard: {
		filter: function(values, search, insensitive, max){
			var newvals = [];
			//var regexp = new RegExp('\\b' + escapeRegExp(search), insensitive ? 'i' : '');
			if(search.length==1){
				var clang = ConvenoCore.prototype.GetLanguage();
				if (ConvenoPage.prototype.IsRomanized(clang)) {
					var regexp = new XRegExp('(?:\p{L}|\\b'+escapeRegExp(search)+')', insensitive ? 'i' : '');
				} else {
					var regexp = new XRegExp('(?:\p{L}|'+escapeRegExp(search)+')', insensitive ? 'i' : '');
				}
			} else {
				var regexp = new XRegExp('(?:\p{L}|'+escapeRegExp(search)+')', insensitive ? 'i' : '');
			}
			
			for (var i = 0; i < values.length; i++){
				//if (newvals.length === max) break;
				if (newvals.length === max && showAll === false) break;
				if (regexp.test(values[i][1])) newvals.push(values[i]);
			}
			
			totalResults=0;
			for (var i = 0; i < values.length; i++){
				if (regexp.test(values[i][1])) totalResults++;
			}
			return newvals;
		},
		
		highlight: function(element, search, insensitive, klass){
			//var regex = new RegExp('(<[^>]*>)|(\\b'+ escapeRegExp(search) +')', insensitive ? 'ig' : 'g');
			if(search.length==1){
				var clang = ConvenoCore.prototype.GetLanguage();
				if (ConvenoPage.prototype.IsRomanized(clang)) {
					var regex = new XRegExp('(<[^>]*>)|(?:\p{L}|\\b'+escapeRegExp(search)+')', insensitive ? 'ig' : 'g');
				} else {
					var regex = new XRegExp('(<[^>]*>)|(?:\p{L}|'+escapeRegExp(search)+')', insensitive ? 'ig' : 'g');
				}
			} else {
				var regex = new XRegExp('(<[^>]*>)|(?:\p{L}|'+escapeRegExp(search)+')', insensitive ? 'ig' : 'g');
			}
			
			//return element.html(element.html().replace(regex, function(a, b, c){
				//return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + c + '</strong>';
			return element.html(element.html().replace(/&amp;/g, '&').replace(regex, function(a, b, c){
				return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + a + '</strong>';
			}));
		}
	}
	
};

var chk = function(v){ return !!(v || v === 0); };
var escapeRegExp = function(str){ return str.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); };

})();
