// requires jquery,cursorManager
// expects global field variable to set to the focused field
	
function isKeyCodeLetter(keyCode){return keyCode>=65 && keyCode<=90;}
function isLetter(str){return str.match(/^[a-zA-Z]$/);}	

var cursorPositionObjBeforeAutoCompleteSelectorShown;
var autocompleteSelector;
var commonFunctionNames=[];

$(document).ready(
	function(){
		// START: prepare autocomplete functions:
			for(i=0;i<commonFunctions.length;i++){
				commonFunctionNames.push( commonFunctions[i].replace(/\W.*/,'') );
			}
		// END: prepare autocomplete functions:
		
		
		
		$('.richCodeEditor').mouseup(
			function(){
				hideAndDestroyAutoCompleteSelector();
			}
		);	
		
		$('.richCodeEditor').keydown(
			function(e){
				var keyCode = e.keyCode ? e.keyCode : e.which;
				if(keyCode==40){ // arrow keys (only down arrow)			
					if(autocompleteSelector!=null){
						autocompleteSelector.lastChild.focus();
					}
					return;
				}
			}
		);
		
		$('.richCodeEditor').keyup(
			function(e){
				hideAndDestroyAutoCompleteSelector();
				var keyCode = e.keyCode ? e.keyCode : e.which;
				// harf veya ctrl-space
				if(isKeyCodeLetter(keyCode)){ //|| (e.ctrlKey && e.keyCode==32)  ctrl'den keyup'da ustteki hidedestroy calisiyor: bir ise yaramiyor
					var strNearCursor = getStringNearCursor(-1,1); // from cursorManager
					var letterBeforeCursor=strNearCursor.charAt(0);
					var characterAfterCursor = strNearCursor.charAt(1);
					if(isLetter(letterBeforeCursor) && !isLetter(characterAfterCursor)){
						createAndShowAutoCompleteSelector();
					}
				}
			}
		);
		
		// sets the global field variable to current active field:
		// eases autocomplete popups to insert text
		// can this be done some other way???
		$('.richCodeEditor').focus(
			function(){
				field=this;
			}
		);
	}		
);
	
var field;

	
// works with ff? not tested:
// hem word'leri hem de fonksiyonlari autocomplete ediyor!!!
function autoCompleteWords(){
	var text=removeStringsCommentsChars(field.innerText);
	// start with reserved words:
	words = reservedWords;
	
	// add functions as:  sum(a,b)
	var functions = text.match( /\w+\s+\w+\([^)"]*\)/g) || [];
	var functionNames=[];
	for(i=0;i<functions.length;i++){
		// convert int sum(int a,int b) to sum(int a,int b)
		functions[i]=functions[i].replace(/^(\w+\s+)*/,'');
		functionNames.push(''+functions[i].match(/^\w+/));
		// convert sum(int a,int b) to sum(a,b):
		// handles sum(struct ff a,enum ff b) also:
		//functions[i]=functions[i].replace(/(\w+\s+)*(\w+)/g,'$2'); : handles arrays also:
		//functions[i]=functions[i].replace(/(\w+\s+)*(\w+)(\[\d*\])*/g,'$2'); : handle pointers
		//functions[i]=functions[i].replace(/(\w+\s+)*\**\s*(\w+)(\[\d*\])*/g,'$2');
		functions[i]=functions[i].replace(/(\w+[\s\*]+)*(\w+)(\[\d*\])*/g,'$2');
	}
	//alert(functions);
	//alert(functionNames);
	
	// TODO: add math.h functions if math.h included??
	// TODO: add stdlib.h functions if stdlib.h included??
	// TODO: add file functions? 
	
	// add words appearing within the code:
	var wordsInText = text.match(/\w+/g);
	words = words.concat(wordsInText);
	words = words.concat(functions);
	words = words.concat(commonFunctions);		
	// remove function names from the list
	words = words.arrayDiff(functionNames);
	words = words.arrayDiff(commonFunctionNames);
	// remove duplicates:
	words = words.unique();
	//sort in ascending order
	words.sort();		
	return words;
}


// not ff compatible:
function createAndShowAutoCompleteSelector(){
	cursorPositionObjBeforeAutoCompleteSelectorShown=getCursorPositionObj();
	var autoCompleteSelectorHtml = autoCompleteSelectorCreator(wordBeforeCursor() /*from cursorManager*/);
	if(autoCompleteSelectorHtml==null || autoCompleteSelectorHtml=='') return;
	
	var cursorPosObj = getCursorPositionObj();
	var cursorLeft = cursorPosObj.cursorLeft;
	var cursorTop = cursorPosObj.cursorTop;
	autocompleteSelector = document.createElement("div");
	// put a close button:
	//autocompleteSelector.innerHTML=closeButton;
	// put selector:
	autocompleteSelector.field=field; // DONE: global field objesi set edilsin!!! -> focus hangisinde ise!! onfocus!!
	
	autocompleteSelector.innerHTML=autoCompleteSelectorHtml;
	autocompleteSelector.style.backgroundColor='white';
	autocompleteSelector.style.border='1px solid black';
	autocompleteSelector.style.position='absolute';
	autocompleteSelector.style.z_index='1';
	autocompleteSelector.style.top = (cursorTop+24+document.body.scrollTop)+"px";
	autocompleteSelector.style.left = (cursorLeft+document.body.scrollLeft)+"px";
	//autocompleteSelector.style.opacity=0.5; //mozilla opera etc
	//autocompleteSelector.style.filter='alpha(opacity=50)';
	document.body.appendChild(autocompleteSelector);
	// help manager:
	activateHelps(); // activates the help on autocomplete selector
	//bindAutoCompleterSelectObjectKeydown(); // kotu performans??
}

function hideAndDestroyAutoCompleteSelector(){
	if(autocompleteSelector!=null){
		document.body.removeChild(autocompleteSelector);
		autocompleteSelector=null;
	}
}
	
/*
function bindAutoCompleterSelectObjectKeydown(){
	// actually there is only one autoCompleterSelectObject, but still given as class
	// for... dunno:)
	$('.autoCompleterSelectObject').keydown(
		function(e){
			var keyCode = e.keyCode ? e.keyCode : e.which;
			var selectObj=this;
			
			if(keyCode==27){ // esc is pressed:
				hideAndDestroyAutoCompleteSelector();
				loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);
				return;
			}
			
			if(isKeyCodeLetter(keyCode)){
				hideAndDestroyAutoCompleteSelector();
				loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);			
				createAndShowAutoCompleteSelector();
			}
			
			if(keyCode==13){ //just works when enter is pressed			
				e.preventDefault();// jquery handles ie version: e.returnValue=false
				autoCompleteWord(selectObj);
			}
		}
	);
}*/

// TODO: not firefox compatible, fix later
function autocompleteSelectorOnKeyDown(selectObj){
	var e=window.event; 
	
	if(e.keyCode==27){ // esc is pressed:
		hideAndDestroyAutoCompleteSelector();
		field.cursorManager.loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);
		return
	}
	
	if(isKeyCodeLetter(e.keyCode)){
		hideAndDestroyAutoCompleteSelector();
		field.cursorManager.loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);
		//field.cursorManager.loadCursor();
		createAndShowAutoCompleteSelector()
	}
	
	if(e.keyCode==13){ //just works when enter is pressed
		//alert(13);
		//field.cursorManager.saveCursor();
		e.returnValue=false;
		/*var text = selectObj.value;
		// daghan: added newly:
		hideAndDestroyAutoCompleteSelector();
		//field.cursorManager.loadCursor();
		field.cursorManager.loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);
		field.cursorManager.insertBeforeCursor(text);*/
		this.autoCompleteWord(selectObj);
	}
}


function autoCompleteWord(selectObj){
	var text = selectObj.value;
	// daghan: added newly:
	hideAndDestroyAutoCompleteSelector();
	//field.cursorManager.loadCursor();
	loadCursorPositionObj(cursorPositionObjBeforeAutoCompleteSelectorShown);
	insertBeforeCursor(text);
}

	
	
// also removes repetitions:)  // private function, not used anywhere else
function autoCompleteWordPicker(wordBeforeCursor){
	var result=[];
	var words=autoCompleteWords();
	for(i=0;i<words.length;i++){
		var word = words[i] || '';
		if( word.match( new RegExp('^'+wordBeforeCursor+'.+')  ) ){
			var textOfOption = word;
			var valueOfOption = word.replace( new RegExp('^'+wordBeforeCursor),''  );	
			result[textOfOption]=valueOfOption;
		}
	}
	return result;
}

function autoCompleteSelectorCreator(wordBeforeCursor){
	var autoCompleteHash = autoCompleteWordPicker(wordBeforeCursor);
	var result='';
	var numOptions=0;		
	for (var textOfOption in autoCompleteHash) {
		if(typeof(autoCompleteHash[textOfOption])=='function') continue;
		result+='<option value=\''+autoCompleteHash[textOfOption]+'\'>'+textOfOption+'</option>';
		numOptions++;
	}
	if(numOptions==0) return null;
	result='<select ondblclick="autoCompleteWord(this)"  size="'+(numOptions+1)+'" class="autoCompleterSelectObject" onkeydown="autocompleteSelectorOnKeyDown(this)">'+result+'</select>';		
	result=				
				'<div class=help>'+
					'Welcome to autocomplete selector help.<br/>'+
					'When typing a word, if you type beginning<br/>'+
					'of an existing word or a common word/function<br/>'+
					'the autocomplete selector will appear. If you<br/>'+
					'press down arrow or click any word within the<br/>'+
					'list with mouse, you will enter the list.<br/>'+
					'You can select the desired word with up-down<br/>'+
					'arrow keys or by clicking by mouse. For inserting<br/>'+
					'the word, you must press enter.<br/>'+
					'Alternatively, you can double-click<br/>'+
					'the desired word with mouse for inserting it.<br/>'+
					'In order to close the autocomplete selector,<br/>'+
					'You can either press esc or click anywhere within<br/>'+
					'the source code by mouse'+
				'</div><br/>'+
			result;
	return result;
}
