SKOBBLERwidgets = (typeof SKOBBLERwidgets =='undefined')?{}: SKOBBLERwidgets;

SKOBBLERwidgets.LastSearches = function(field, data, options) {
	this.init(field, data, options);
}

SKOBBLERwidgets.LastSearches.prototype = {
	field: null,
	data: null,
	options: null,

	/**
	inner data
	*/
	instanceId: null,
	index: -1,

	lastValue: "",
	/**
	@constructor
	@param field string or HTMLElement
	@param data array of strings
	@param options
	*/
	init: function(field, data, options) {

		this.browser = this.getBrowser();

		this.field = field;
		this.data = data;

		this.options = options || {};
		this.applyOptions();

		this.instanceId = parseInt(Math.random() * 10000);

		/* Export widget instance into global scope */
		this.globalName = 'SKOBBLER_LS' + this.instanceId;
		eval(this.globalName + '=this;');

		this.fieldElem = $(this.field);
		this.formElem = $(this.fieldElem.form);

		this.createContainer();
		this.processData(this.data);

		switch(this.options.boxType) {
		case "where":
			this.alteration = skobbler_HOMEADDRESS + " (__TEXT__)";
			if(this.data.length > 1) {
				this.alterData();
			}
			this.fillAlterContainer(this.data);

			break;
		case "secure":

			this.alteration = skobbler_FULL_FUNCTIONALITY;

			if(this.data.length > 1) {
				this.alterData();
			}
			this.fillAlterContainer(this.data);
			this.containerElem.setStyle({
				cursor: 'default'
			});

			break;
		default:
			this.fillContainer(this.data);
		}

		this.createShadow();
		this.hide();
		this.buttonElem = $$('form#' + this.formElem.id + ' input[type=submit]')[0];
		this.attachEvents();
		this.wasBlur = false;
		this.buttonClick = false;
	},

	processItem: function(item){
		item = item.unescapeHTML();//this function also strips tags
		item = item.replace(/&quot;/gi, '"');
		item = item.replace(/&#039;/gi, "'");
		return item;
	},

	processData: function(data) {
		for(var i =0;i<data.length; i++) {
			data[i] = this.processItem(data[i]);
		}
	},

	applyOptions : function() {
		this.options.boxType = this.options.boxType || "whatever";
		this.options.deleteContentOnFocus = this.options.deleteContentOnFocus || false;
		this.options.classNames = {};
		this.options.classNames.normalRow = Object.isString(this.options.classNames.normalRow )?this.options.classNames.normalRow:'normalRow';
		this.options.classNames.selectedRow = Object.isString(this.options.classNames.selectedRow )?this.options.classNames.selectedRow:'selectedRow';
	},

	/**
	@private
	*/
	createContainer: function() {

		this.containerElem = document.createElement('div');
		this.containerElem.id = 'lastsearches' + this.instanceId;
		$(this.containerElem).addClassName("skobblerLastSearches");

		document.body.appendChild(this.containerElem);

		this.containerElem = $(this.containerElem);
		this.containerElem.addClassName("lastSearches");
		this.containerElem.setStyle({width: (this.fieldElem.getWidth() - 6) + "px"}); //-10
		this.positionContainer();

		this.containerElemDim = this.containerElem.getDimensions();

	},

	createShadow: function() {
		/* design deffects */
		this.shadowElem = document.createElement('div');
		this.shadowElem.id = 'lastshadow' + this.instanceId;
		document.body.appendChild(this.shadowElem);
		this.shadowElem = $(this.shadowElem);
		this.shadowElem.addClassName("lastShadow");
		this.shadowElem.clonePosition(this.containerElem);
		this.positionShadow();
	},

	positionShadow: function() {
		var off = this.containerElem.cumulativeOffset();
		this.shadowElem.setStyle({
			position: 'absolute',
			top: (off[1] + 2)+"px",
			left: (off[0] + 2)+"px"
		});
	},

	alterData: function() {
		this.data.splice(this.data.length-1, 1, "", "", this.data[this.data.length-1]);
	},

	alterItem: function(text) {
		var itext = new String(this.alteration);
		itext = itext.replace("__TEXT__", text);
		return itext;
	},

	positionContainer: function() {
		this.containerElem.setStyle({
			position: 'absolute',
			top: (this.findPosY(this.fieldElem))+"px",
			left: (this.findPosX(this.fieldElem) + 4)+"px"
		});
	},

	fillContainer: function(data) {
		var ind = 0;
		data.each(function(item){
			this.addSearch(item, ind++);
		}.bind(this));
	},

	fillAlterContainer: function(data) {
		var ind = 0;
		data.each(function(item){

			if( ind == this.data.length-1) {
				this.addSearch(this.alterItem(item), ind++);
				return;
			}
			this.addSearch(item, ind++);
		}.bind(this));
	},

	attachEvents: function() {
		Event.observe(window, "resize", this.onResize.bindAsEventListener(this));
		Event.observe(document, "click", this.inputBlur.bindAsEventListener(this));
		Event.observe(this.fieldElem, "blur", this.fieldOnBlur.bindAsEventListener(this));
		Event.observe(this.fieldElem, "click", this.fieldOnFocus.bindAsEventListener(this));
		Event.observe(document, "keyup", this.onTab.bindAsEventListener(this));
		Event.observe(this.fieldElem, "keydown", this.onKeyDown.bindAsEventListener(this));
		Event.observe(this.fieldElem, "keyup", this.onKeyUp.bindAsEventListener(this));
		Event.observe(this.buttonElem, "mouseup", this.onButtonClick.bindAsEventListener(this));
		Event.observe(this.fieldElem.form, "submit", this.onFormSubmit.bindAsEventListener(this));
	},

	onButtonClick: function(event) {
		this.buttonClick = true;
	},

	onResize: function(event) {
		this.positionContainer();
		this.positionShadow();
	},

	onKeyDown: function(event) {
		if (!event && window.event) event = window.event;
		if (event) this.key = event.keyCode;
		else this.key = event.which;
		this.keyDown = this.key;
	},

	onKeyUp: function(event) {
		this.keyDown = null;

		if (!event && window.event) event = window.event;
		if (event) this.key = event.keyCode;
		else this.key = event.which;

		if (this.key == 40){ //Arrow down
			if(!this.isVisible() ) {
				this.show();
				if(this.index == -1) return;
			}
			if(this.index >= this.data.length-1) {
				this.setRowClass(this.data.length-1, this.options.classNames.normalRow);
				this.index = -1;
			}
			if(this.index >= -1 && this.index < this.data.length-1) {

				var prev = this.index;
				this.index++;

				var dat = this.data[this.index];
				while(dat == "") {
					this.index++;
					dat = this.data[this.index];
				}

				/* TODO: when last items are empty
				if(this.index >= this.data.length-1) {
					this.setRowClass(prev, this.options.classNames.normalRow);
					return;
				}
				*/

				this.setRowClass(this.index, this.options.classNames.selectedRow);
				if(this.index > 0)
					this.setRowClass(prev, this.options.classNames.normalRow);

				var val = this.data[this.index];
				this.fieldElem.value = val;


			}
		} else if (this.key == 38){ //Arrow up
			if(!this.isVisible()) {

				this.show();
				if(this.index == -1) return;
			}
			if(this.index <= 0) {
				this.setRowClass(0, this.options.classNames.normalRow);
				this.index = this.data.length;
			}

			if(this.index > 0 && this.index <= this.data.length) {
				var prev = this.index;
				this.index--;

				var dat = this.data[this.index];
				while(dat == "") {
					this.index--;
					dat = this.data[this.index];
				}

				/* TODO : when last items are empty
				if(this.index <= 0) {
					this.setRowClass(prev, this.options.classNames.normalRow);
					return;
				}*/

				this.setRowClass(this.index, this.options.classNames.selectedRow);
				if(this.index < this.data.length-1)
					this.setRowClass(prev, this.options.classNames.normalRow);

				var val = this.data[this.index];
				this.fieldElem.value = val;

			}
		} else if (this.key == 27){ // Esc

			if(this.isVisible()) {
				this.hide();
			}
		} else if (this.key == 8){ // Backspace

			if(this.isVisible()) {
				this.hide();
			}
		} else if(this.key == 13) { //ENTER
			if(this.index == -1) return;

			var val = this.data[this.index];

			this.fieldElem.value = val;


			if(this.isVisible()) {

				this.hide();
			}

		} else if(this.key == 9) { //TAB

			this.show(); 	/* To replace onFocus event */

		} else { //other keystrokes

			if(this.isVisible()) {

				this.hide();
			}
		}

	},

	fieldOnFocus: function(event) {

		this.lastValue = this.fieldElem.value!=""? this.fieldElem.value: this.lastValue;
		if(this.options.deleteContentOnFocus == true) {
			this.fieldElem.value = "";
		}
		this.show();
	},

	__fieldOnBlur: function(event) {

		var trg = !Object.isUndefined(event.explicitOriginalTarget)?event.explicitOriginalTarget: document.activeElement;

		if(this.containerElem != trg &&
			trg.parentNode != this.containerElem &&
			trg.parentNode.parentNode != this.containerElem
			/* when link used instead of plain text */
			/* && trg.parentNode.parentNode.parentNode != this.containerElem */
			) {
				if(this.isVisible()) {
					if(this.fieldElem.value == "") {
						this.fieldElem.value = this.lastValue;
					}
					this.hide();
				}
			}
	},

	fieldOnBlur: function(event) {
		if(this.fieldElem.value == "") {
			this.fieldElem.value = this.lastValue;
		}
	},

	inputBlur: function(event) {
		this.wasBlur = true;
		var trg = !Object.isUndefined(event.target)?event.target:event.srcElement;

		/* WAS not a mouse event !!! */
		if(this.isVisible() && trg == this.buttonElem && this.buttonClick == false) { // NOT working in IE
			event.returnValue = false;
		}

		if(trg != this.fieldElem && trg != this.containerElem &&
			trg.parentNode != this.containerElem &&
			trg.parentNode.parentNode != this.containerElem &&
			(trg.parentNode.parentNode != this.formElem ||
			(trg.parentNode.parentNode == this.formElem && Event.pointerX(event) != 0 && Event.pointerY(event) != 0)
			) /*&& trg.type != "submit"*/
		) {
			if(this.isVisible()) {
				if(this.fieldElem.value == "") {
					this.fieldElem.value = this.lastValue;
				}
				this.hide();
			}
		}
	},

	/* Can replace findPosX, findPosY with prototype functions ? */
	findPosX: function(obj) {
		var curleft = 0;
		if (obj.offsetParent){
			while (obj.offsetParent){
				curleft += obj.offsetLeft;
				obj = obj.offsetParent;
			}
		}
		else if (obj.x)
			curleft += obj.x;
		return curleft;
	},

	findPosY: function(obj) {
		var curtop = 0;
		if (obj.offsetParent){
			curtop += obj.offsetHeight;
			while (obj.offsetParent){
				curtop += obj.offsetTop;
				obj = obj.offsetParent;
			}
		}
		else if (obj.y){
			curtop += obj.y;
			curtop += obj.height;
		}
		return curtop;
	},

	addSearch: function(search, index) {
		if(!search || search == "") {
			this.addEmptySearch();
			return;
		}

		var sr = document.createElement("p");
		this.containerElem.appendChild(sr);
		sr.setAttribute('ind', index);

		/* when link used instead of plain text */
		/*var link = document.createElement('a');
		var linkText = document.createTextNode(search);
		link.appendChild(linkText);
		link.setAttribute('href','#');
		link.setAttribute('ind', index);
		sr.appendChild(link);
		*/

		sr = $(sr);
		sr.setStyle({width: (this.containerElemDim.width - 20) + "px"});

		if(this.options.boxType == "secure") {
			sr.innerHTML = search;
			sr.setStyle({
				cursor: 'default'
			});
		} else {
			Event.observe(sr, "click", this.lastSearchOnClick.bindAsEventListener(this));
			Event.observe(sr, "mouseover", this.mouseHandlerOver.bindAsEventListener(this));
			Event.observe(sr, "mouseout", this.mouseHandlerOut.bindAsEventListener(this));
			sr.appendChild(document.createTextNode(search)); //createTextNode does not interpret htmlentities
		}
	},

	mouseHandlerOver: function(event){
		if(this.index > -1 && this.index < this.data.length){
			this.setRowClass(this.index, this.options.classNames.normalRow);
		}
		var trg = !Object.isUndefined(event.target)?event.target:event.srcElement;
		this.index = parseInt(trg.getAttribute("ind"));
		this.setRowClass(this.index, this.options.classNames.selectedRow);
	},

	mouseHandlerOut: function(event){
		var trg = !Object.isUndefined(event.target)?event.target:event.srcElement;
		var index = parseInt(trg.getAttribute("ind"));
		this.setRowClass(index, this.options.classNames.normalRow);
	},

	/*
	* FF click on link, then on document
	*/
	lastSearchOnClick: function(event) {

		var trg = !Object.isUndefined(event.target)?event.target:event.srcElement;

		var index = parseInt(trg.getAttribute("ind"));
		var val = this.data[index];

		this.fieldElem.value = val;

		this.lastValue = this.fieldElem.value!=""? this.fieldElem.value: this.lastValue;

		if(this.isVisible()) {
			this.hide();
		}
	},

	addEmptySearch: function() {
		/*var sr = document.createElement("p");
		var srt = document.createTextNode("&nbsp;");
		this.containerElem.appendChild(sr);
		sr.appendChild(srt);*/
		var br = document.createElement("br");
		this.containerElem.appendChild(br);
	},

	isVisible: function() {
		return (this.containerElem.getStyle("display") == "none")?false: true;
	},

	show: function() {
		this.buttonClick = false;
		this.stopFormSubmit();
		this.containerElem.setStyle({display:"block"});
		
		this.containerElem.setStyle({width: (this.fieldElem.getWidth() - 6) + "px"}); //-10
		this.positionContainer();
		this.containerElemDim = this.containerElem.getDimensions();
		
		this.positionShadow();
		this.shadowElem.setStyle({display:"block"});
	},

	hide: function() {

		if(this.index > -1 && this.index < this.data.length){
			this.setRowClass(this.index, this.options.classNames.normalRow);
		}
		this.index = -1;

		/* Check if something else opened */
		var elems = $$(".skobblerLastSearches");
		var opened = false;

		$A(elems).each(function(item){
			if(item.id != this.containerElem.id && item.getStyle("display") != "none") {
					opened = true;
			}
		}.bind(this));

		if(opened == false) {
			this.attachFormSubmit();
		}

		this.containerElem.setStyle({display:"none"});
		this.shadowElem.setStyle({display:"none"});
	},

	getText: function(control) {
		if (document.all) {
			return control.innerText; /* IE */
		}
		return control.textContent; /* Firefox */

	},

	setRowClass: function(posi, className) {

		this.containerElem.childNodes[posi].className = className;
	},

	onTab: function(event) {
		this.lastKey = this.key;
		var trg = !Object.isUndefined(event.target)?event.target:event.srcElement;

		if (!event && window.event) event = window.event;
		if (event) this.key = event.keyCode;
		else this.key = event.which;

		if(this.key == 9 && trg != this.fieldElem && trg != this.containerElem ) {

			/* Issue when tabbed: form submit reattached wrongly */
			if(this.isVisible()) {
				this.hide();
			}
		}
	},

	stopFormSubmit: function() {

		this.formElem.setAttribute("onsubmit", "return false;");
	},

	onFormStopSubmit: function(event) {
		Event.stop(event);
	},

	attachFormSubmit: function() {
		this.formElem.setAttribute("onsubmit", "return true;");
	},

	trim: function(value) {
		return value.replace(/^\s+|\s+$/g,"");
	},

	onFormSubmit: function(event) {
		var val = new String(this.fieldElem.value);
		val = this.trim(val);
		this.fieldElem.value = val;
	},

	getBrowser: function() {
		var browser = 'Other';
		if(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1) {
			browser = 'IE';
		}
		if(navigator.userAgent.indexOf('Opera') > -1) {
			browser = 'Opera';
		}
		if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
			browser = 'WebKit';
		}
		if(navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') === -1) {
			browser = 'Gecko';
		}
		if(navigator.userAgent.match(/Apple.*Mobile.*Safari/)) {
			browser = 'MobileSafari';
		}
		if(navigator.userAgent.indexOf('Chrome') > -1) {
			browser = 'Chrome';
		}
		return browser;

	}

}
