vyletnik.filter = {};
vyletnik.filter.CilePanel = function (qPath, categories, topicsPanel, topicsCriteriaModifier, serializedGetter, urlModifier, urlParam) {
	var dontChangeModel = false;
	var dontChangeUrl = false;
	var pub = {
		init : function () {
			categories.init(qPath);
			categories.unselectAll();
			categories.added(function (cat) {
				if (dontChangeModel !== true) {
					topicsCriteriaModifier.addTopic(cat);
				}
				if (dontChangeUrl !== true) {
					urlModifier.set(serializedGetter.getSerialized());
				}
			});
			categories.removed(function (cat) {
				if (dontChangeModel !== true) {
					topicsCriteriaModifier.removeTopic(cat);
				}
				if (dontChangeUrl !== true) {
					urlModifier.set(serializedGetter.getSerialized());
				}
			});
			categories.onShow(function () {
				topicsPanel.hideAll();
			});
			//tento panel ma pak moznost zavrit vsechny otevrene podpanely
			topicsPanel.registerMember(categories);
		},
		select : function (values) {
			dontChangeModel = true;
			dontChangeUrl = true;
			categories.select(values);
			dontChangeModel = false;
			topicsCriteriaModifier.set(values);
			dontChangeUrl = false;
		},
		getHistoryChangeListener : function () {
			return function (params) {
				if (params.isChanged([urlParam])) {
					pub.select(params.getArray(urlParam));
				}
			};
		},
		show : function () {
			categories.show();
		}
	};
	return pub;
};
vyletnik.filter.TuristickeCilePanel = function (categories, topicsPanel, topicsCriteriaModifier, serializedGetter, urlModifier) {
	return vyletnik.filter.CilePanel("#topicPointShower .turistickecile", categories, topicsPanel, topicsCriteriaModifier, serializedGetter, urlModifier, 'f_rc');
};
vyletnik.filter.SluzbyPanel = function (categories, topicsPanel, topicsCriteriaModifier, serializedGetter, urlModifier) {
	return vyletnik.filter.CilePanel("#topicPointShower .ubytovaniasluzby", categories, topicsPanel, topicsCriteriaModifier, serializedGetter, urlModifier, 'f_sc');
};
vyletnik.filter.Resetor = function (turistickeCile, sluzby) {
	return {
		resetFilter : function () {
			turistickeCile.select([]);
			sluzby.select([]);
		}
	};
};
vyletnik.filter.FilterabilityPopupAgent = function (filterabilityChangeReporter, topicFilterabilityPopup) {
	var pub = {
		run : function () {
			filterabilityChangeReporter.registerFilteringDenyAnnuledListener({
				onFilteringDenyAnnuled : function () {
					topicFilterabilityPopup.hide();
				}
			});
			filterabilityChangeReporter.registerFilteringDeniedListener({
				onFilteringDenied : function () {
					topicFilterabilityPopup.show();
				}
			});
		}
	};
	return pub;
};
vyletnik.filter.FilterabilityPopup = function () {
	var qWindow;
	var pub = {
		init : function () {
			qWindow = jQuery('#pointsByTopicsNotShowed');
		},
		show : function () {
			qWindow.css("display", "block");
		},
		hide : function () {
			qWindow.css("display", "none");
		}
	};
	
	return pub;
};
vyletnik.filter.Model = function () {
	var turistickyCilTopics = [];
	var sluzbyTopics = [];
	var tipyNaVylet = false;
	var sw_x, sw_y, ne_x, ne_y;
	var zoom;
	
	var filteringStartedListeners = [];
	var filteringStoppedListeners = [];	
	var filteringDeniedListeners = [];
	var filteringDenyAnnuledListeners = [];
	
	var filteringAllreadyStart = false;
	var filteringAllreadyDenied = false;
	
	var allowedFilteringRequestListeners = [];
	
	var pub = {
		addTuristickyCilTopic : function (topic) {
			if (topic === 0) {
				tipyNaVylet = true;
			} else {
				turistickyCilTopics[topic] = true;
			}
			tryTriggerFilteringStarted();
			tryTriggerAllowedFilteringRequest();
		},
		setTuristickyCil : function (values) {
			turistickyCilTopics = [];
			tipyNaVylet = false;
			jQuery.each(values, function (index, topic) {
				if (parseInt(topic, 10) === 0) {
					tipyNaVylet = true;
				} else {
					turistickyCilTopics[topic] = true;
				}
			});
			
			tryTriggerFilteringStarted();
			tryTriggerAllowedFilteringRequest();
			tryTriggerFilteringStopped();
			tryTriggerFilteringDenyAnnuled();
		},
		removeTuristickyCilTopic : function (topic) {
			if (topic === 0) {
				tipyNaVylet = false;
			} else {
				turistickyCilTopics[topic] = false;
			}
			tryTriggerAllowedFilteringRequest();
			tryTriggerFilteringStopped();
			tryTriggerFilteringDenyAnnuled();
		},
		addSluzbyTopic : function (topic) {
			sluzbyTopics[topic] = true;
			tryTriggerFilteringStarted();
			tryTriggerAllowedFilteringRequest();
		},
		setSluzby : function (values) {
			sluzbyTopics = [];
			jQuery.each(values, function (index, topic) {
				sluzbyTopics[topic] = true;
			});
			tryTriggerFilteringStarted();
			tryTriggerAllowedFilteringRequest();
			tryTriggerFilteringStopped();
			tryTriggerFilteringDenyAnnuled();
		},
		removeSluzbyTopic : function (topic) {
			sluzbyTopics[topic] = false;
			tryTriggerAllowedFilteringRequest();
			tryTriggerFilteringStopped();
			tryTriggerFilteringDenyAnnuled();
		},
		setViewport : function (pzoom, psw_x, psw_y, pne_x, pne_y) {
			zoom = pzoom;
			sw_x = psw_x;
			sw_y = psw_y;
			ne_x = pne_x;
			ne_y = pne_y;
			tryTriggerFilteringStarted();			
			tryTriggerAllowedFilteringRequest();
			tryTriggerFilteringStopped();
			tryTriggerFilteringDenyAnnuled();
		},
		isFilteringRequested : function () {
			return isFilteringRequested();
		},
		/**
		 * registrace pro odchytavani povolenych pozadavku na filtrovani
		 */
		registerAllowedFilteringRequestListener : function (listener) {
			allowedFilteringRequestListeners[allowedFilteringRequestListeners.length] = listener;
		},
		/**
		 * registrace pro odchytavani startu filtrovani
		 */
		registerFilteringStartedListener : function (listener) {
			filteringStartedListeners[filteringStartedListeners.length] = listener;
		},
		/**
		 * registrace pro odchytavani ukonceni filtrovani.
		 * Stop filtrovani muze nastat z duvodu jeho zakazani, nebo proto ze jiz neni pozadovano
		 */
		registerFilteringStoppedListener : function (listener) {
			filteringStoppedListeners[filteringStoppedListeners.length] = listener;
		},
		/**
		 * registrace pro odchyceni udalosti, kdy pokus o start filtrovani byl zakazan
		 */
		registerFilteringDeniedListener : function (listener) {
			filteringDeniedListeners[filteringDeniedListeners.length] = listener;
		},
		/**
		 * registrace pro odchyceni udalosti, kdy se rusi zakaz filtrovani
		 * 1. Filtrovani jiz neni potreba
		 * 2. Filtrovani jiz je mozne provadet
		 */
		registerFilteringDenyAnnuledListener : function (listener) {
			filteringDenyAnnuledListeners[filteringDenyAnnuledListeners.length] = listener;
		},
		isZoomFilterable : function () {
			return isZoomFilterable();
		},
		getTuristickeCileSerializeGetter : function () {
			return {
				getSerialized : function () {
					var turistickeCileSerialized = vyletnik.utils.hashMapToVector(turistickyCilTopics);
					if (tipyNaVylet) {
						if (turistickeCileSerialized.length > 0) {
							turistickeCileSerialized = ',' + turistickeCileSerialized;
						}
						turistickeCileSerialized = '0' + turistickeCileSerialized;
					}
					return turistickeCileSerialized;
				}
			};
		},
		getSluzbySerializeGetter : function () {
			return {
				getSerialized : function () {
					return vyletnik.utils.hashMapToVector(sluzbyTopics);
				}
			};
		}
	};
	
	function getRequest() {
		var params = {
			'sw_x' : sw_x,
			'sw_y' : sw_y,
			'ne_x' : ne_x,
			'ne_y' : ne_y,				
			'turistickyCilTopics[]' : vyletnik.utils.hashMapToVector(turistickyCilTopics),
			'sluzbyTopics[]' : vyletnik.utils.hashMapToVector(sluzbyTopics),
			'tipyNaVylet' : tipyNaVylet
		};
		return params;
	}
	function isFilteringRequested() {
		if (vyletnik.utils.hashMapToVector(turistickyCilTopics).length > 0) {
			return true;
		} else if (vyletnik.utils.hashMapToVector(sluzbyTopics).length > 0) {
			return true;
		} else if (tipyNaVylet === true) {
			return true;
		}
		return false;
	}
	function isZoomFilterable() {
		return zoom > 7 ? true : false;
	}
	function isAllowedFilteringRequested() {
		if (isZoomFilterable() && isFilteringRequested()) {
			return true;
		}
		return false;
	}
	function tryTriggerAllowedFilteringRequest() {
		if (isAllowedFilteringRequested()) {
			triggerAllowedFilteringRequest();
		} else if (isZoomFilterable() === false && isFilteringRequested() === true && filteringAllreadyDenied === false) {
			triggerFilteringDenied();
			filteringAllreadyDenied = true;
		}
	}
	function triggerAllowedFilteringRequest() {
		for (var i = 0; i < allowedFilteringRequestListeners.length; i++) {
			var listener = allowedFilteringRequestListeners[i];
			listener.onAllowedFilteringRequest(getRequest());
		}
		lastAllowedFilteringRequested = true;		
	}
	function tryTriggerFilteringStarted() {
		if (filteringAllreadyStart === false && isAllowedFilteringRequested) {
			triggerFilteringStarted();
		}
	}
	function triggerFilteringStarted() {
		for (var i = 0; i < filteringStartedListeners.length; i++) {
			filteringStartedListeners[i].onFilteringStarted();
		}
		filteringAllreadyStart = true;
	}
	function tryTriggerFilteringStopped() {
		if (isAllowedFilteringRequested() === false && filteringAllreadyStart === true) {
			triggerFilteringStopped();
		}
	}
	function triggerFilteringStopped() {
		for (var i = 0; i < filteringStoppedListeners.length; i++) {
			var listener = filteringStoppedListeners[i];
			listener.onFilteringStopped();
		}
		filteringAllreadyStart = false;
	}
	function triggerFilteringDenied() {
		for (var i = 0; i < filteringDeniedListeners.length; i++) {
			var listener = filteringDeniedListeners[i];
			listener.onFilteringDenied();
		}		
	}
	function tryTriggerFilteringDenyAnnuled() {
		if (filteringAllreadyDenied === true && (isAllowedFilteringRequested() === true || isFilteringRequested() === false)) {
			triggerFilteringDenyAnnuled();
		}
	}
	function triggerFilteringDenyAnnuled() {
		for (var i = 0; i < filteringDenyAnnuledListeners.length; i++) {
			var listener = filteringDenyAnnuledListeners[i];
			listener.onFilteringDenyAnnuled();
		}
		filteringAllreadyDenied = false;
	}

	return pub;
};
vyletnik.filter.Invoker = function (loadingBar, pointShower) {
	var pub = {
		invokeFiltering : function (request) {
			loadingBar.showLoading();
			jQuery.post('/body/', request, proccessResult, "json");
		},
		stopFiltering : function () {
			pointShower.clearPoints();
		}
	};
	function proccessResult(data) {
		pointShower.setPoints(data);
		vyletnik.PageTracker.track('/body/');
		loadingBar.hideLoading();
	}
	return pub;
};
vyletnik.filter.InvokerAgent = function (filter, invoker) {
	return {
		run : function () {
			filter.registerAllowedFilteringRequestListener({
				onAllowedFilteringRequest : function (request) {
					invoker.invokeFiltering(request);
				}
			});
			filter.registerFilteringStoppedListener({
				onFilteringStopped : function () {
					invoker.stopFiltering();
				}
			});			
		}
	};
};
vyletnik.filter.Factory = function (filterModel) {
	return {
		getTuristickeCileTopicsCriteriaModifier : function () {
			return {
				addTopic : function (topic) {
					filterModel.addTuristickyCilTopic(topic);
				},
				removeTopic : function (topic) {
					filterModel.removeTuristickyCilTopic(topic);
				},
				set : function (values) {
					filterModel.setTuristickyCil(values);
				}
			};
		},
		getSluzbyTopicsCriteriaModifier : function () {
			return {
				addTopic : function (topic) {
					filterModel.addSluzbyTopic(topic);
				},
				removeTopic : function (topic) {
					filterModel.removeSluzbyTopic(topic);
				},
				set : function (values) {
					filterModel.setSluzby(values);
				}
			};
		},		
		getFilterabilityChangeReporter : function () {
			return filterModel;
		},
		getFilteringReporter : function () {
			return filterModel;
		},
		getViewPortCriteriaModifier : function () {
			return filterModel;
		}
		
	};
};
vyletnik.filter.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.filter.OpeningFiltering = function (turistickeCileTopicsPanel) {
	return {
		filter : function () {
			if (document.location.hash.length === 0) {
				turistickeCileTopicsPanel.show();
				turistickeCileTopicsPanel.select([1]);
			}
		}
	};
};