vyletnik.search = {};

/**
 * Implementace finderPanelu
 * Jako parametry konstruktoru jsu zde
 * @param manipulationController - reaguje na stisknuti tlacitka na schovani panelu
 * @param fulltextPhrase - implementace inputu na vyhledavani. Finder panel ho zinicializuje
 * @param locationSelects - implementuje vyber regionu a oblasti. Finder ho zinicializuje
 * @param rejstrikMistCategories - implementace kategorii mist. Finder panel ho zinicializuje
 * @param sluzbyCategories - implementace kategorii sluzeb. Finder panel ho zinicializuje
 * @param turistickeInfoCategories - implementace kategorii turistickych mist. Finder panel ho zinicializuje
 * 
 */
vyletnik.search.CriteriaPanel = function (mainForm, fulltextPhrase, locationSelects, rejstrikMistCategories, sluzbyCategories, turistickeInfoCategories) {
	var qPanel;
	var qHideButton;
	
	var pub = {
		init : function () {
			fulltextPhrase.init();
			locationSelects.init();
			rejstrikMistCategories.init();
			sluzbyCategories.init();
			turistickeInfoCategories.init();
			
			qPanel = jQuery('#finderPanel');
			qHideButton = qPanel.find('.hideicon');
			qHideButton.click(onHideClick);
		},
		/**
		 * schova finderPanel
		 */
		hide : function () {
			qPanel.css('overflow', 'hidden');
			qPanel.animate({left : '-250px'}, 1000, function () {
				qHideButton.unbind('click', onHideClick);
				qHideButton.click(onShowClick);
			});
		},
		/**
		 * 
		 */
		show : function () {
			qPanel.css('overflow', 'auto');			
			qPanel.animate({left : '0px'}, 1000, function () {
				qHideButton.unbind('click', onShowClick);
				qHideButton.click(onHideClick);
			});
		}
	};
	function onShowClick(e) {
		e.preventDefault();
		mainForm.showFinderPanel();
	}
	function onHideClick(e) {
		e.preventDefault();
		mainForm.hideFinderPanel();
	}
	
	return pub;
};
/**
 * Implementace komponenty textbox fraze, vcetne vyhledavaciho tlacitka
 * @param phraseModel - propaguje zmeny do phraseModelu
 * @param filterInvoker - vola ho k vyvolani vyhledavani
 */
vyletnik.search.PhraseControl = function (phraseModel, filterInvoker, urlStore, searchModel) {
	var qForm;
	var qTextBox;
	
	var pub = {
		init : function () {
			qForm = jQuery('#finder_fulltext');
			qForm.submit(function () {
				phraseModel.setPhrase(qTextBox.val());
				urlStore.setSearchRequest(searchModel.getRequestParam());
				filterInvoker.invokeFiltering();
				return false;
			});
			qTextBox = jQuery('#fulltext_pharse');
			phraseModel.setPhrase(qTextBox.val());
			qTextBox.change(function () {
				phraseModel.setPhrase(qTextBox.val());
			});
		},
		setPhrase : function (str) {
			qTextBox.val(str);
			qTextBox.change();
		}
	};
	
	return pub;
};
/**
 * Komponenta vyberu regionu a oblasti.
 * Po vyberu regionu AJAXEM stahne oblasti.
 * Po kliknuti na zobrazit, zaostri mapu na vybrany region, oblast
 * @param locationModel - model do ktereho se maji propagovat zmeny
 * @param mainForm - umoznuje zostrit mapu pri stisku tlacitka 'zobrazit'
 */
vyletnik.search.LocationSelectsControl = function (locationModel, focalizer) {
	var qRegionSelect;
	var qOblastSelect;
	var qForm;
	
	var set_oblast = 0;
	
	var locationChangeEvent = vyletnik.utils.Event('onLocationChange');
	
	var pub = {
		init : function () {
			qRegionSelect = jQuery('#finder_filter_regions');
			qRegionSelect.change(function () {
				var region = jQuery(this).val();
				locationModel.setRegion(region);
				loadOblasti(region);
				//slouzi por zamereni mapy
				locationChangeEvent.notifyListeners();
			});
			qOblastSelect = jQuery('#finder_filter_territory');
			qOblastSelect.change(function () {
				var oblast = jQuery(this).val();
				oblastChanged(oblast);
			});
			qForm = jQuery('#finder_filter_kraje');
			qForm.submit(function () {
				focalizer.focalizeMapByModel();
				return false;
			});
			
			//pokud jsou nastaveny defaultne nejake hodnoty, informujeme model
			if (qRegionSelect.val()) {
				locationModel.setRegion(qRegionSelect.val());
			}
			if (qOblastSelect.val()) {
				locationModel.setOblast(qOblastSelect.val());
			}			
		},
		registerLocationChangeListener : function (listener) {
			locationChangeEvent.registerListener(listener);
		},
		setRegion : function (region) {
			if (qRegionSelect.val() != region) {
				qRegionSelect.val(region);
				qRegionSelect.change();
			}
		},
		setOblast : function (oblast) {
			setOblast(oblast);
			set_oblast = oblast;
		}
	};
	function oblastChanged(oblast) {
		locationModel.setOblast(oblast);
		locationChangeEvent.notifyListeners(locationModel);		
	}
	function setOblast(oblast) {
		qOblastSelect.val(oblast);
		oblastChanged(oblast);
		set_oblast = 0;
	}
	/**
	 * zobrazi nactene oblasti
	 */
	function showOblasti(data) {
		qOblastSelect.empty();
		qOblastSelect.append('<option value="0">všechny</option>');		
		for (i = 0; i < data.length; i++) {
			var oblast = data[i];
			var option = jQuery('<option value="' + oblast.key + '">' + oblast.nazev + '</option>');
			qOblastSelect.append(option);
		}
		if (set_oblast != '0') {
			setOblast(set_oblast);
		}
	}
	function loadOblasti(region) {
		jQuery.get('/oblasti/', {'region' : region}, showOblasti, "json");
	}

	return pub;
};
/**
 * Konkretni implementace boxu s kategoriema mist
 * @param cateories - pomocnik ktery implementuje inicializaci a chovani kategorii (schovavani ...)
 * @param filterModel - propaguje do nej zmeny filtru kategorii
 */
vyletnik.search.RejstrikMistCategories = function (categories, filterModel) {
	var pub = {
		init : function () {			
			categories.added(function (category) {
				filterModel.addRejstrikCategory(category);
			});
			categories.removed(function (category) {
				filterModel.removeRejstrikCategory(category);
			});
			
			categories.init('#finder_filter_rejstrik_mist_group');
		},
		/**
		 * Ukaze ci schova kategorie mist
		 */
		toggle : function () {
			categories.toggle();
		},
		select : function (values) {
			categories.select(values);
		}
	};
	return pub;
};
/**
 * Konkretni implementace boxu s kategoriema sluzeb
 * @param cateories - pomocnik ktery implementuje inicializaci a chovani kategorii (schovavani ...)
 * @param filterModel - propaguje do nej zmeny filtru kategorii
 */
vyletnik.search.SluzbyCategories = function (categories, filterModel) {
	var pub = {
		init : function () {			
			categories.added(function (category) {
				filterModel.addSluzbyCategory(category);
			});
			categories.removed(function (category) {
				filterModel.removeSluzbyCategory(category);
			});
			categories.init('#finder_filter_sluzby_group');		
		},
		/**
		 * Ukaze ci schova kategorie sluzeb
		 */
		toggle : function () {
			categories.toggle();
		},
		select : function (values) {
			categories.select(values);
		}
	};
	return pub;
};
/**
 * Konkretni implementace boxu s kategoriema informaci
 * @param cateories - pomocnik ktery implementuje inicializaci a chovani kategorii (schovavani ...)
 * @param filterModel - propaguje do nej zmeny filtru kategorii
 */
vyletnik.search.TuristickeInfoCategories = function (categories, filterModel) {
	var pub = {
		init : function () {
			categories.added(function (category) {
				filterModel.addTuristickeInfoCategory(category);
			});
			categories.removed(function (category) {
				filterModel.removeTuristickeInfoCategory(category);
			});
			categories.init('#finder_filter_turisticke_informace_group');
		},
		/**
		 * Ukaze ci schova kategorie 
		 */
		toggle : function () {
			categories.toggle();
		},
		select : function (values) {
			categories.select(values);
		}
	};
	return pub;
};
vyletnik.search.AdresyCategory = function (filterModel) {
	var qCheckbox;
	return {
		init : function () {
			qCheckbox = jQuery('#finder_filter_adresy');
			qCheckbox.change(function () {
				if (jQuery(this).attr('checked') === true) {
					filterModel.adresy(true);
				} else {
					filterModel.adresy(false);
				}
			});
		},
		check : function (flag) {
			if (flag == 1) {
				qCheckbox.attr('checked', true);
			} else {
				qCheckbox.attr('checked', false);
			}
			qCheckbox.change();			
		}
	};
};
vyletnik.search.ResultModel = function (pointShower) {
	var rejstrikCount;
	var sluzbyCount;
	var turistickeInfoCount;
	var adresyCount;

	var rejstrikPages;
	var sluzbyPages;
	var turistickeInfoPages;
	var adresyPages;
	
	var activeType;
	var activePage = 1;
	
	var pointsChangedListeners = [];
	var resultChangedEvent = vyletnik.utils.Event('onResultChanged');	
	var nextPointsRequestedListeners = [];
	var resultCleared = vyletnik.utils.Event();
	
	var pub = {
		setResult : function (result, options) {
			rejstrikPages = result.rejstrikPages;
			sluzbyPages = result.sluzbyPages;
			turistickeInfoPages = result.turistickeInfoPages;
			adresyPages = result.adresyPages;
			
			rejstrikCount = result.rejstrikCount;
			sluzbyCount = result.sluzbyCount;
			turistickeInfoCount = result.turistickeInfoCount;
			adresyCount = result.adresyCount;
			activeType = result.activeType;
			activePage = result.page;

			var points = result.points;
			pointShower.clearPoints();
			pointShower.setPoints(points);
			triggerResultChanged(rejstrikCount, sluzbyCount, turistickeInfoCount, adresyCount, options);
			triggerPointsChanged(activeType, points, getActivePagesCount(), activePage);
		},
		changeActiveType : function (type) {
			activeType = type;
			activePage = 1;
			triggerNextPointsRequested(type, 1);
		},
		changeActivePoints : function (points) {
			pointShower.clearPoints();
			pointShower.setPoints(points);
			triggerPointsChanged(activeType, points, getActivePagesCount(), activePage);
		},
		changeActivePage : function (page) {
			activePage = page;
			triggerNextPointsRequested(activeType, page);
		},
		registerNextPointsRequestedListener : function (listener) {
			nextPointsRequestedListeners[nextPointsRequestedListeners.length] = listener;
		},
		registerPointsChangedListener : function (listener) {
			pointsChangedListeners[pointsChangedListeners.length] = listener;
		},
		registerResultChangedListener : function (listener) {
			resultChangedEvent.registerListener(listener);
		},
		unregisterResultChangedListener : function (listener) {
			resultChangedEvent.unregisterListener(listener);
		},
		registerResultClearedListener : function (listener) {
			resultCleared.registerListener(listener);
		},
		clearResult : function () {
			pointShower.clearPoints();
			resultCleared.notifyListeners();
		}
	};
	
	function triggerResultChanged(pRejstrikCount, pSluzbyCount, pTurisitckeInfoCount, adresyCount, options) {
		resultChangedEvent.notifyListeners({
			rejstrikCount : pRejstrikCount,
			sluzbyCount : pSluzbyCount,
			turistickeInfoCount : pTurisitckeInfoCount,
			adresyCount : adresyCount,
			options : options
		});
	}
	function triggerPointsChanged(type, pPoints, pages, page) {
		for (var i = 0; i < pointsChangedListeners.length; i++) {
			pointsChangedListeners[i].onPointsChanged(type, pPoints, pages, page);
		}
	}
	function triggerNextPointsRequested(type, page) {
		for (var i = 0; i < nextPointsRequestedListeners.length; i++) {
			nextPointsRequestedListeners[i].onNextPointsRequested(type, page);
		}		
	}
	
	function getActivePagesCount() {
		var activePagesCount;
		if (activeType === 'rejstrik') {
			activePagesCount = rejstrikPages;
		}
		if (activeType === 'sluzby') {
			activePagesCount = sluzbyPages;
		}
		if (activeType === 'turistickeInfo') {
			activePagesCount = turistickeInfoPages;
		}
		if (activeType === 'adresy') {
			activePagesCount = adresyPages;
		}
		return activePagesCount;
	}
	return pub;
};
vyletnik.search.ResultPanel = function (resultModel, layerManager, infoWindowShower) {
	var qResultContainer;
	var qTabs;
	var qRejstrikTab, qSluzbyTab, qTuristickeInfoTab, qAdresyTab;
	var qPages;
	var qCloseButton;
	
	var pub = {
		init : function () {
			qPanel = jQuery('#findingResultPanel');
			qResultContainer = jQuery("#findingResultPanel ul");
			qTabs = jQuery('#findingResultPanel .tabs');
			qRejstrikTab = jQuery('#findingResultPanel .rejstrik');
			qRejstrikTab.click(switchTab);
			qSluzbyTab = jQuery('#findingResultPanel .sluzby');
			qSluzbyTab.click(switchTab);
			qTuristickeInfoTab = jQuery('#findingResultPanel .turistickeInfo');
			qTuristickeInfoTab.click(switchTab);
			qAdresyTab = jQuery('#findingResultPanel .adresy');
			qAdresyTab.click(switchTab);
			
			qPages = jQuery("#findingResultPanel p.pages");
			qCloseButton = jQuery('#findingResultPanel .closeButton');
			qCloseButton.click(function (e) {
				e.preventDefault();
				resultModel.clearResult();
			});
			qPanel.click(function () {
				layerManager.top(qPanel);
			});

			var bottom;
			qPanel.find('a.minimizeButton').click(function (e) {
				e.preventDefault();				
				if (!bottom) {
					bottom = qPanel.css('bottom');
				}
				var minimizable = qPanel.find('.minimizable');
				
				if (minimizable.css('display') == 'none') {
					minimizable.css('display', 'block');
					qPanel.css('bottom', bottom);
					qPanel.css('height', 'auto');
				} else {
					minimizable.css('display', 'none');
					qPanel.css('bottom', 'auto');
					qPanel.css('height', '55px');
				}
			});

			
			resultModel.registerPointsChangedListener({
				onPointsChanged : function (type, points, pages, page) {
					highlightType(type);
					showPoints(points);
					showPages(pages, page);
				}
			});
			resultModel.registerResultChangedListener({
				onResultChanged : function (event) {
					showHideTab(qRejstrikTab, event.rejstrikCount);
					showHideTab(qSluzbyTab, event.sluzbyCount);
					showHideTab(qTuristickeInfoTab, event.turistickeInfoCount);
					showHideTab(qAdresyTab, event.adresyCount);					
					qPanel.find('h2').html(event.options.name);
					layerManager.top(qPanel);
					qPanel.css("display", 'block');
				}
			});
			resultModel.registerResultClearedListener(function () {
				pub.close();
			});
		},
		close : function () {
			qPanel.css("display", "none");
		}
	};
	/**
	 * vlozi zadane body do vyhledavaciho panelu
	 */
	function showPoints(points) {
		qResultContainer.empty();
		for (var i = 0; i < points.length; i++) {
			var point = points[i];
			addPoint(point);
		}
		if (points.length === 0) {
			qResultContainer.append('vašim kritériím neodpovídá žádný záznam ...');
		}
	}
	/**
	 * vlozi jeden bod do vyhledavaciho panelu
	 */
	function addPoint(point) {
		var hRecord;
		var record;
		var description;
		if (point.description) {
			description = point.description;
			if (point.description.length > 80) {
				description = point.description.substring(0, 40) + ' ...';
			}
		}
		hRecord = "<li style=\"background-image : url('" + point.listIcon + "');\">";
		if (point.mapLink) {
			hRecord += '<a title="Přejít na stránku s detailními informacemi o bodu" href=\"' + point.mapLink + '"\" class="style_heading">';
		} else {
			hRecord += '<span class="style_heading">';
		}
		hRecord += point.name;
		if (point.mapLink) {
			hRecord += '</a>';
		} else {
			hRecord += '</span>';
		}
		if (point.kategorie_name) {
			hRecord += '&nbsp;(' + point.kategorie_name + ')<br/>';
		}
		if (point.regionMapLink && point.oblastMapLink) {
			hRecord += '<a title="Přejít na stránku s detailními informacemi o regionu" href="' + point.regionMapLink + '" class="region">' + point.region_name + '</a>' +
			'  &nbsp;  ' + 
			'<a title="Přejít na stránku s detailními informacemi o oblasti" href="' + point.oblastMapLink + '" class="region">' + point.oblast_name + '</a><br/>';
		}
		if (description) {
			hRecord += description;
		}
		hRecord += "</li>";
		record = jQuery(hRecord);
		
		record.hover(function () {
			point.mapHighlight();
			point.listHighlight();
		},
		function () {
			point.mapUnhighlight();
			point.listUnhighlight();
		});
		record.click(function (e) {
			infoWindowShower.show(point);			
		});
		point.listHighlight = function () {
			record.addClass('hover');
		};
		point.listUnhighlight = function () {
			record.removeClass('hover');
		};
		qResultContainer.append(record);
	}
	/**
	 * rozhodne o tom zda se ma tab zobrazit ci ne. Prvni tab, ktery se ma zobrazit
	 * se nastavi jako defaultni
	 * @param tab - jQuery objekt tabu
	 * @param count - pocet vysledku kategorie tabu
	 */
	function showHideTab(tab, count) {
		if (count > 0) {
			tab.css('display', 'block');
			tab.find('.count').text(count);
		} else {
			tab.css('display', 'none');
		}
	}
	function highlightType(type) {
		qTabs.find('a').removeClass('active');
		qTabs.find('a.' + type).addClass('active');
	}
	/**
	 * zobrazi stranky aktivniho tabu
	 */
	function showPages(pages, page) {
		qPages.empty();
		if (pages === 0 || !pages) {
			return;
		}
		var pages_to_show = 8;
		var page_start = 1;
		var page_stop = pages;
		if (pages > pages_to_show) {
			if (page > (pages_to_show / 2)) {
				page_start = page - (pages_to_show / 2);
			}
			page_stop = page_start + pages_to_show;
			if (page_stop > pages) {
				page_start = pages - pages_to_show;
				page_stop = pages;
			}
		}
		
		for (var i = page_start; i <= page_stop; i++) {
			var qpage = jQuery('<a title="Zobrazit body na straně ' + i + '" href="#">' + i + '</a>');
			if (page == i) {
				qpage.css('font-weight', 'bold');
				qpage.click(function (e) {
					e.preventDefault();
				});
			} else {
				(function (toPage) {
					qpage.click(function (e) {
						e.preventDefault();
						switchPage(toPage);
					});
				})(i);
			}
			qPages.append(qpage);
			qPages.append('&nbsp;');
		}
		if (page != 1) {
			var qfirstpage = jQuery('<a title="Zobrazit body na první straně" href="#">&laquo;</a>');
			var qpreviouspage = jQuery('<a title="Zobrazit body na předchozí straně" href="#">&lt;</a>');
			qfirstpage.click(function (e) {
				e.preventDefault();
				switchPage(1);
			});
			qpreviouspage.click(function (e) {
				e.preventDefault();
				switchPage(page - 1);
			});			
			qPages.prepend(qpreviouspage);
			qPages.prepend(qfirstpage);
		}
		if (page != pages) {
			var qlastpage = jQuery('<a title="Zobrazit body na poslední straně" href="#">&raquo;</a>');
			var qnextpage = jQuery('<a title="Zobrazit body na další straně" href="#">&gt;</a>');
			qlastpage.click(function (e) {
				e.preventDefault();
				switchPage(pages);
			});
			qnextpage.click(function (e) {
				e.preventDefault();
				switchPage(page + 1);
			});
			qPages.append(qnextpage);
			qPages.append(qlastpage);			
		}
	}
	function switchTab(e) {
		e.preventDefault();
		var type = jQuery(this).attr('href');
		resultModel.changeActiveType(type);
	}
	function switchPage(page) {
		resultModel.changeActivePage(page);
	}
	return pub;	
};

/**
 * Obsahuje kriteria pro vyhledavani
 * Phrase
 */
vyletnik.search.Model = function () {
	var phrase;
	
	var region = 0;
	var regionChangeListeners = [];
	var oblast = 0;
	
	var locationChangeListeners = [];
	
	var rejstrikCategories = [];
	var sluzbyCategories = [];
	var turistickeInfoCategories = [];
	var adresy = false;
	
	var pub = {
		/**
		 * Nastavi frazi
		 */
		setPhrase : function (pPhrase) {
			phrase = pPhrase;
		},
		getPhrase : function () {
			return phrase;
		},
		/**
		 * slouzi k registrace posluchace, ktery reaguje na zmenu regionu
		 * posluchac musi implementovat metodu onRegionChange(idregionu)
		 */
		registerLocationChangeListener : function (listener) {
			locationChangeListeners[locationChangeListeners.length] = listener;
		},
		/**
		 * slouzi k registrace posluchace, ktery reaguje na zmenu regionu
		 * posluchac musi implementovat metodu onRegionChange(idregionu)
		 */
		registerRegionChangeListener : function (listener) {
			regionChangeListeners[regionChangeListeners.length] = listener;
		},
		/**
		 * nastavi id regionu
		 */
		setRegion : function (pregion) {
			region = pregion;
			pub.setOblast(0);
			triggerRegionChangeEvent(pregion);
			triggerLocationChangeEvent(region, oblast);			
		},
		getRegion : function () {
			return region;
		},
		hasRegion : function () {
			if (region === 0) {
				return false;
			}
			return true;			
		},
		setOblast : function (poblast) {
			oblast = poblast;
			triggerLocationChangeEvent(region, poblast);
		},
		getOblast : function () {
			return oblast;
		},
		hasOblast : function () {
			if (oblast == '0') {
				return false;
			}
			return true;
		},
		addRejstrikCategory : function (category) {
			rejstrikCategories[category] = true;
		},
		removeRejstrikCategory : function (category) {
			rejstrikCategories[category] = false;			
		},
		addSluzbyCategory : function (category) {
			sluzbyCategories[category] = true;
		},
		removeSluzbyCategory : function (category) {
			sluzbyCategories[category] = false;			
		},
		addTuristickeInfoCategory : function (category) {
			turistickeInfoCategories[category] = true;
		},
		removeTuristickeInfoCategory : function (category) {
			turistickeInfoCategories[category] = false;			
		},
		/**
		 * Zapnout vypnout vyhledavani v adresach
		 */
		adresy : function (flag) {
			adresy = flag;
		},
		/**
		 * Vytvori filtrovaci request, ktery se posila AJAXEM na server
		 */
		getRequestParam : function () {
			var params = {
				'phrase' : phrase,
				'region' : region,
				'oblast' : oblast,
				'rejstrikCategories[]' : getCategories(rejstrikCategories),
				'sluzbyCategories[]' : getCategories(sluzbyCategories),
				'turistickeInfoCategories[]' : getCategories(turistickeInfoCategories),
				'adresy' : adresy?'1':'0'
			};

			return params;
		}
	};
	
	function getCategories(data) {
		var result = [];
		jQuery.each(data, function (index, value) {
			if (value === true) {
				result[result.length] = index;
			}
		});
		return result;
	}
	/**
	 * privatni metoda zavolana pri zmene regionu
	 * notifikuje vsechny posluchace o tom ze se region zmenil
	 */
	function triggerRegionChangeEvent(region) {
		for (var i = 0; i < regionChangeListeners.length; i++) {
			regionChangeListeners[i].onRegionChange(region);
		}
	}	
	/**
	 * privatni metoda zavolana pri zmene regionu, nebo oblasti
	 * notifikuje vsechny posluchace o tom ze se lokace zmenila
	 */
	function triggerLocationChangeEvent(region, oblast) {
		for (var i = 0; i < locationChangeListeners.length; i++) {
			locationChangeListeners[i].onLocationChange(pub);
		}
	}	
	return pub;
};
/**
 * Pouziva se ke spusteni filtrovani bodu na mape, podle modelu filtru
 * model filtru obsahuje vsechny kriteria pro vyhledavani
 */
vyletnik.search.Invoker = function (searchModel, findedResultModel, failedPopup, loadingBar, filterResetor, nextPointInvokerAgent, tabPageUrlStore, focalizer, infoWindowShower) {
	var lastRequest;
	
	var nextPointInvoker = {
		invoke : function (type, page) {
			tabPageUrlStore.setTabPage(type, page);
			loadingBar.showLoading();
			jQuery.post('/hledat/' + type + '/' + page + '/', lastRequest, function (points) {
				findedResultModel.changeActivePoints(points);
				setMapStateByPoints(points);
				loadingBar.hideLoading();
				vyletnik.PageTracker.track('/hledat/' + type + '/' + page + '/');
			}, 'json');				
		}
	};
	var pub = {
		/**
		 * Tato metoda se spusti po stisku tlacitka na vyhledavani.
		 * Ma za ukol inciovat vyhledavani a dale deleguje nasledne
		 * zobrazeni vysledku
		 */
		invokeFiltering : function (tab, page) {
			findedResultModel.clearResult();
			if (searchModel.getPhrase().length < 3) {
				failedPopup.show();
			} else {
				nextPointInvokerAgent.setNextPointInvoker(nextPointInvoker);
				lastRequest = searchModel.getRequestParam();
				searchForRequest(lastRequest, tab, page);
			}
		},
		cancelSearch : function () {
			findedResultModel.clearResult();
		}
	};
	
	function searchForRequest(request, tab, page) {
		if (tab) {
			request.tab = tab;
		}
		if (page) {
			request.page = page;
		}
		loadingBar.showLoading();
		filterResetor.resetFilter();
		failedPopup.hide();
		jQuery.post('/hledat/', request, function (data) {
			findedResultModel.setResult(data, {name : 'Výsledek hledání'});
			setMapStateByPoints(data.points);
			loadingBar.hideLoading();
			vyletnik.PageTracker.track('/hledat/');
		}, "json");		
	}
	function setMapStateByPoints(points) {
		//najit body pro zamereni
		var minx = 9999, miny = 9999, maxx = 0, maxy = 0;
		for (var i = 0; i < points.length; i++) {
			var point = points[i];
			minx = Math.min(minx, point.x);
			maxx = Math.max(maxx, point.x);
			miny = Math.min(miny, point.y);
			maxy = Math.max(maxy, point.y);			
		}
		//pokud je nalezen pouze jeden výsledek, ihned zaměřit mapu na tento bod
		if (points.length === 1) {
			infoWindowShower.show(points[0]);
		} else if (points.length > 1) {
			//jinak zaměřit mapu tak, aby byli vidět všechny body
			focalizer.focalize(minx, miny, maxx, maxy);
		}		
	}
	return pub;
};

vyletnik.search.vokoli = {};
vyletnik.search.vokoli.Panel = function (searchInvoker, searchUrlStore, boundsGetter, topicsPanel, layerManager) {
	var qPanel;
	var qForm;
	var service = 'ubytovani-v-okoli';
	var distanceValue = 5;
	
	function hide() {
		qForm.css('display', 'none');
		boundsGetter.disableMarker();
	}
	function show() {
		layerManager.top(qForm);
		topicsPanel.hideAll();
		qForm.css('display', 'block');
		boundsGetter.initMarker();
	}
	return {
		init : function () {
			qPanel = jQuery('#topicPointShower .hledanivokoli');
			qForm = qPanel.find('form');
			qForm.click(function () {
				layerManager.top(qForm);
			});
			//rekneme nadrazenemu panelu jak nas ma zavrit
			topicsPanel.registerMember({
				hide : function () {
					hide();
				}
			});
			qPanel.find('a').click(function (e) {
				e.preventDefault();
				//schovat vsechny jen tehdy ze se mam objevit
				if (qForm.css('display') === 'none') {
					show();
				} else {
					hide();
				}
			});
			qPanel.find('input[type=submit]').click(function (e) {
				e.preventDefault();
				var x = boundsGetter.getCenterx();
				var y = boundsGetter.getCentery();
				var services = [];

				qPanel.find('input[type=checkbox]').each(function () {
					if (jQuery(this).attr('checked')) {
						services[services.length] = jQuery(this).val();
					}
				});

				searchUrlStore.setSearchRequest(services, x, y, distanceValue);
				searchInvoker.invokeSearch(services, x, y, distanceValue);
			});
			var slider = qPanel.find('.distance').slider({
				min : 5,
				max : 40,
				step : 1,
				slide : function (event, ui) {
					qPanel.find('.distance-value').html(ui.value);
					distanceValue = ui.value;
				}
			});
		}
	};
};
vyletnik.search.vokoli.Invoker = function (findedResultModel, loadingBar, nextPointInvokerAgent, tabPageUrlStore, boundsGetter, boundsDrawer, failedWindow) {
	var service;
	var lastRequest;
	
	var nextPointInvoker = {
		invoke : function (type, page) {
			tabPageUrlStore.setTabPage(type, page);
			loadingBar.showLoading();
			jQuery.post('/hledat-v-okoli/' + type + '/' + page + '/', lastRequest, function (points) {
				findedResultModel.changeActivePoints(points);
				loadingBar.hideLoading();
				vyletnik.PageTracker.track('/hledat-v-okoli/' + type + '/' + page + '/');
			}, 'json');
		}
	};
	
	//@todo presunout do invokeSearch a v cancelSearch odregistrovat
	findedResultModel.registerResultClearedListener(function () {
		boundsDrawer.removeCircle();
	});

	var pub = {
		invokeSearch : function (services, x, y, distance, type, page) {
			findedResultModel.clearResult();
			nextPointInvokerAgent.setNextPointInvoker(nextPointInvoker);
			loadingBar.showLoading();
						
			lastRequest = {
				x : x,
				y : y,
				distance : distance,
				'services[]' : services
			};
						
			if (type) {
				lastRequest.type = type;
			}
			if (page) {
				lastRequest.page = page;
			}
			//pokud je zvolen typ vyhledavani
			if (services.length > 0) {
				jQuery.post('/hledat-v-okoli/', lastRequest, function (result) {
					findedResultModel.setResult(result,  {name : 'Výsledek hledání v okolí'});
					loadingBar.hideLoading();
					boundsDrawer.showLocation(x, y, distance);
					vyletnik.PageTracker.track('/hledat-v-okoli/');
				}, 'json');
				failedWindow.hide();
			} else {
				failedWindow.show();
				loadingBar.hideLoading();
			}
		},
		cancelSearch : function () {
			findedResultModel.clearResult();
			failedWindow.hide();
		}
	};
	return pub;
};
vyletnik.search.vokoli.HistoryChangeListener = function (searchInvoker) {
	return function (params) {
		if (params.isChanged(['ox', 'oy', 'os', 'od', 'page', 'type'])) {
			var x = params.getString('ox');
			var y = params.getString('oy');
			var page = params.getString('page');
			var type = params.getString('tab');
			var services = params.getArray('os');
			var distance = params.getString('od');
			if (x && y && services.length > 0) {
				searchInvoker.invokeSearch(services, x, y, distance, type, page);
			} else if (page === '' && type === '') {
				searchInvoker.cancelSearch();
			}
		}
	};
};
vyletnik.search.NextPointInvokerAgent = function (nextPointsRequestedNotifier) {
	var nextPointsInvoker;
	
	return {
		run : function () {
			nextPointsRequestedNotifier.registerNextPointsRequestedListener({
				onNextPointsRequested : function (type, page) {
					nextPointsInvoker.invoke(type, page);
				}
			});		
		},
		setNextPointInvoker : function (invoker) {
			nextPointsInvoker = invoker;
		}
	};
};
vyletnik.search.FocalizerByModel = function (focalizer, locationModel) {
	function focalize(data) {
		if (data !== null) {
			focalizer.focalize(
				parseFloat(data.minx),
				parseFloat(data.miny),
				parseFloat(data.maxx),
				parseFloat(data.maxy)
			);
		}
	}

	return {
		focalizeMapByModel : function () {
			if (locationModel.hasOblast()) {
				jQuery.get('/oblast/', {'oblast' : locationModel.getOblast()}, focalize, "json");				
			} else {
				jQuery.get('/region/', {'region' : locationModel.getRegion()}, focalize, "json");
			}
		}
	};
};
vyletnik.search.PointShowingFactory = function () {
	var pointsSettedEvent = vyletnik.utils.Event();
	var pointsClearedEvent = vyletnik.utils.Event();
	
	return {
		getPointShower : function () {
			return {
				setPoints : function (points) {
					pointsSettedEvent.notifyListeners(points);
				},
				clearPoints : function () {
					pointsClearedEvent.notifyListeners();
				}
			};
		},
		getPointsClearedReporter : function () {
			return {
				registerListener : function (listener) {
					pointsClearedEvent.registerListener(listener);
				}
			};
		},
		getPointsSettedReporter : function () {
			return {
				registerListener : function (listener) {
					pointsSettedEvent.registerListener(listener);
				}
			};
		}
	};
};
vyletnik.search.HistoryChangeListener = function (phraseControl, locationControl, searchRejstrikCategories, searchSluzbyCategories, searchTuristickeInfoCategories, searchAdresy, searchInvoker) {
	return function (params) {
		if (params.isChanged(['phr', 'reg', 'obl', 's_rc', 's_sc', 's_tc', 's_a', 'tab', 'page'])) {
			if (params.getString('phr').length > 0) {
				phraseControl.setPhrase(params.getString('phr'));
				locationControl.setRegion(params.getString('reg'));
				locationControl.setOblast(params.getString('obl'));
				searchRejstrikCategories.select(params.getArray('s_rc'));
				searchSluzbyCategories.select(params.getArray('s_sc'));
				searchTuristickeInfoCategories.select(params.getArray('s_tc'));
				searchAdresy.check(params.getArray('s_a'));
				searchInvoker.invokeFiltering(params.getString('tab'), params.getString('page'));
			} else if (params.getString('tab') === '' && params.getString('page') === '') {
				searchInvoker.cancelSearch();
			}
		}
	};
};