﻿// (c) Copyright Visit Technology Group

Type.registerNamespace("Transport");

Transport.RouteBehavior = function(element)
{
	Transport.RouteBehavior.initializeBase(this, [element]);

	this._valueControl = null;
	this._servicePath = null;
	this._serviceMethod = null;
	this._onlineId = null;
	this._culture = null;
	this._productGroupId = null;
	this._productIds = null;
	this._start = null;
	this._minLength = 3;

	this._popupCssClass = null;
	this._itemCssClass = null;
	this._selectedItemCssClass = null;
	this._tickerCssClass = null;

    this._timer = null;
    this._request = null;
    this._cache = {};

	this._currentText = null;
	this._popupElement = null;

	this._selectedItem = null;

	this._focusHandler = null;
	this._blurHandler = null;
	this._keyDownHandler = null;

	this._popupMouseDownHandler = null;
	this._popupMouseUpHandler = null;
	this._popupMouseOverHandler = null;
	this._popupBlurHandler = null;

	this._bodyClickHandler = null;

	this._tickHandler = null;
}

Transport.RouteBehavior.prototype =
{
	initialize: function()
	{
		Transport.RouteBehavior.callBaseMethod(this, 'initialize');

		this._focusHandler = Function.createDelegate(this, this._onFocus);
		this._blurHandler = Function.createDelegate(this, this._onBlur);
		this._keyDownHandler = Function.createDelegate(this, this._onKeyDown);

		this._popupMouseDownHandler = Function.createDelegate(this, this._onPopupMouseDown);
		this._popupMouseUpHandler = Function.createDelegate(this, this._onPopupMouseUp);
		this._popupMouseOverHandler = Function.createDelegate(this, this._onPopupMouseOver);
		this._popupBlurHandler = Function.createDelegate(this, this._onPopupBlur);

		this._bodyClickHandler = Function.createDelegate(this, this._onBodyClick);

		this._tickHandler = Function.createDelegate(this, this._onTimerTick);

		this._requestCompleteHandler = Function.createDelegate(this, this._onRequestComplete);
		this._requestFailedHandler = Function.createDelegate(this, this._onRequestFailed);

		var el = this.get_element();

		el.autocomplete = 'off';

		$addHandler(el, 'focus', this._focusHandler);
		$addHandler(el, 'blur', this._blurHandler);
		$addHandler(el, 'keydown', this._keyDownHandler);

		var pe = this._popupElement = document.createElement('ul');
		pe.id = this.get_id() + '_popup';
		el.parentNode.insertBefore(this._popupElement, el.nextSibling);

		if (this._popupCssClass)
			Sys.UI.DomElement.addCssClass(pe, this._popupCssClass);

		$addHandler(pe, 'mousedown', this._popupMouseDownHandler);
		$addHandler(pe, 'mouseup', this._popupMouseUpHandler);
		$addHandler(pe, 'mouseover', this._popupMouseOverHandler);
		$addHandler(pe, 'blur', this._popupBlurHandler);

		$addHandler(document.body, 'click', this._bodyClickHandler);

		this._preload();
	},
	dispose: function()
	{
		if (this._timer)
			this._stopTimer();

		var el = this.get_element();

		$removeHandler(el, 'focus', this._focusHandler);
		$removeHandler(el, 'blur', this._blurHandler);
		$removeHandler(el, 'keydown', this._keyDownHandler);

		var pe = this._popupElement;

		$removeHandler(pe, 'mousedown', this._popupMouseDownHandler);
		$removeHandler(pe, 'mouseup', this._popupMouseUpHandler);
		$removeHandler(pe, 'mouseover', this._popupMouseOverHandler);
		$removeHandler(pe, 'blur', this._popupBlurHandler);

		$removeHandler(document.body, 'click', this._bodyClickHandler);

		Transport.RouteBehavior.callBaseMethod(this, 'dispose');
	},

	get_valueControl: function()
	{
		return this._valueControl;
	},
	set_valueControl: function(value)
	{
		this._valueControl = value;
	},

	get_servicePath: function()
	{
		return this._servicePath;
	},
	set_servicePath: function(value)
	{
		this._servicePath = value;
	},

	get_serviceMethod: function()
	{
		return this._serviceMethod;
	},
	set_serviceMethod: function(value)
	{
		this._serviceMethod = value;
	},

	get_onlineId: function()
	{
		return this._onlineId;
	},
	set_onlineId: function(value)
	{
		this._onlineId = value;
	},

	get_culture: function()
	{
		return this._culture;
	},
	set_culture: function(value)
	{
		this._culture = value;
	},

	get_productGroupId: function()
	{
		return this._productGroupId;
	},
	set_productGroupId: function(value)
	{
		this._productGroupId = value;
	},

	get_productIds: function()
	{
		return this._productIds;
	},
	set_productIds: function(value)
	{
		this._productIds = value;
	},

	get_start: function()
	{
		return this._start;
	},
	set_start: function(value)
	{
		this._start = value;
	},

	get_minLength: function()
	{
		return this._minLength;
	},
	set_minLength: function(value)
	{
		this._minLength = value;
	},

	get_popupCssClass: function()
	{
		return this._popupCssClass;
	},
	set_popupCssClass: function(value)
	{
		this._popupCssClass = value;
	},

	get_itemCssClass: function()
	{
		return this._itemCssClass;
	},
	set_itemCssClass: function(value)
	{
		this._itemCssClass = value;
	},

	get_selectedItemCssClass: function()
	{
		return this._selectedItemCssClass;
	},
	set_selectedItemCssClass: function(value)
	{
		this._selectedItemCssClass = value;
	},

	get_tickerCssClass: function()
	{
		return this._tickerCssClass;
	},
	set_tickerCssClass: function(value)
	{
		this._tickerCssClass = value;
	},

	_startTimer: function()
	{
		if (this._timer)
			return;

		this._timer = window.setInterval(this._tickHandler, 500);
	},

	_stopTimer: function()
	{
		if (this._timer)
		{
			window.clearInterval(this._timer);
			this._timer = null;
		}
	},

	_onFocus: function(e)
	{
		if (this._minLength == 0 && this.get_element().value == '')
			this._startTimer();
	},

	_onBlur: function(e)
	{
		this._stopTimer();

		if (this._request)
		{
			this._request.get_executor().abort();
			this._request = null;
		}

		this._hidePopup();
	},

	_onKeyDown: function(e)
	{
		this._stopTimer();

		var k = e.keyCode ? e.keyCode : e.rawEvent.keyCode;

		if (k === Sys.UI.Key.esc)
		{
			this._hidePopup();
			e.preventDefault();
		}
		else if (k === Sys.UI.Key.up)
		{
			if (this._selectedItem && this._selectedItem.previousSibling)
			{
				this._selectItem(this._selectedItem.previousSibling);

				e.stopPropagation();
				e.preventDefault();
			}
		}
		else if (k === Sys.UI.Key.down)
		{
			if (this._selectedItem)
			{
				if (this._selectedItem.nextSibling)
				{
					this._selectItem(this._selectedItem.nextSibling);

					e.stopPropagation();
					e.preventDefault();
				}
			}
			else if (this._popupElement.childNodes && this._popupElement.childNodes.length > 0)
			{
				this._selectItem(this._popupElement.childNodes[0]);

				e.stopPropagation();
				e.preventDefault();
			}
		}
		else if (k === Sys.UI.Key.enter)
		{
			if (this._selectedItem)
			{
				this._setText(this._selectedItem);

				e.preventDefault();
			}
			else
			{
				this._hidePopup();
			}
		}
		else if (k === Sys.UI.Key.tab)
		{
			if (this._selectedItem)
			{
				this._setText(this._selectedItem);
			}
		}
		else
		{
			this._startTimer();
		}
	},

	_onPopupMouseDown: function(e)
	{
		var item = e.target;

		if (item !== this._popupElement)
		{
			this._setText(item);
		}
	},

	_onPopupMouseUp: function(e)
	{
		this.get_element().focus();
	},

	_onPopupMouseOver: function(e)
	{
		var item = e.target;

		if (item !== this._popupElement)
		{
			this._selectItem(item);
		}
	},

	_onPopupBlur: function(e)
	{
		this._hidePopup();
	},

	_onBodyClick: function(e)
	{
		this._hidePopup();
	},

	_onTimerTick: function(e)
	{
		this._stopTimer();

		var text = this.get_element().value;

		if (text.trim().length < this._minLength)
		{
			this._currentText = null;
			this._update('', null);
			return;
		}

		if (this._currentText !== text || (this._minLength == 0 && text == ''))
		{
			this._currentText = text;

			if (this._cache[text])
			{
				this._update(text, this._cache[text]);
				return;
			}

			this._download(
				text,
				this._requestCompleteHandler,
				this._requestFailedHandler);

			if (this._tickerCssClass)
				Sys.UI.DomElement.addCssClass(this.get_element(), this._tickerCssClass);
		}
	},

	_preload: function()
	{
		if (this._minLength == 0)
		{
			this._download(
				'',
				Function.createDelegate(this, function(result, context)
				{
					this._request = null;

					this._cache[context] = result;
				}),
				Function.createDelegate(this, function()
				{
					this._request = null;
				}));
		}
	},

	_download: function(text, completeHandler, failedHandler)
	{
		if (this._servicePath && this._serviceMethod && this._onlineId && (this._productGroupId || this._productIds))
		{
			if (this._request)
			{
				this._request.get_executor().abort();
				this._request = null;
			}

			this._request = Sys.Net.WebServiceProxy.invoke(
				this.get_servicePath(),
				this.get_serviceMethod(),
				false,
				{
					'onlineid': this.get_onlineId(),
					'culture': this.get_culture(),
					'productgroupid': this.get_productGroupId(),
					'productids': this.get_productIds(),
					'start': this.get_start(),
					'query': text
				},
				completeHandler,
				failedHandler,
				text);
		}
	},

	_onRequestComplete: function(result, context)
	{
		this._request = null;
		this._update(context, result);

		this._cache[context] = result;

		if (this._tickerCssClass)
			Sys.UI.DomElement.removeCssClass(this.get_element(), this._tickerCssClass);
	},

	_onRequestFailed: function(err, response, context)
	{
		this._request = null;

		if (this._tickerCssClass)
			Sys.UI.DomElement.removeCssClass(this.get_element(), this._tickerCssClass);
	},

	_update: function(text, items)
	{
		if (items && items.length)
		{
			var pe = this._popupElement;

			pe.style.width = '';
			pe.innerHTML = '';
			this._selectedItem = null;

			for (var i = 0; i < items.length; i++)
			{
				var e = document.createElement('li');
				e.appendChild(document.createTextNode(items[i].Name));
				var inp = document.createElement('input');
				inp.type = 'hidden';
				inp.value = items[i].Id;
				e.appendChild(inp);

				if (this._itemCssClass)
					Sys.UI.DomElement.addCssClass(e, this._itemCssClass);

				pe.appendChild(e);
			}

			this._showPopup();
		}
		else
		{
			this._hidePopup();
		}
	},

	_selectItem: function(item)
	{
		if (this._selectedItem)
		{
			if (this._selectedItemCssClass)
				Sys.UI.DomElement.removeCssClass(this._selectedItem, this._selectedItemCssClass);
			if (this._itemCssClass)
				Sys.UI.DomElement.addCssClass(this._selectedItem, this._itemCssClass);
		}

		this._selectedItem = item;

		if (this._itemCssClass)
			Sys.UI.DomElement.removeCssClass(this._selectedItem, this._itemCssClass);
		if (this._selectedItemCssClass)
			Sys.UI.DomElement.addCssClass(this._selectedItem, this._selectedItemCssClass);
	},

	_showPopup: function()
	{
		var el = this.get_element();

		var pe = this._popupElement;

		var b = Sys.UI.DomElement.getBounds(el);
		b.y += b.height;

		Sys.UI.DomElement.setLocation(pe, b.x, b.y);
		var l = Sys.UI.DomElement.getBounds(pe);

		if (l.x != b.x || l.y != b.y)
			Sys.UI.DomElement.setLocation(pe, b.x - (l.x - b.x), b.y - (l.y - b.y));

		if (l.width < b.width)
			pe.style.width = b.width + 'px';

		pe.style.visibility = 'visible';
	},

	_hidePopup: function()
	{
		this._popupElement.style.visibility = 'hidden';

		this._selectedItem = null;
	},

	_setText: function(item)
	{
		var text = (item && item.firstChild) ? item.firstChild.nodeValue : null;
		var id = (item && item.lastChild) ? item.lastChild.value : null;

		this.get_element().value = text;

		if (this._valueControl)
			this._valueControl.value = id;

		this._currentText = text;

		this._hidePopup();
	}
}

Transport.RouteBehavior.registerClass('Transport.RouteBehavior', Sys.UI.Behavior);

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
