//////////////////////////////////////////////////////////
///		GLOBAL DATA
//////////////////////////////////////////////////////////

var resetPromptKeyCodes = { 46:'Delete', 27:'Escape' }
var setPromptKeyCodes = { 13:'Enter' }
var conditionalPromptResetCodes = { 8:'BackSpace' }
var navigationKeyCodes = {	38:'KeyUp', 40:'KeyDown' 
							// 39:'KeyRight', 37:'KeyLeft'  - it seems there's no need to process these keys
						}
var ignoreKeys = { 39:'KeyRight', 37:'KeyLeft' }
var checkPreviousSymbolKeys = { 32:'Space' }

var promptItems = new Array();
var currentItemIndex = 0;
var storedSenderObj;

var adjustTextareaMenuPlacement = false;

var promptTypes = {'Tag':0, 'Organisation':1, 'EducationEstablishment':2, 'VacancyTag':5, 'SearchResume':6 };

var columnWidth = 8;
var rowHeight = 16;
var symbolHeight = 8;
var additionalOffset = 3;

var searchFocused;
//////////////////////////////////////////////////////////
///		EOF GLOBAL DATA
//////////////////////////////////////////////////////////

function filterKeys(sender, e){
	formatSenderValue(sender);
	var keyCode = getKeyCode(e);    

    //if(keyCode == 13 && !isMenuVisible() && searchFocused != undefined)
    //{
        //document.getElementById(searchFocused).click();
    //    return true;        
    //}
    

	if (navigationKeyCodes[keyCode])
		return !isMenuVisible();
	if (setPromptKeyCodes[keyCode])
		return false;
	if (checkPreviousSymbolKeys[keyCode]) {
		if (sender.value == "" || sender.value[sender.value.length - 1] == " ")
			return false;
	}
}

function processTagPrompt(sender, e){
	processPrompt(sender, e, promptTypes["Tag"]);
}

function processOrganisationPrompt(sender, e){
	processPrompt(sender, e, promptTypes["Organisation"]);
}

function processEducationEstablishmentPrompt(sender, e){	
	processPrompt(sender, e, promptTypes["EducationEstablishment"]);
}

function processVacancyTagPrompt(sender, e){
	processPrompt(sender, e, promptTypes["VacancyTag"]);
}


// main prompt menu function. smth like 'entry point'
function processPrompt(sender, e, promptType){
	var menu = getPromptMenu();
	var keyCode = getKeyCode(e);
	
	// check if need to be ignored
	if (ignoreKeys[keyCode]) {
		return;
	}
	
	// process reset keys
	if (isMenuVisible() && resetPromptKeyCodes[keyCode]){
		hidePromptMenu(menu);
		moveCursorToTheEndOfLine(sender);
		return;
	}
	
	// process menu navigation commands
	if (isMenuVisible() && navigationKeyCodes[keyCode]){
		processMenuNavigation(keyCode);
		moveCursorToTheEndOfLine(sender);
		return;
	}
	
	// process setting prompt item
	if (setPromptKeyCodes[keyCode] && isMenuVisible()){
		setPromptMenuItem(sender);
		moveCursorToTheEndOfLine(sender);
		return;
	}
	
	// update prompt menu items and reset if needed
	if (getLastWord(sender.value).length > 2){
		showPromptMenu(menu, sender, promptType);
	}
	else {
		hidePromptMenu(menu);
	}
	
	// TODO: check if the following code is necessary
	if (getLastWord(sender.value).length < 3 && conditionalPromptResetCodes[keyCode]){
		hidePromptMenu(menu);
	}
}

//////////////////////////////////////////////////////////
///		PROMPT MENU NAVIGATION METHODS
//////////////////////////////////////////////////////////

function processMenuNavigation(keyCode){
	switch(keyCode){
		case 38: // key up
			currentItemIndex = (currentItemIndex == 0) ? promptItems.length - 1 : currentItemIndex - 1;
			break;
		case 40: // key down
			currentItemIndex = (currentItemIndex == promptItems.length - 1) ? 0 : currentItemIndex + 1;
			break;
	}
	setCurrentItem();
}

function setPromptMenuItem(sender){
	var menu = getPromptMenu();
	var menuItemsArray = menu.getElementsByTagName("div");
	for (var i = 0; i < menuItemsArray.length; i++) {
		if (menuItemsArray[i].id == ("item_" + currentItemIndex)){
			sender.value = getUpdatedLastWord(sender.value, menuItemsArray[i].firstChild.nodeValue) + (sender.type == "textarea" ? ", " : "");
			break;
		}
	}
	hidePromptMenu(menu);
}

function setPromptMenuItemByClick(item){
	var itemText = item.firstChild.nodeValue;
	storedSenderObj.value = getUpdatedLastWord(storedSenderObj.value, itemText) + (storedSenderObj.type == "textarea" ? ", " : "");
	hidePromptMenu(getPromptMenu());
	storedSenderObj.focus();
}

function mouseChangeCurrentItem(item){
	var itemId = item.id;
	var itemIndex = Number(itemId.substr(5));
	currentItemIndex = itemIndex;
	setCurrentItem();
}

//////////////////////////////////////////////////////////
///		EOF PROMPT MENU NAVIGATION METHODS
//////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////
///		PROMPT MENU HELPER METHODS
//////////////////////////////////////////////////////////
function getPromptMenu(){
	return document.getElementById("promptmenu");
}

function isMenuVisible(){
	return getPromptMenu().style.display == "block";
}

// asynchronious call of web service method
function populateMenuItems(currentValue, promptType){
    try
    {
	PromptTool.GetTagPromptItemsArray(currentValue, promptType, buildMenu);
	}
	catch(err)
    {
    
    }
}

function getUpdatedLastWord(currentString, itemValue){
	var lastWord = getLastWord(currentString);
	var replPattern = lastWord;
	return currentString.substr(0, currentString.lastIndexOf(lastWord)) + itemValue;
}

function getLastWord(str){
	var lastSpaceIndex = str.lastIndexOf(", ");
	if (lastSpaceIndex == -1)
		lastSpaceIndex = 0;
	return str.substr(lastSpaceIndex + (lastSpaceIndex == 0 ? 0 : 2));
}

function setCurrentItem(){
	var menu = getPromptMenu();
	var menuItemsArray = menu.getElementsByTagName("div");
	for (var i = 0; i < menuItemsArray.length; i++){
		if (menuItemsArray[i].id == ("item_" + currentItemIndex))
			menuItemsArray[i].className = "currentItem";
		else if (menuItemsArray[i].id.indexOf("item_") != -1)
			menuItemsArray[i].className = "item";
	}
}

// callback function to bind menu div
function buildMenu(result){
	var menu = getPromptMenu();
	clearPromptMenu(menu);
	var menuContent = document.createElement("div");
	menuContent.id = "menuItemsContainer";
	menuContent.style.paddingTop = menuContent.style.paddingBottom = "4px";

	promptItems = result;
	
	// do not show menu if there are no items
	if (promptItems.length == 0 || (promptItems.length == 1 && promptItems[0].length  < 2))
		hidePromptMenu(getPromptMenu());		
	else
		getPromptMenu().style.display = "block";
		
	for (var i=0; i<promptItems.length; i++) {
		menuContent.appendChild(createMenuItem(i));
	}
	menu.appendChild(menuContent);
}

// clears menu data
function clearPromptMenu(menu){
	var menuContent = document.getElementById("menuItemsContainer");
	if (menuContent) 
		menu.removeChild(menuContent);
}

function formatSenderValue(sender){
	if (sender.type == "textarea") {
		var currentValue = sender.value;
		var regexp = new RegExp("\\s*,\\s*");
		sender.value = currentValue.replace(/\s*,\s*/g, ", ");
	}
}

// create single menu item to be added into menu content div
function createMenuItem(itemIndex){
	var menuItem = document.createElement("div");
	var menuItemText = document.createTextNode(promptItems[itemIndex]);
	menuItem.appendChild(menuItemText);
	menuItem.id = "item_" + itemIndex;
	menuItem.className = (itemIndex == currentItemIndex) ? "currentItem" : "item";
	menuItem.onclick = new Function ("setPromptMenuItemByClick(this)");
	menuItem.onmouseover = new Function ("mouseChangeCurrentItem(this)");
	menuItem.style.marginLeft = menuItem.style.marginRight = "4px";
	return menuItem;
}

function showPromptMenu(menu, sender, promptType){
	storedSenderObj = sender;
	//menu.style.display = "block";
	populateMenuItems(getLastWord(sender.value), promptType); //(sender.value);
	setPromptMenuPosition(menu, sender);
}

function hidePromptMenu(menu){
	currentItemIndex = 0;
	menu.style.display = "none";
}

function getKeyCode(e){
	var keyId = (window.event) ? event.keyCode : e.which;
	return keyId;
}

// sets menu div position according sender input control
function setPromptMenuPosition(menu, sender){
    var senderPos = getSenderPosition(sender);
    var senderSize = getSenderSize(sender);

	if (sender.type == "text") {
		menu.style.top = senderPos[0] + senderSize[0] + "px";
		menu.style.left = senderPos[1] + "px"; // + senderSize[1];
		menu.style.width = senderSize[1] + "px";
	}
	if (sender.type == "textarea") {
		var rowsColsArray = new Array();
		rowsColsArray = getCursorRowColumnPos(sender);
		//menu.style.top = senderPos[0] + Math.round(0.25*senderSize[0])*Number(adjustTextareaMenuPlacement) + "px";
		//menu.style.left = senderPos[1] + Math.round(0.2*senderSize[1])*Number(adjustTextareaMenuPlacement) + senderSize[1]*Number((!adjustTextareaMenuPlacement)) + "px";
		menu.style.top = senderPos[0] + rowHeight*(rowsColsArray[0] + 1) + "px";
		menu.style.left = senderPos[1] + columnWidth*(rowsColsArray[1] - 4) - additionalOffset + "px";
		menu.style.width = "155px"; //(694 - senderSize[1]) + "px";
	}
}

function getSenderPosition(sender){
	var currentLeft = currentTop = 0;
	if (sender.offsetParent) {
		do {
			currentLeft += sender.offsetLeft;
			currentTop += sender.offsetTop;
		} while (sender = sender.offsetParent);
	}
	return new Array(currentTop, currentLeft);
}

function getSenderSize(sender){
	var height = width = 0;
	height = sender.offsetHeight;
	width = sender.offsetWidth;

	return new Array(height, width);
}

//////////////////////////////////////////////////////////
///		EOF PROMPT MENU HELPER METHODS
//////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////
///		TEXTAREA HELPER METHODS
//////////////////////////////////////////////////////////

function moveCursorToTheEndOfLine(sender){
	setCaretPosition(sender, sender.value.length);
}

function setCaretPosition(sender, caretPos) {
    var elem = sender;

    if(elem != null) {
        if(elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if(elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}

function getCurrentCursorPosition(textarea){
	// for normal browsers
	if (typeof(textarea.selectionStart) == 'number') {
		return textarea.selectionStart;
	}
	// IE workaround
	else if(document.selection){
		var selection_range = document.selection.createRange().duplicate();

		if (selection_range.parentElement() == textarea) { // Check that the selection is actually in our textarea
			// Create three ranges, one containing all the text before the selection,
			// one containing all the text in the selection (this already exists), and one containing all
			// the text after the selection.
			var before_range = document.body.createTextRange();
			before_range.moveToElementText(textarea); // Selects all the text
			before_range.setEndPoint("EndToStart", selection_range); // Moves the end where we need it

			var after_range = document.body.createTextRange();
			after_range.moveToElementText(textarea); // Selects all the text
			after_range.setEndPoint("StartToEnd", selection_range); // Moves the start where we need it

			var before_finished = false, selection_finished = false, after_finished = false;
			var before_text, untrimmed_before_text, selection_text, untrimmed_selection_text, after_text, untrimmed_after_text;

			// Load the text values we need to compare
			before_text = untrimmed_before_text = before_range.text;
			selection_text = untrimmed_selection_text = selection_range.text;
			after_text = untrimmed_after_text = after_range.text;

			// Check each range for trimmed newlines by shrinking the range by 1 character and seeing
			// if the text property has changed. If it has not changed then we know that IE has trimmed
			// a \r\n from the end.
			do {
				if (!before_finished) {
					if (before_range.compareEndPoints("StartToEnd", before_range) == 0) {
						before_finished = true;
					} else {
						before_range.moveEnd("character", -1)
						if (before_range.text == before_text) {
							untrimmed_before_text += "\r\n";
						} else {
							before_finished = true;
						}
					}
				}
				if (!selection_finished) {
					if (selection_range.compareEndPoints("StartToEnd", selection_range) == 0) {
						selection_finished = true;
					} else {
						selection_range.moveEnd("character", -1)
						if (selection_range.text == selection_text) {
							untrimmed_selection_text += "\r\n";
						} else {
							selection_finished = true;
						}
					}
				}
				if (!after_finished) {
					if (after_range.compareEndPoints("StartToEnd", after_range) == 0) {
						after_finished = true;
					} else {
						after_range.moveEnd("character", -1)
						if (after_range.text == after_text) {
							untrimmed_after_text += "\r\n";
						} else {
							after_finished = true;
						}
					}
				}

			} while ((!before_finished || !selection_finished || !after_finished));

			// Untrimmed success test to make sure our results match what is actually in the textarea
			// This can be removed once you’re confident it’s working correctly
			var untrimmed_text = untrimmed_before_text + untrimmed_selection_text + untrimmed_after_text;
			var untrimmed_successful = false;
			if (textarea.value == untrimmed_text) {
				untrimmed_successful = true;
			}
			// ** END Untrimmed success test

			var startPoint = untrimmed_before_text.length;
			return startPoint;
		}
	}
}

function getCursorRowColumnPos(textarea){
	var debugOut = document.getElementById("debug_out");
	var currentLinearPos = getCurrentCursorPosition(textarea);
	//debugOut.value = currentLinearPos;
	
	var rows = 9; // textarea.rows;
	var cols = 74; // textarea.cols;
	
	var rowsCounter = 0;
	var colsCounter = 0;
	
	//var currentWord = getLastWord(textarea.value);
	var prefixString = textarea.value; //textarea.value.replace(currentWord, "");
	//if (prefixString.length > cols) {
		var prefixWordsArray = prefixString.split(" ");
		for (var i = 0; i < prefixWordsArray.length; i++) {
			colsCounter += prefixWordsArray[i].length + (i == 0 ? 0 : 1);
			if (colsCounter > cols){
				colsCounter = prefixWordsArray[i].length;
				if (rowsCounter < 5) rowsCounter++;
			}
		}
	//}
	//debugOut.value += " / " + rowsCounter + ":" + colsCounter;
	return new Array(rowsCounter, colsCounter);
}

//////////////////////////////////////////////////////////
///		EOF TEXTAREA HELPER METHODS
//////////////////////////////////////////////////////////
