var Search; // export
var SearchUI; // export

$(document).ready(function() {
	Keys = {
		'BACKSPACE': 8,
		'ENTER': 13,
		'ESCAPE': 27,
		'ARROW_UP': 38,
		'ARROW_DOWN':40,
		'DELETE': 46,
		'KEY_0': 48,
		'KEY_Z': 90,

		changesInput: function(keyCode) {
			return (keyCode >= this.KEY_0 && keyCode <= this.KEY_Z) || keyCode == this.BACKSPACE || keyCode == this.DELETE;
		}
	};

	Direction = {
		UP: -1,
		DOWN: +1
	};

	SearchUI = {
		setup: function() {
			this.SEARCH_FORM.setup();
			this.QUERY_INPUT.setup();
		},
		
		SEARCH_FORM: {
			CONTROL: $("form#livesearch"),
			setup: function() {
				this.CONTROL.submit(function(e) {
					return false;
				});
			}
		},

		QUERY_INPUT: {
			CONTROL: $("#livesearch > input#query"),

			setup: function() {
				this.CONTROL.focus(function(e) {
					SearchUI.QUERY_INPUT.activate();
					SearchUI.QUERY_INPUT.clear();
				});

				this.CONTROL.blur(function(e) {
					SearchUI.QUERY_INPUT.deactivate();
					SearchUI.QUERY_INPUT.setDefaultText();
					SearchUI.RESULTS.clear();
				});

				this.CONTROL.keyup(this.handleInput);
			},

			handleInput: function(e) {

				if (Keys.changesInput(e.which)) {
					if (SearchUI.QUERY_INPUT.get().val().length >= 2) {
						Search.perform(SearchUI.QUERY_INPUT.get().val());
					}

					if (SearchUI.QUERY_INPUT.get().val().length == 0) {
						SearchUI.RESULTS.clear()
					}
				} else if (e.which == Keys.ESCAPE) {
					SearchUI.QUERY_INPUT.clear();
					SearchUI.RESULTS.clear();
				} else if (e.which == Keys.ARROW_DOWN) {
					SearchUI.RESULTS.handleSelection(Direction.DOWN);
				} else if (e.which == Keys.ARROW_UP) {
					SearchUI.RESULTS.handleSelection(Direction.UP);
				} else if (e.which == Keys.ENTER) {
					SearchUI.RESULTS.gotoSelectedResult();
				}

			}, 

			get: function() {
				return this.CONTROL;
			},

			clear: function() {
				this.CONTROL.val("");
			},

			activate: function() {
				this.CONTROL.addClass("active");
			},

			deactivate: function() {
				this.CONTROL.removeClass("active");
			},

			setDefaultText: function() {
				this.CONTROL.val("ISIN, Ticker, Value")
			}
		},

		RESULTS: {
			CONTROL: $("#livesearchResults"),
			RESULT_ITEM_SELECTOR: "#livesearchResults tr",
			ACTIVE_ITEM_SELECTOR: "#livesearchResults tr.active",
			currentSelection: -1,

			show: function(data) {
				this.CONTROL.html(data);
				this.CONTROL.show();
			},

			hide: function() {
				this.CONTROL.hide();
			},

			clear: function() {
				this.clearSelection();
				this.CONTROL.html("");
				this.hide();
			},

			clearSelection: function() {
				this.currentSelection = -1;
				this.getActiveResult().removeClass("active");
			},

			getActiveResult: function() {
				return $(this.ACTIVE_ITEM_SELECTOR);
			},

			getAllResults: function() {
				return $(this.RESULT_ITEM_SELECTOR);
			},

			handleSelection: function(direction) {
				if (this.currentSelection != -1) {
					this.toggleSelection(this.currentSelection);
				}
				var resultCount = this.getAllResults().size();
				this.currentSelection = (this.currentSelection + direction) % resultCount;
				this.currentSelection = this.currentSelection >= 0 ? this.currentSelection : resultCount - Math.abs(this.currentSelection);
				this.toggleSelection(this.currentSelection);
			},

			toggleSelection: function(index) {
				this.getAllResults().eq(index).toggleClass("active");
			},

			gotoSelectedResult: function() {
				var link = this.getActiveResult().find("a");
				window.location = link.attr("href");
			}
		}
	};

	Search = {
		searchUrl: '/search', 
		perform: function(query) {
			if (query == null && query != "") {
				return;
			}

			$.ajax({
				url: this.searchUrl,
				cache: true,
				data: "query=" + query,
				dataType: 'html',
				success: function(data, textStatus, request) {
					SearchUI.RESULTS.show(data);
				}
			});
		},
		setup: function(url) {
			this.searchUrl = url;
		}
	};

	SearchUI.setup();
});
