
//this is to replace regular oversized selection
//how to do?
// 1. add wrapSelect tag to SELECT class
// 2. add wrapSelect.init() when document is ready
// 3. check if setting needs to do that

var WrapSelect = {
	useWrapSelect: true,
	dataArray: [],
	scrollHeight: 258,
	isWrapSelectObj: function(e) {
		if (isJQueryObject(e))
			return e.is('.ws');
		else
			return $j(e).is('.ws');
	},

	selectClick: function(elem, maxsize) {

		if (!elem.is('.wrapSelect'))
			elem = WrapSelect.getWrapElem(elem);
		//		$j('.wrapSelectDisplayTable', elem).click();
		//we should only init autocomplete only after click to save time on loading.
		//		$j('.wrapSelectDisplayTable', elem).click(function() {

		if (elem.is('.ddDisabled'))
			return false;

		var input = $j('input.htmlContentInput', elem);
		var id = $j('input.htmlContentId', elem);

		//reset input text if preload empty selection
		if (id.val() == -1)
			input.val('');

		var name = input.attr('name');
		var wrapSelectContent = $j('.wrapSelectContent', elem);

		var temp = input.val();
		input.val('');
		temp = WrapSelect.removeHtmlBold(temp);

		//this timeout is to make sure input bind with autocomplete is ready. so input.display() could run correctly.
		setTimeout(function() {
			input.display();
			input.val(temp);
			WrapSelect.setSize(input, maxsize);
			var ul = elem.find('ul');
			var selectedRowCount = ul.attr('selectRowCount');
			var firstLi = ul.find('li:first');
			var lineHeight = parseFloat(firstLi.outerHeight());
			//fix different browser scroll to problem. test on 800+ rows.
			if ($j.browser.msie && $j.browser.version < 8 && $j.browser.version > 6)
				lineHeight = lineHeight + 1;
			else if ($j.browser.msie && $j.browser.version > 7)
				lineHeight = lineHeight + 0.4;
			else if ($j.browser.msie && $j.browser.version < 7)
				lineHeight = lineHeight - 1;
			else if ($j.browser.mozilla)
				lineHeight = lineHeight - 0.4;

			if (selectedRowCount != undefined) {
				var offset = parseInt(selectedRowCount) * lineHeight;
				ul.scrollTo({ top: offset });
			}
			input.focus().select();
		}, 50);

		wrapSelectContent.show();
		input.focus().select();
		return true;
	},

	removeHtmlBold: function(string) {
		string = string.replace(/&nbsp;/gi, ""); //make sure &nbsp; is not showing.
		string = string.replace(/<b>/gi, "").replace(/<\/b>/gi, ""); //make sure <b> and </b> also removed
		return string;
	},

	init: function(elem, inputData, maxsize) {
		if (!elem.is('.wrapSelect'))
			elem = WrapSelect.getWrapElem(elem);

		if (elem.length == 0)
			return false;
	
		//most of time we will update inputData. so should continue
		//if(elem.is('.initialized'))
		//	return false;

		if (!inputData) {
			inputData = [];
		} else {
			var inputName = WrapSelect.getIdElem(elem).attr("name");
			if (inputName != null)
				WrapSelect.dataArray[inputName] = inputData;
		}

		var id = $j('input.htmlContentId', elem);

		var wrapSelectText = $j('.wrapSelectText', elem);
		if (id.val() == -1) {
			WrapSelect.setDisplayText(wrapSelectText, "");
		}

		var input = $j('input.htmlContentInput', elem);
		input.setOptions({ selectFirst: false });

		var name = id.attr('name');
		if (elem.is('.ddDisabled')) {
			//don't do disable or enable here to save performance onloading.
			//stop. no need more init process
			return false;
		}
		elem.removeClass('initialized');
		elem.find('.ac_results').remove();
		input.flushCache();
		var wrapSelectContent = $j('.wrapSelectContent', elem);

		var mousein = false;
		wrapSelectContent.mouseenter(function() {
			mousein = true;
			return false;
		});
		wrapSelectContent.mouseleave(function() {
			mousein = false;
			return false;
		});

		$j('input.htmlContentId_projid', elem).change(function() {
			projectChanged($j(this));
			projTaskTimeChange($j(this));
		});

		$j('input.htmlContentId_taskid', elem).change(function() {
			inputChanged($j(this));
			projTaskTimeChange($j(this));
		});

		$j('input.htmlContentId_timetype', elem).change(function() {
			inputChanged($j(this));
			projTaskTimeChange($j(this));
		});

		input.keydown(function(event) {
			if (event.keyCode == "13") {
				if (input.val() == "")
					id.val("-1");
				WrapSelect.setDisplayText(wrapSelectText, "");
			} else {
				return true;
			}
		});

		var wrapSelectCancel = $j('.wrapSelectCancel', elem);
		wrapSelectCancel.click(function() {
			$j('div.wrapSelectContent').hide();
			$j('.ac_results_' + name).hide();
			return false;
		});

		var wrapSelectDisplayDD = $j('.wrapSelectDisplayDD', elem);
		wrapSelectDisplayDD.keydown(function(event) {
			// data key or any arrow key
			if(!(DataKeyPressed(event.keyCode) || event.keyCode == "37" || event.keyCode == "38" || event.keyCode == "39" || event.keyCode == "40"))
				return;
			var text = String.fromCharCode(event.keyCode).toLowerCase();
			var htmlContentInput = $j('input.htmlContentInput', elem);
			//trigger as empty search
			if(!(event.keyCode == "37" || event.keyCode == "38" || event.keyCode == "39" || event.keyCode == "40")) {
				htmlContentInput.val("");
			}
			$j(this).parents('table.wrapSelectDisplayTable').click();
			//start with char just entered. arrow key don't have any
			if(!(event.keyCode == "37" || event.keyCode == "38" || event.keyCode == "39" || event.keyCode == "40")) {
				setTimeout(function() {htmlContentInput.val(text); }, 60);
			}
		});

		var initWidth = WrapSelect.setSize(input, maxsize);

		//before attach new click event, remove current it has
		$j('.wrapSelectDisplayTable', elem).unbind('click');

		//this check is to handle blur and click event
		var justblured = false;

		//this is a flag for if it is result() changed the selection
		var resultSelected = false;
		//flag for modal alert
		var modalalertOn = false;

		if (justblured == true) {
			//hide all content divs
			wrapSelectContent.hide();
			$j('.ac_results_' + name).hide();
			//WrapSelect.contentDivOpening = false;
			justblured = false;
			return false;
		}
		if (!elem.is('.initialized')) {
			elem.addClass('initialized');

			var originalText = wrapSelectText.text();

			//remove possible added emptyList div.
			wrapSelectContent.find('div.emptyList').remove();
			if (inputData.length == 0 && wrapSelectContent.find('div.emptyList').length == 0) {
				//case that this dropdown has no data. show user that it has no data.
				wrapSelectContent.append('<div class="emptyList nowrap">&nbsp;&nbsp;- Nothing to select -</div>');
			}

			input.autocomplete(inputData, {
				//autoFill: true,
				addblank: false, //don't add blank here. some field such as project has blank value with id not -1.
				resultsClass: "ac_results ac_results_" + name,
				//resultsClass: "ac_results",
				minChars: 0,
				//reduce delay since it is local%
				delay: 100,
				max: 1024,
				matchContains: true,
				matchSubset: false,
				mustMatch: false,
				selectFirst: false,
				scrollHeight: WrapSelect.scrollHeight,
				attachedToInput: true,
				width: initWidth + 4,
				selectid: WrapSelect.parseIdVal(elem),
				//turn off highlight to increase performace
				highlight: false,
				formatMatch: function(data) {
					if (data[0] == -2) //don't format result if it is -2 roll, which is size data
						return "";
					if (data[3])
						return data[3]; //search on full name if possible
					else if (data[2])
						return data[2];
					else
						return data[0];
				},
				formatItem: function(data) {
					if (data[0] == -2) //don't format result if it is -2 roll, which is size data
						return "";
					if (data[2])
						return data[2];
					else
						return data[0];
				},
				formatResult: function(data) {
					if (data[0] == -2) //don't format result if it is -2 roll, which is size data
						return "";
					if (data[3])
						return data[3];
					if (data[2])
						return data[2];
					else
						return data[0];
				}
			}).result(function(event, data, formatted) {
				// Called only when an autocomplete item is selected
				var idVal;
				var text = "";
				if (data[3])
					text = data[3];
				else if (data[2])
					text = data[2];
				else
					text = data[0];

				if (data) {
					//project should be data [1]???
					idVal = data[1];
				} else {
					idVal = -1;
				}
				if (idVal != undefined) {
					id.val(idVal);
					id.trigger('change');
				}
				wrapSelectContent.hide();
				$j('button.wrapSelectDisplayDD', elem).focus();
				$j('button.wrapSelectDisplayDD', elem).trigger({ type : 'keypress', which : 9 });
				
				input.setOptions({ selectFirst: false });
				var selectText = WrapSelect.removeHtmlBold(text);
				WrapSelect.setDisplayText(wrapSelectText, selectText);
				originalText = selectText;
				input.setOptions({ selectid: WrapSelect.parseIdString(idVal) });
				resultSelected = true;

			}).blur(function() {
				if (mousein == false) {
					justblured = true;
					wrapSelectContent.hide();

					if (modalalertOn != true)
						$j('button.wrapSelectDisplayDD', elem).focus();

					setTimeout(function() { justblured = false }, 500); //this is to help click wrapselect table to close the content div.
					return false;
				} else {
					// for ie that lose focus even when click scrollbar
					setTimeout(function() { input.focus().select(); }, 1);
					justblured = false;
					return false;
				}
			}).keydown(function(event) {
				//tab enter esc should close the content div
				if (event.keyCode == 9 || event.keyCode == 13 || event.keyCode == 27) {
					mousein = false;
					setTimeout(function() { wrapSelectContent.hide(); }, 1);
					//not esc. tab.
					if (resultSelected != true && event.keyCode != 27) {
						var message = "<b>" + input.val() + "</b> is an incorrect value.";
						modalAlert("", message, {
							onOk: function() {
								$j.modal.close();
								setTimeout(function() { WrapSelect.setFocus(input) }, 50);
							}
						});
						modalalertOn = true;
					}
					input.val(originalText);
					WrapSelect.setDisplayText(wrapSelectText, originalText);
					if(event.keyCode == 9) {
						//tab key should tab away from current dropdown button
						var fields = elem.parents('form:first').find('button, input');
						var index = fields.index($j('button.wrapSelectDisplayDD',elem)[0]);
						if(index != -1) {
							//need to jump 4 index number since wrapselect has total 2 button and 2 hidden inputs 
							var nextElement = fields.eq( index + 4 ); 
							setTimeout(function() {nextElement.focus().select() }, 60);
						}
						return true;
					}
					return false;
				}
				input.setOptions({ selectFirst: true });
				resultSelected = false;
				return true;
			});
		}
		return false;
	},

	setSize: function(input, maxsize) {
		var currentDropDown, wrapSelectContent;
		var length = input.val().length;
		if (maxsize && parseInt(length) < parseInt(maxsize)) {
			length = maxsize;
		}
		var width = WrapSelect.calculateSizeFromCharLen(length, input);
		//set input width
		input.width(width);

		//set position if needed
		var wrap = WrapSelect.getWrapElem(input);
		currentDropDown = $j('.ac_results', wrap);
		wrapSelectContent = $j('.wrapSelectContent', wrap);
		wrapSelectText = $j('.wrapSelectText', wrap);
		//set dropdown content width
		currentDropDown.width(width + 24);

		var screenSizeHeight = $j(window).height();

		var screenScrollHeight = $j(window).scrollTop();

		var textPosition = wrapSelectText.offset().top;
		var textAbsoluteTop = wrapSelectText.position().top - screenScrollHeight;

		var wrapSelectContentHeight = wrapSelectContent.height();

		//we set default scrollHeight: 258. also need to make sure there is a dropdown
		if (screenSizeHeight > WrapSelect.scrollHeight && (screenSizeHeight - textAbsoluteTop) < wrapSelectContentHeight) {
			//dropdown case that open towards up
			wrapSelectContent.css('top', textPosition + wrapSelectText.height() - wrapSelectContentHeight - 17);  //try to cover original screen
			//try to give a fixed size height to avoid shrink dropdown size
			wrapSelectContent.css('height', wrapSelectContentHeight);
		} else {
			wrapSelectContent.css('top', textPosition - 4);  //try to cover original screen
			//reset the height back to auto to auto shrink
			wrapSelectContent.css('height', 'auto');
		}

		return width;
	},

	calculateSizeFromCharLen: function(length, input) {

		var constant = (input[0].style.fontSize || 14) / 2;
		var width = length * constant; //+ 20;

		if (width < 270)
			width = 270; 	//min width
		if (width > 640)
			width = 640; 	//max width
		//			if (isMyStuffScrolling($j('.ac_resluts')))
		//				width = width + 16;
		// position should be based on the input position. otherwise, on too low of the bottom, it will give trouble
		return width;
	},

	getWrapElem: function(elem) {
		if (elem.is('.wrapSelect'))
			return elem;
		else
			return elem.parents('div.wrapSelect:first');
	},

	getIdVal: function(elem, inputName) {
		var wrap = WrapSelect.getWrapElem(elem);
		var temp = WrapSelect.getIdElem(wrap, inputName);

		if (temp.length > 0)
			return temp.val();
		else
			return null;
	},

	getIdElem: function(elem, inputName) {
		var wrap = WrapSelect.getWrapElem(elem);
		if (inputName != null)
			return wrap.find('input.htmlContentId' + inputName);
		else
			return wrap.find('input.htmlContentId');
	},

	getInputVal: function(elem, inputName) {
		var wrap = WrapSelect.getWrapElem(elem);
		var temp = WrapSelect.getInputElem(wrap, inputName);
		if (temp.length > 0)
			return temp.val();
		else
			return null;
	},
	parseIdString: function(val) {
		if (val.indexOf(',') != -1)
			return val.split(',')[0];
		else
			return val;
	},

	parseIdVal: function(elem, inputName) {
		var val = WrapSelect.getIdVal(elem, inputName);
		if (val.indexOf(',') != -1)
			return val.split(',')[0];
		else
			return val;
	},

	getInputElem: function(elem, inputName) {
		elem = WrapSelect.getWrapElem(elem);
		if (inputName != null)
			return elem.find('input.htmlContentInput' + inputName);
		else
			return elem.find('input.htmlContentInput');
	},

	inputIsDisabled: function(input) {
		var result = input.attr('disabled');
		if (result == "disabled" || result == true)
			return true;
		else
			return false;
	},

	disableInputElem: function(elem) {
		//we need to disable two things. 1. display div; 2. the click event
		var wrap = WrapSelect.getWrapElem(elem);
		wrap.addClass('ddDisabled');
		wrap.find('input').attr('disabled', 'true');
		$j('.wrapSelectDisplayTable', wrap).unbind('click').addClass('wrapSelectDisplayTableDisabled');
		$j('button.wrapSelectDisplayDD', wrap).addClass('ddDisabled');
		$j('td.wrapSelectDisplayDDtd', wrap).addClass('ddTdDisabled');
		var wrapSelectText = $j('.wrapSelectText', wrap);
		wrapSelectText.addClass('textDisabled');
		WrapSelect.setDisplayText(wrapSelectText, "");
		$j('.htmlContentId', wrap).val("-1");
	},

	enableInputElem: function(elem) {

		var wrap = WrapSelect.getWrapElem(elem);
		wrap.removeClass('ddDisabled');

		wrap.find('input').removeAttr('disabled');
		$j('.wrapSelectDisplayTable', wrap).removeClass('wrapSelectDisplayTableDisabled');
		$j('button.wrapSelectDisplayDD', wrap).removeClass('ddDisabled');
		$j('td.wrapSelectDisplayDDtd', wrap).removeClass('ddTdDisabled');
		$j('.wrapSelectText', wrap).removeClass('textDisabled');
	},

	clearSelection: function(elem) {
		var wrap = WrapSelect.getWrapElem(elem);
		WrapSelect.setDisplayText($j('.wrapSelectText', wrap), "");
		$j('.htmlContentId', wrap).val("-1");
	},

	selectByValue: function(elem, value, name) {
		var found = false;
		var wrap = WrapSelect.getWrapElem(elem);

		var id = $j('.htmlContentId', wrap);

		var span = $j('.wrapSelectText', wrap);
		if (value == '-1') {
			WrapSelect.setDisplayText(span, "");
			id.val(value);
			found = true;
		} else if (name != undefined) {
			WrapSelect.setDisplayText(span, name);
			id.val(value);
			found = true;
		} else {
			// case for empty name
			var text = "";
			var data = WrapSelect.dataArray[id.attr("name")];
			if (!data)
				return false;
			for (var i = 0; i < data.length; i++) {
				if (data[i]) {
					if (data[i][1] == value) {
						if (data[i][3] != undefined)
							text = data[i][3];
						else if (data[i][2] != undefined)
							text = data[i][2];
						else
							text = data[i][0];
						found = true;
						break;
					}
				}
			}
			if (found) {
				WrapSelect.setDisplayText(span, text);
				id.val(value);
			}
		}
		return found;
	},

	selectByName: function(elem, name, data) {
		if (!data) {
			var wrap = WrapSelect.getWrapElem(elem);
			var id = $j('.htmlContentId', wrap);
			data = WrapSelect.dataArray[id.attr('name')];
		}
		if (!data)
			return false;

		for (var i = 0; i < data.length; i++) {
			var text = "";
			if (data[i]) {
				if (data[i][3] != undefined)
					text = data[i][3];
				else if (data[i][2] != undefined)
					text = data[i][2];

				if (text == "")
					return false;
				if (text == name) {
					return WrapSelect.selectByValue(elem, data[i][1], name);
					break;
				}
			}
		}
		return false;
	},
	getAutoSelectFirst: function(elem) {
		var wrap = WrapSelect.getWrapElem(elem);
		var data = WrapSelect.dataArray[elem.attr('name')];
		if (!data)
			return "-1";
		for (var i = 0; i < data.length; i++) {
			var val = data[0][1];
			if (val != "-1")
				return val;
		}
		return "-1";
	},

	getSelectTextFromValue: function(elem, value) {
		var wrap = WrapSelect.getWrapElem(elem);
		var data = WrapSelect.dataArray[elem.attr('name')];
		if (!data)
			return "";

		var text = "";
		for (var i = 0; i < data.length; i++) {
			if (data[i]) {
				if (data[i][1] == value) {
					if (data[i][3] != undefined)
						text = data[i][3];
					else if (data[i][2] != undefined)
						text = data[i][2];
					break;
				}
			}
		}
		return text;
	},

	getSelectTextFromId: function(elem, id) {
		var wrap = WrapSelect.getWrapElem(elem);
		var data = WrapSelect.dataArray[elem.attr('name')];
		if (!data)
			return "";

		var text = "";
		for (var i = 0; i < data.length; i++) {
			if (data[i]) {
				if (data[i][0] == id) {
					if (data[i][3] != undefined)
						text = data[i][3];
					else if (data[i][2] != undefined)
						text = data[i][2];
					break;
				}
			}
		}
		return text;
	},

	setFocus: function(elem) {
		elem = $j(elem);
		var wrap = WrapSelect.getWrapElem(elem);
		$j('.wrapSelectDisplayTable', wrap).click();
		return true;
	},

	setDisplayText: function(elem, text) {
		if ($j.browser.msie && $j.browser.version == 6) {
			if (text == "") {
				// if it is ie6 and empty text, then we need to give a minimal width
				$j(elem).addClass("wrapSelectTextMinWidth").html("");
			} else {
				$j(elem).removeClass("wrapSelectTextMinWidth").html(text);
			}
		} else {
			$j(elem).html(text);
		}
	}
}
