﻿function SmartBox(inputID, hiddenID, optionsContainerID, optionsID, oUrl, listType, smartBoxType, langID) {
	function getOptions(keyword) {
		self.SelectedOptionIndex = -1;
		self.Keyword = keyword;
	    self.LangID = langID;
		bindSelectedOption();
		if (self.DoRequestTimer != null) {
			clearTimeout(self.DoRequestTimer);
		}
		if (keyword.length >= minChar) {
			self.DoRequestTimer = setTimeout(doRequest, delay);
		}
		else {
			//Clear Options
			clearOptions();
		}
	}
	function doRequest() {
		function requestSuccess(data, textStatus) {
			self.Options = data;
			self.SelectedOptionIndex = findOptionPositionByText(self.Keyword);
			bindOptions();
			bindSelectedOption();
		}
		if (self.GetOptionsRequest != null && this.GetOptionsRequest.readyState != 4) {
			self.GetOptionsRequest.abort();
		}
		this.GetOptionsRequest = jQuery.ajax({
			type: "POST",
			contentType: "application/x-www-form-urlencoded;charset=utf-8",
			url: oUrl,
			data: "type=" + listType + "&keyword=" + self.Keyword + "&langID=" + self.LangID,
			dataType: "json",
			success: requestSuccess
		});
	}

	function _keyUp(event) {
		switch (event.keyCode) {
			case KEY.ESC:
				event.cancelBubble = true;
				event.preventDefault();
				acceptSelection();
				break;
			case KEY.RETURN:
				event.cancelBubble = true;
				event.preventDefault();
				acceptSelection();
				break;
			case KEY.UP:
				event.preventDefault();
				selectPreviousOption();
				break;
			case KEY.DOWN:
				event.preventDefault();
				selectNextOption();
				break;
			case KEY.TAB:
				break;
			default:
				getOptions(this.value);
				break;
		}
	}

	function _keyDown(event) {
		switch (event.keyCode) {
			case KEY.RETURN:
				event.cancelBubble = true;
				event.preventDefault();
				acceptSelection();
				break;
			default:
				break;
		}
	}

	function _blur(event) {
		if (smartBoxType.toLowerCase() == "list" && self.SelectedOptionIndex < 0) {
			jQuery('#' + inputID).val("");
			bindSelectedOption();
		}
		self.HideOptionsTimer = setTimeout(hideOptions, 1000);
	}

	function options_focus(event) {
		clearTimeout(self.HideOptionsTimer);
	}

	function options_blur(event) {
		_blur(event);
	}

	function acceptSelection() {
		hideOptions();
	}
	function hideOptions() {
		jQuery('#' + optionsContainerID).hide();
	}
	function showOptions() {
		var objInput = document.getElementById(inputID);
		var posInput = findPos(objInput);
		var cLayerLeft = posInput[0];
		var cLayerTop = posInput[1] + jQuery('#' + inputID).outerHeight();
		jQuery('#' + optionsContainerID).css({ left: cLayerLeft, top: cLayerTop });
		jQuery('#' + optionsContainerID).show();
	}
	function selectNextOption() {
		if (self.Options != null) {
			if (self.SelectedOptionIndex == self.Options.length - 1) {
				self.SelectedOptionIndex = -1;
			}
			self.SelectedOptionIndex = self.SelectedOptionIndex + 1;
			bindSelectedOption();
		}
	}
	function selectPreviousOption() {
		if (self.Options != null) {
			if (self.SelectedOptionIndex <= 0) {
				self.SelectedOptionIndex = self.Options.length;
			}
			self.SelectedOptionIndex = self.SelectedOptionIndex - 1;
			bindSelectedOption();
		}
	}
	function optionClick(e) {
		self.SelectedOptionIndex = findOptionPositionByValue(this.value);
		bindSelectedOption();
		hideOptions();
	}
	function paintSelectedOption() {
		jQuery('#' + optionsID + ' > ul > li').removeClass('selected');
		if (self.SelectedOptionIndex >= 0) {
			jQuery('#' + optionsID + ' > ul > li:eq(' + self.SelectedOptionIndex + ')').addClass('selected');
		}
	}
	function bindValues() {
		if (self.SelectedOptionIndex >= 0) {
			jQuery('#' + inputID).val(self.Options[self.SelectedOptionIndex].textField);
			jQuery('#' + hiddenID).val(self.Options[self.SelectedOptionIndex].valueField);
		}
		else {
			jQuery('#' + hiddenID).val("");
		}
	}
	function bindSelectedOption() {
		paintSelectedOption();
		bindValues();
		if (self.SelectedOptionChangedEvent != null) {
			self.SelectedOptionChangedEvent();
		}
	}
	function clearOptions() {
		jQuery('#' + optionsID).empty();
		hideOptions();
	}
	function bindOptions() {
		if (self.Options.length > 0) {
			optionsHTML = '<ul>';
			for (var i = 0; i < self.Options.length; ++i) {
				option = self.Options[i];
				optionsHTML += '<li value="' + option.valueField + '"><a href="javascript:void(0);">' + highlight(option.textField, self.Keyword) + '</a></li>';
			}
			optionsHTML += '</ul>';
			jQuery('#' + optionsID).empty();
			jQuery('#' + optionsID).append(optionsHTML);
			jQuery('#' + optionsID + ' > ul > li').bind('click', optionClick);
			showOptions();
		}
		else {
			clearOptions();
		}
	}
	function findOptionPositionByText(text) {
		var result = -1;
		for (var i = 0; i < self.Options.length; ++i) {
			if (self.Options[i].textField.buyukHarf() == text.buyukHarf()) {
				result = i;
				break;
			}
		}
		return result;
	}
	function findOptionPositionByValue(value) {
		var result = -1;
		for (var i = 0; i < self.Options.length; ++i) {
			if (self.Options[i].valueField == value) {
				result = i;
				break;
			}
		}
		return result;
	}
	function highlight(value, term) {
		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
	}
	function findPos(obj) {
		var curleft = curtop = 0;
		if (obj.offsetParent) {
			do {
				curleft += obj.offsetLeft;
				curtop += obj.offsetTop;
			}
			while (obj = obj.offsetParent);
		}
		return [curleft, curtop];
	}
	function bindSelectedOptionChanged(fn) {
		self.SelectedOptionChangedEvent = fn;
	}
	this.DoRequestTimer = null;
	this.GetOptionsRequest = null;
	this.Options = null;
	this.SelectedOptionIndex = null;
	this.Keyword = null;
	this.Url = oUrl;
	this.ListType = listType;
	this.HideOptionsTimer = null;
	this.SelectedOptionChangedEvent = null;
	this.BindSelectedOptionChanged = bindSelectedOptionChanged;
    this.LangID = langID;
	delay = 300;
	minChar = 3;
	KEY = {
		BACKSPACE: 8,
		TAB: 9,
		RETURN: 13,
		SHIFT: 16,
		CTRL: 17,
		ALT: 18,
		PAUSEBREAK: 19,
		CAPSLOCK: 20,
		ESC: 27,
		PAGEUP: 33,
		PAGEDOWN: 34,
		END: 35,
		HOME: 36,
		LEFT: 37,
		UP: 38,
		RIGHT: 39,
		DOWN: 40,
		PRINTSCRN: 44,
		INSERT: 45
	};
	jQuery("#" + inputID).attr("autocomplete", "off");
	jQuery("#" + inputID).keyup(_keyUp);
	jQuery("#" + inputID).keydown(_keyDown);
	jQuery("#" + inputID).blur(_blur);
	jQuery("#" + optionsID).focus(options_focus);
	jQuery("#" + optionsID).blur(options_blur);
	return this;
}

String.prototype.buyukHarf = function() {
	var str = [];
	for (var i = 0; i < this.length; i++) {
		var ch = this.charCodeAt(i);
		var c = this.charAt(i);
		if (ch == 105) str.push('İ');
		else if (ch == 305) str.push('I');
		else if (ch == 287) str.push('Ğ');
		else if (ch == 252) str.push('Ü');
		else if (ch == 351) str.push('Ş');
		else if (ch == 246) str.push('Ö');
		else if (ch == 231) str.push('Ç');
		else if (ch >= 97 && ch <= 122) str.push(c.toUpperCase());
		else str.push(c);
	}
	return str.join('');
}
