﻿/// public:

/// private:
/// A CAddressSearch osztaly allapotmentesere valo segedosztaly
function CAddressSearchUserState(strInputText, address, arrAddressList)
{
	this.strInputText = strInputText;
	this.address = address;
	this.arrAddressList = arrAddressList;
}
///protected:
// Egy input mezohoz rendelheto cimkereso objektum.
// Terkepi muveletet nem vegez.
// Parameterben a CTopoliszMap osztaly egy peldanyat varja
function CAddressSearch(pTopoliszMap)
{
	// Keressen-e focus vesztesre
	this.bAutoSearch = true;
	// Eltuntesse-e a talalati listat focus vesztesre
	this.bAutoHideResultList = true;
	// Begepeles kozben adjon-e listat
	this.bAutoComplete = true;
	// Cimek reszletezettsege:
	this.bUseComplexAddress = false;

	this.bOKPressed = false;
	this.strEventSource = null; // OK gombot nyomtak-e meg, avagy Entert
	// Keresosztring
	this.strInputText = "";

	//Talált egyértelmű cím:
	this.address = null;
	// CAddress lista
	this.arrAddressList = null;
	// A cimlista milyen keresesbol allt elo
	this.strLastSearchString = "";
	// Aktiv talalat sorszama, enterre ha lista van akkor ez lesz az uj elem;
	this.iActive = 0;
	// Default szoveg
	this.strDefaultText = "";
	// Lista div eltolasa az input mezohoz kepest
	this.iListOffsetX = 5;
	this.iListOffsetY = 20;

	this.iCommandID = null;
	this.bSearchNeeded = false;
	this.pTopoliszMap = pTopoliszMap;
	this.input = null;
	this.divResult = null;
	this.divHint = null;

	this.killTimer = null;
	this.bSkipNextBlur = false;
	this.bListHidden = false;
	this.bDisplayPostcode = false; // A cím elején írja-e ki mindig az irányítószámot, ha létezik
	// Egy szervervalaszt csak akkor fogad el, ha megegyezo a stamp-je
	this.iStamp = 0;
	// Akkor true, ha a user indított kérést (nem autocomplete)
	this.bStrongSearch = false;
	this.bIsBusy = false;
	this.timerSearch = null;

	// public:
	// OK gombra, vagy enterre hivodik meg
	this.OnOK = function(strEventSource)
	{
	}

	// protected:
	// Egyertelmu cimtalalat eseten hivodik meg
	this.OnAddressFound = function(address) 
	{
	}
	
	// User altal inditott kereses (blur vagy ok) vegen hivodik meg (nem biztos, hogy van egyertelmu cim)
	this.OnSearchEnded = function(bFound)
	{
	}

	// private:
	var me = this;

	// protected:
	// Melyik CTopoliszMap osztalyon keresztul tortenjen a szerver kommunikacio
	this.SetServer = function(pTopoliszMap)
	{
		me.pTopoliszMap = pTopoliszMap;
	}

	// protected:
	// Cim megadasa, CSimpleAddress-t var
	this.SetAddress = function(pAddress)
	{
		me.iStamp++;
		me.bIsBusy = false;
		me.bStrongSearch = false;
		delete me.arrAddressList;
		me.arrAddressList = new Array();
		me.address = null;
		me.strLastSearchString = "";
		me.strInputText = "";
		me.iActive = 0;
		me.bWasDeleteBack = false;
		if(pAddress != null)
		{
			if(pAddress.strName != null && pAddress.strName.length > 0)
				me.strInputText = pAddress.strName;
			else
				me.strInputText = pAddress.strAddress;
			if(pAddress.dX > 0 && pAddress.dY > 0)
			{
				me.address = pAddress;
				me.strLastSearchString = pAddress.strAddress;
			}
			else
			{
				me.Show();
				me.FindAddress();
				return;
			}
		}
		else
		{
			me.strInputText == "";
		}
		me.ClearHint();

		if(me.input)
			me.Show();

		me.OnSearchEndedInternal(me.address ? true : false);

		if(me.address != null)
		{
			//Dump('OnAddressFound('+ pAddress.strAddress + ')');
			if(me.OnAddressFound)
			{
				try {
					me.OnAddressFound(pAddress);
				}
				catch(exp) {
					if(me.pTopoliszMap.OnError)
						me.pTopoliszMap.OnError(exp, 'AddressSearch.OnAddressFound');
				}
			}
		}

		if(me.bOKPressed)
			me.Go();
	}

	//private:
	this.ValidateAddress = function()
	{
		if(me.strInputText != me.GetInputValue())
			me.address = null;
	}

	// protected:
	// Visszaadja az egyertelmu cimtalalatot
	this.GetAddress = function()
	{
		me.ValidateAddress();
		return me.address;
		//if(GetArrayLength(me.arrAddressList) == 1)
		//	return me.arrAddressList[0];
		//return null;
	}
	
	/// protected:
	// Visszadja, hogy a címtalálatokban szerepel-e irányítószám.
	// Visszatérési érték: bool
	this.IsDisplayPostcode = function()
	{
		return me.bDisplayPostcode;
	}
	
	// protected:
	// Beállítja, hogy a címtalálatokban szerepeljen-e irányítószám.
	// Alapesetben nem szerepel.
	// Paraméter:
	// bool bDisplay:  A címtalálokban szerepeljen-e irányítószám
	// Visszatérési érték: nincs
	this.SetDisplayPostcode = function(bDisplay)
	{
		me.bDisplayPostcode = bDisplay;
	}

	// protected:
	// Van-e egyertelmu cimtalalat
	this.IsUnique = function()
	{
		//me.ValidateAddress();
		return (me.address != null);
	}

	// protected:
	// Van-e cimlista
	this.HasList = function()
	{
		//me.ValidateAddress();
		return GetArrayLength(me.arrAddressList) > 0;
	}

	//protected:
	// Input mezo beallitasa
	this.SetInput = function(input)
	{
		me.input = input;
		if(me.input)
		{
			AddEvent(me.input, 'focus', me.OnFocus);
			AddEvent(me.input, 'blur', me.OnBlur);
			AddEvent(me.input, 'change', me.OnChange);
			AddEvent(me.input, 'keyup', me.OnKeyUp);
			AddEvent(me.input, 'keypress', me.OnKeyPress);
			AddEvent(me.input, 'click', me.OnClick);
		}
	}

	// protected:
	// Hozzarendelt input mezo lekerdezese
	this.GetInput = function()
	{
		return me.input;
	}
	
	this.SetHintDiv = function(div)
	{
		me.divHint = div;
		if(me.divHint)
		{
			me.divHint.className = "AddressHint"
		}
	}

	this.ClearHint = function()
	{
		if(me.divHint)
		{
			while(me.divHint.firstChild)
				me.divHint.removeChild(me.divHint.firstChild)
		}
	}

	this.HintExample = function()
	{
		if(me.divHint)
		{
			me.ClearHint();
			me.divHint.className = "AddressHint"
			if(g_InitSettings.strCountryName == "Románia")
				NewTextTag(g_Babel.GetWord('ExampleAddressRo', ""), me.divHint);
			else
				NewTextTag(g_Babel.GetWord('ExampleAddress', "pl. Budapest V. Vigadó tér 2  vagy  N47.3 E19.3"), me.divHint);
		}
	}
	
	this.HintError = function()
	{
		if(me.divHint)
		{
			me.ClearHint();
			me.divHint.className = "AddressHintError"
			NewTextTag(g_Babel.GetWord('AddressError',"Hibás cím!"), me.divHint);
		}
	}
	
	this.HintList = function()
	{
		if(me.divHint)
		{
			me.ClearHint();
			me.divHint.className = "AddressHintError"
			NewTextTag(g_Babel.GetWord('SelectAddressFromList', "Nem egyértelmű cím!"), me.divHint);
		}
	}

	// protected:
	// Allapotmentes (input box szovege, cimlista)
	this.GetUserState = function()
	{
		return new CAddressSearchUserState(me.strInputText, me.address, me.arrAddressList);
	}

	// protected:
	// Allapot betoltes a GetUserState altal visszaadott objektummal
	this.SetUserState = function(state)
	{
		me.strInputText = state.strInputText;
		me.SetInputValue(me.strInputText);
		me.address = state.address;
		me.arrAddressList = state.arrAddressList;
	}

	// protected:
	// Fokuszvesztesre kezdjen-e el cimet keresni
	this.IsAutoSearch = function() 
	{
		return me.bAutoSearch;
	}
	
	// protected:
	this.SetAutoSearch = function(bValue)
	{
		me.bAutoSearch = bValue;
	}

	// protected:
	// ures input box szovegenek beallitasa
	this.SetDefaultText = function(strDefaultText)
	{
		var strInputValue = me.GetInputValue(); // Valtozik az alapszoveg, ezert az ures mezot ujra be kell allitani
		me.strDefaultText = strDefaultText;
		me.SetInputValue(strInputValue);
	}

	// protected:
	// ures input box szovegenek lekerdezese
	this.GetDefaultText = function()
	{
		return me.strDefaultText;
	}

	// private:
	this.SetListOffset = function(iListOffsetX, iListOffsetY)
	{
		me.iListOffsetX = iListOffsetX;
		me.iListOffsetY = iListOffsetY;
	}
	// private:
	this.GetListOffsetX = function() 
	{
		return me.iListOffsetX;
	}
	// private:
	this.GetListOffsetY = function()
	{
		return me.iListOffsetY;
	}
	
	//private:
	this.SetInputValue = function(strInputValue)
	{
		if(me.input)
		{
			if(strInputValue != "")
				me.input.value = strInputValue;
			else
				me.input.value = me.strDefaultText;
		}
		else
		{
			me.strInputText = strInputValue;
		}
	}
	// private:
	this.GetInputValue = function()
	{
		if(me.input)
		{
			if(me.input.value != me.strDefaultText)
				return me.input.value;
			else
				return "";
		}
		else
			return me.strInputText;
	}

	// private:
	this.OnFocus = function(pEvent)
	{
		if(me.input.value == me.strDefaultText)
		{
			if(g_InitSettings.strCountryName == "Magyarország")
				me.input.value = "Budapest ";
			else
				me.input.value = "";
			me.input.select();
			me.HintExample();
		}
		if(me.IsUnique())
		{
			me.HintExample();
		}
		if(me.HasList())
		{
		/*	me.SetActive(0);
			if(me.bAutoHideResultList)
			{
				if(me.divResult && me.divResult.parentNode)
				{
					me.divResult.style.display = "";
				}
			}
			*/
		}
		else
			me.input.select();
	}
	
	this.HideList = function()
	{
		//Dump("HideList");
		me.bListHidden = true;
		if(me.divResult && me.divResult.parentNode)
		{
			me.divResult.style.display = "none";
		}
	}

	this.UnhideList = function()
	{
		me.bListHidden = false;
		if(me.divResult && me.divResult.parentNode)
		{
			me.divResult.style.display = "";
		}
	}

	// private:
	this.OnBlur = function(pEvent)
	{
		if(me.input.value == "")
		{
			me.input.value = me.strDefaultText;
			me.ClearHint();
		}

		if(me.bAutoSearch)
		{
			if(!me.bOKPressed)
			{
				me.bStrongSearch = true;
				me.FindAddress();
			}
		}

		if(me.IsUnique())
			me.ClearHint();
		if(me.HasList())
		{
			if(me.bAutoHideResultList)
			{
				if(me.divResult && me.divResult.parentNode)
				{
					if(!me.bSkipNextBlur)
					{
						me.killTimer = window.setTimeout(me.HideList, 250);
						//Dump('setTimeout');
						window.setTimeout(me.input.focus, 250);
					}
					else
						me.bSkipNextBlur = false;
					return;
				}
			}
		}

		StopEventPropagation(pEvent);
		return false;
	}
	
	this.OnClick = function(pEvent)
	{
		if(me.bAutoHideResultList && me.HasList())
		{
			if(me.bListHidden)
				me.ShowList();
			else
				me.UnhideList();
		}
	}

	// private:
	// Az IE olyan kedves, hogy elviszi a focus-t egy uj HTML elem generalasakor, 
	// hat most majd nem hagyjuk neki
	this.OnBeforeDeactivate = function(pEvent)
	{
		var divTo = GetEventRelatedElement(pEvent);
		if(divTo && divTo.nodeName.toLowerCase() == "body")
		{
			return false;
		}
		return true;
	}

	// private:
	this.OnChange = function(pEvent)
	{
	}

	// private:
	this.OnKeyUp = function(pEvent)
	{
		if (me.input.value == me.strDefaultText)
			me.input.value = "";
	
		if(pEvent == null)
			pEvent = window.event;
		// felnyil
		if(pEvent.keyCode== 38)
		{
			if(me.iActive > 0)
				me.SetActive(me.iActive-1);
			else
				me.SetActive(GetArrayLength(me.arrAddressList)-1);
			StopEventPropagation(pEvent);
			return false;
		}
		//lenyil
		if(pEvent.keyCode == 40)
		{
			if(me.iActive <GetArrayLength(me.arrAddressList)-1)
				me.SetActive(me.iActive+1);
			else
				me.SetActive(0);
			StopEventPropagation(pEvent);
			return false;
		}
		if(pEvent.keyCode != 13)
		{
			me.SetActive(-1);
		}
	}
	
	this.OnKeyPress = function(pEvent)
	{
		if (me.input.value == me.strDefaultText)
			me.input.value = "";
		
		if(pEvent == null)
			pEvent = window.event;
		if(pEvent.keyCode==13)
		{
			if(me.HasList() && me.bListHidden)
				me.UnhideList();
			else
				me.Go("enter");
			if(GetArrayLength(me.arrAddressList) == 1)
			{
				return true;
			}
			else
			{
				StopEventPropagation(pEvent);
				return false;
			}
		}
		else if(pEvent.keyCode==27) // escape
		{
			me.SetAddress(null);
			me.input.value = "";
		}
		else if(me.bAutoComplete && (me.GetInputValue().length > 1))
		{ // nem jön be: tab, nyilak
			keycodes = [ 9, 37, 38, 39, 40];
			//space, pont, vesszo
			charcodes = [32, 46, 44]
			for(var i=0; i<keycodes.length; i++)
			{
				if(pEvent.keyCode == keycodes[i])
					return;
			}
			for(var i=0; i<charcodes.length; i++)
			{
				if(pEvent.charCode == charcodes[i])
					return;
			}

			me.bSearchNeeded = true;
			if(me.timerSearch == null)
			{
				me.timerSearch = window.setTimeout(me.FindAddressListOnly, 500);
			}
		}
	}

	this.KillTimer = function()
	{
		//Dump("KillTimer:" + me.killTimer);
		me.bSkipNextBlur = true;
		if(me.killTimer)
		{
			window.clearTimeout(me.killTimer);
			me.killTimer = null;
		}
	}

	// private:
	this.SetOnClick = function(a, address, iAddress)
	{
		a.onclick = function()
		{
			me.SetAddress(address); 
		}
		a.onmouseover = function()
		{
			me.SetActive(iAddress, true);
		}
		a.onkeyup = me.OnKeyPress;
	}

	// protected:
	// Kitolti az input mezot
	this.Show = function()
	{
		me.SetInputValue(me.strInputText);
		me.ShowList();
	}

	this.ShowList = function()
	{
		me.ClearResultDiv();
		if(me.HasList())
		{
			me.divResult = NewTag ('div',document.body);
			me.divResult.className = "AddressResult";
			me.divResult.style.position = "absolute";
			me.divResult.style.top = (GetAbsLayerTop(me.input)+GetLayerHeight(me.input)) + "px";
			me.divResult.style.left = (GetAbsLayerLeft(me.input)) + "px";
			me.divResult.style.width = (GetLayerWidth(me.input)-1) + "px";

			//AddEvent(me.divResult, 'blur', me.OnBlur);
			//AddEvent(me.divResult, 'focus', function() {Dump('focus'); me.KillTimer()});
			AddEvent(me.divResult, 'keyup', me.OnKeyUp);
			AddEvent(me.divResult, 'keypress', me.OnKeyPress);
			AddEvent(me.divResult, 'mousedown', me.KillTimer);
			AddEvent(me.divResult, 'mouseover', me.KillTimer);

			var iLength = GetArrayLength(me.arrAddressList);
			var a;
			var i;
			for(i=0; i<iLength; i++)
			{
				a = NewTag('a', me.divResult);
				a.setAttribute('href', 'javascript:void(0)');
				if(i== me.iActive)
					a.className = "AddressResultActive";
				else
					a.className = "AddressResult";
				a.style.zIndex = "5";
				var pAddress = me.arrAddressList[i];
				me.SetOnClick(a, me.arrAddressList[i], i);

				NewTextTag(me.arrAddressList[i].strAddress , a);
			}
			if(GetLayerHeight(me.divResult) > 150)
			{
				me.divResult.style.height = "150px";
				me.divResult.style.overflowY = "scroll";
			}
		}
	}

	// private:
	this.SetActive = function (iActive, bSkipScroll)
	{
		me.iActive = iActive;
		if(me.divResult)
		{
			var aList = me.divResult.getElementsByTagName("a");
			for(var i=0; i<aList.length; i++)
			{
				if(i == iActive)
				{
					aList[i].className = "AddressResultActive";
					if(bSkipScroll)
					{
					}
					else
					{
						var iTop = GetLayerTop(aList[i]);
						aList[i].parentNode.scrollTop = iTop;
					}
				}
				else
					aList[i].className = "AddressResult";
			}
			if(iActive <= 0)
				me.UnhideList();
		}
	}

	// private:
	this.ClearResultDiv = function()
	{
		if(me.divResult)
		{
			if(me.divResult.parentNode)
				me.divResult.parentNode.removeChild(me.divResult);
			delete me.divResult;
			me.divResult = null;
		}
	}

	// private:
	this.FillAddress = function(addresslist, clientParam, iCommandID)
	{
		me.bIsBusy = false;
		if(me.iStamp != clientParam.iStamp)
			return;
		//Dump('FillAddress');
		me.iCommandID = null;
		me.strLastSearchString = clientParam.strInputText;
		me.arrAddressList = addresslist;
		if(GetArrayLength(me.arrAddressList) == 1)
			me.SetActive(0);
		else
			me.SetActive(-1);

		me.ShowList();
		me.FindAddress();
	}

	this.FindAddressListOnly = function()
	{
		me.timerSearch = null;
		if(me.bSearchNeeded)
		{
			if(me.bIsBusy)
				me.timerSearch = window.setTimeout(me.FindAddressListOnly, 500)
			else
				me.FindAddress();
		}
	}

	// private:
	this.FindAddress = function()
	{
		//Dump('FindAddress(bAutoCompleteCall=='+bAutoCompleteCall+')');
		if(me.timerSearch)
		{
			window.clearTimeout(me.timerSearch);
			me.timerSearch = null;
		}
		me.bSearchNeeded = false;
		me.bListHidden = false;

		me.strInputText = me.GetInputValue();
		if(me.strInputText != me.strLastSearchString)
		{
			me.address = null;
			var clientParam = { 'strInputText' : me.strInputText, 'iStamp' : me.iStamp };
			if(me.strInputText != null && me.strInputText.length > 0)
			{
				me.bIsBusy = true;
				me.iCommandID = me.pTopoliszMap.NoSessionServer.CallFunction("FindAddress", "strAddress="+me.strInputText + "&bComplex=" + me.bUseComplexAddress, 0, me.FillAddress, clientParam);
			}
			else
			{
				me.FillAddress(null, clientParam, null);
				return;
			}
		}
		else if(me.bStrongSearch)
		{
			var iCount = GetArrayLength(me.arrAddressList);
			if(iCount==1)
			{
				me.SetAddress(me.arrAddressList[0]);
				me.ClearHint();
			}
			else if(iCount > 1)
			{
				me.HintList();
				me.OnSearchEndedInternal(false);
			}
			else if(me.strInputText.length > 0)
			{
				me.HintError();
				me.OnSearchEndedInternal(false);
			}
		}
	}


	this.OnSearchEndedInternal = function(bFound)
	{
		if(me.OnSearchEnded)
		{
			try {
				me.OnSearchEnded(bFound);
			}
			catch(exp) {
				if(me.pTopoliszMap.OnError)
					me.pTopoliszMap.OnError(exp, 'AddressSearch.SearchEnded');
			}
		}
	}

	// protected:
	// Elinditja a cimkeresest
	this.Go = function(strEventSource)
	{
		//console.log('Go(' + me.strInputText + ')' );;
		me.bOKPressed = true;
		if(strEventSource != undefined && strEventSource != null)
		{
			me.strEventSource = strEventSource;
		}
		me.strInputText = me.GetInputValue();
		if(me.strInputText != me.strLastSearchString)
		{
			me.bStrongSearch = true;
			me.FindAddress();
		}
		else
		{
			if(me.HasList())
			{
				if(me.iActive >= 0 && me.iActive < GetArrayLength(me.arrAddressList))
				{
					if(GetArrayLength(me.arrAddressList) != 1)
						me.bOKPressed = false;
					return me.SetAddress(me.arrAddressList[me.iActive]);
				}
				else
					me.UnhideList();
			}
			else
			{
				me.bOKPressed = false;
				//Dump('OnOK');
				if(me.OnOK)
				{
					try {
						me.OnOK(me.strEventSource);
						me.strEventSource = null;
					}
					catch(exp) {
						if(me.pTopoliszMap.OnError)
							me.pTopoliszMap.OnError(exp, 'AddressSearch.OnOK');
					}
				}
			}
		}
	}
}
