var vyletnik = {};

/**
 * Slouzi k inicializaci a spusteni cele aplikaci
 */
vyletnik.Launcher = function (initializer, plugins) {
	var pub = {
		run : function () {
			initializer.init();
			if (plugins) {
				jQuery.each(plugins, function (key, plugin) {
					plugin.run();
				});
			}
		}
	};
	
	return pub;
};

/**
 * Formular cele aplikace
 * @param locationModel - pouzivan na zjisteni aktualni nastavene lokace
 */
vyletnik.MainForm = function (map) {
	var finderPanel;
	
	var pub = {
		/**
		 * Schova vyhledavaci panel, a roztahne mapu
		 */
		hideFinderPanel : function () {
			finderPanel.hide();
			map.expand();
		},
		/**
		 * Ukaze vyhledavaci panel a smrskne mapu
		 */
		showFinderPanel : function () {
			finderPanel.show();
			map.straiten();
		},
		setFinderPanel : function (panel) {
			finderPanel = panel;
		}
	};
	
	return pub;
};

/**
 * Implementace mapy
 */
vyletnik.MapPanel = function (element, mapInitializer, findedPointsManager, filteredPointsManager) {
	/**
	 * jQuery map container
	 */
	var qMap;
	
	var pub = {
		init : function () {
			qMap = jQuery(element);
			mapInitializer.init(qMap[0]);
		},
		/**
		 * Roztahne mapu pres celou obrazovku
		 */
		expand : function () {
			qMap.animate({left : '13px'}, 1000, function () {
				
			});
			//pro IE6 se musi roztahnout jeste width
			if (qMap.css('right') == 'auto') {
				qMap.css('width', (document.body.offsetWidth - 13) + 'px');				
			}
		},
		/**
		 * Smrskne mapu zpet
		 */
		straiten : function () {
			qMap.animate({left : '263px'}, 1000);
			//pro IE6 se musi smrsknout jeste width
			if (qMap.css('right') == 'auto') {
				qMap.css('width', (document.body.offsetWidth - 263) + 'px');				
			}			
		}
	};

	return pub;
};
vyletnik.DetailInMapPanel = function () {
	var qPanel;
	return {
		init : function () {
			qPanel = jQuery('#detailPanel');
			qPanel.find('a.closeButton').click(function (e) {
				e.preventDefault();
				qPanel.css('display', 'none');
			});
			
			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');
					qPanel.find('.hledatVOkoli').css('display', 'block');
				} else {
					minimizable.css('display', 'none');
					qPanel.css('bottom', 'auto');
					qPanel.css('height', '55px');
					qPanel.find('.hledatVOkoli').css('display', 'none');
				}
			});
		}
	};
};
vyletnik.TopicsPanel = function () {
	var members = [];

	//prekreslovaci metoda pro operu
	function redraw() {
		jQuery('#topicPointShower').css('visibility', 'hidden');
		setTimeout(function () {
			jQuery('#topicPointShower').css('visibility', 'visible');
		}, 1);
	}

	return {
		registerMember : function (member) {
			members[members.length] = member;
		},
		hideAll : function () {
			jQuery.each(members, function (k, member) {
				member.hide();
			});
			if (jQuery.browser.opera === true) {
				redraw();
			}
		}
	};
};
vyletnik.PointDetailGetter = function (detailZoomer) {
	return {
		withDetail : function (ptype, pid, handler) {
			jQuery.get("/pointInfoWindow/" + ptype + "/", {id : pid}, function (data) {
				var tabMaker = vyletnik.InfoWindowTabMaker(detailZoomer);
				
				var jInfoTab = tabMaker.makeTab(data.infoTab, data.point);
				var jPhotoTab = tabMaker.makeTab(data.fotoTab, data.point);
				var jGpsTab = tabMaker.makeTab(data.gpsTab, data.point);
				var jLinksTab = tabMaker.makeTab(data.linksTab, data.point);
				
				jPhotoTab.find('[rel=lightbox]').lightbox();
				
				handler({
					'infoTab' : jInfoTab[0],
					'photoTab' : jPhotoTab[0],
					'gpsTab' : jGpsTab[0],
					'linksTab' : jLinksTab[0]				
				});
				vyletnik.PageTracker.track("/pointInfoWindow/" + ptype + "/");
			}, 'json');
		}
	};
};
/**
 * Vytvari taby pro konkretni info window
 */
vyletnik.InfoWindowTabMaker = function (detailZoomer) {
	var zoomButtons = function () {
		var jButtonPairs = [];
		return {
			add : function (buttonPair) {
				jButtonPairs[jButtonPairs.length] = buttonPair;
			},
			showZoomIn : function () {
				jQuery.each(jButtonPairs, function (index, buttonPair) {
					buttonPair.zoomIn.css('display', 'inline');
					buttonPair.zoomOut.css('display', 'none');
				});
			},
			showZoomOut : function () {
				jQuery.each(jButtonPairs, function (index, buttonPair) {
					buttonPair.zoomOut.css('display', 'inline');
					buttonPair.zoomIn.css('display', 'none');
				});				
			}
		};
	}();
	return {
		makeTab : function (html, point) {
			var jTab = jQuery(html);
			var jPriblizitButton = jTab.find('a.priblizit');
			var jOddalitButton = jTab.find('a.oddalit');
			var commentsButton = jTab.find('a.commentsButton');
			
			zoomButtons.add({
				zoomIn : jPriblizitButton,
				zoomOut : jOddalitButton
			});
			
			jPriblizitButton.click(function (e) {
				e.preventDefault();
				detailZoomer.zoomTo(point);
				zoomButtons.showZoomOut();
			});
			jOddalitButton.click(function (e) {
				e.preventDefault();
				detailZoomer.zoomOut();
				zoomButtons.showZoomIn();
			});
			
			commentsButton.click(function (e) {
				e.preventDefault();
				window.open(jQuery(this).attr('href'), "_blank", "width=600,height=500,scrollbars=yes");
			});
			return jTab;
		}
	};
};
vyletnik.FocalizationAgent = function (locationChangeReporter, focalizer) {
	return {
		run : function () {
			locationChangeReporter.registerLocationChangeListener({
				onLocationChange : function () {
					focalizer.focalizeMapByModel();
				}
			});		
		}
	};
};
vyletnik.urlControl = function () {
	var lastHash = '';
	var changeDisabled = false;
	var ieHistoryInited;
		
	var historyKeeper = function () {
		return { 
			set : function (hash) {
				document.location.hash = hash;
			},
			get : function () {
				return location.hash;
			}
		};
	}();
	function initHistoryForIe() {
		if (!ieHistoryInited) {
			historyKeeper = function () {
				var iframe = jQuery('<iframe id="ui-history-iframe" style="display:none"></iframe>').
				prependTo(document.body)[0];
				iframe.contentWindow.document.open();
				iframe.contentWindow.document.close();			
				
				(function synchronizeHashes() {
					setTimeout(function () {
						if (document.location.hash != iframe.contentWindow.document.location.hash) {
							document.location.hash = iframe.contentWindow.document.location.hash;
						}
						synchronizeHashes();
					}, 200);
				})();
				return { 
					set : function (hash) {
						iframe.contentWindow.document.open();
						iframe.contentWindow.document.close();			
						iframe.contentWindow.document.location.hash = hash;
					},
					get : function () {
						return iframe.contentWindow.document.location.hash;
					}
				};
			}();
			ieHistoryInited = true;
		}
	}	

	function setHash(str) {
		if (jQuery.browser.msie && parseInt(jQuery.browser.version, 10) < 8) {
			initHistoryForIe();
		}
		historyKeeper.set(str);
		changeDisabled = true;
	}
	function getHash() {
		return historyKeeper.get().replace('#', '');
	}
	function assembleHash(add, remove) {
		var currentHashData = decodeHash(getHash());
		jQuery.each(add, function (key, value) {
			currentHashData[key] = value;
		});
		if (remove) {
			jQuery.each(remove, function (key, value) {
				delete currentHashData[value];
			});
		}
		return encodeToHash(currentHashData);
	}
	function setToHash(add, remove) {
		var currentHash = assembleHash(add, remove);
		setHash(currentHash);
	}
	function setToHashOnRoot(add, remove) {
		var hash = assembleHash(add, remove);
		var pathname = document.location.pathname.toString();
		//vyhledavani musi byt provedeno pouze z adresy /
		if (pathname.replace('/', '').length > 0) {
			document.location.href = '/#' + hash;
		} else {
			setHash(hash);
		}
	}
	function decodeHash(hash) {
		var params = [];
		if (hash.length) {
			params = hash.split('@');
		}
		
		var result = {};
		jQuery.each(params, function (index, param) {
			var param_data = param.split('=');
			if (param_data.length == 2) { 
				result[param_data[0]] = param_data[1];
			}
		});
		return result;
		
	}
	function encodeToHash(data) {
		var hashString = '';
		jQuery.each(data, function (key, value) {
			if (hashString.length > 0) {
				hashString += '@';
			}
			hashString += key + '=' + value;
		});
		return hashString;
	}
	function setString(param, value) {
		var hashParams = decodeHash();
		hashParams[param] = value;
		setHash(encodeHash(hashParams));
	}
	function hashChanged(handler) {
		if (changeDisabled === false && getHash() != lastHash) {
			handler();
			lastHash = getHash();
		}
		lastHash = getHash();
		changeDisabled = false;
	}
	function getChangedParams() {
		var lastData = decodeHash(lastHash);
		var currentData = decodeHash(getHash());
		var changedParams = {};
		jQuery.each(currentData, function (param, value) {
			if (lastData[param] != currentData[param]) {
				changedParams[param] = true;
			}
		});
		jQuery.each(lastData, function (param, value) {
			if (lastData[param] != currentData[param]) {
				changedParams[param] = true;
			}
		});		
		return changedParams;		
	}
	function getFilterUrlSetter(param) {
		return {
			set : function (values) {
				var data = {};
				data[param] = values;
				setToHash(data);
			}
		};
	}
	return {
		getSearchUrlStore : function () {
			var clear = [];
			return {
				setSearchRequest : function (request) {
					setToHashOnRoot({
						phr : request.phrase,
						reg : request.region,
						obl : request.oblast,
						s_rc : request['rejstrikCategories[]'],
						s_sc : request['sluzbyCategories[]'],
						s_tc : request['turistickeInfoCategories[]'],
						s_a : request.adresy
					}, clear.concat(['tab', 'page']));
				},
				/**
				 * Jakakoliv akce ktera vylucuje spusteni teto akce dostane parametry
				 * ktere kdyz neexistuji, tato akce se neprovede
				 */
				clearWith : function () {
					return ['phr', 'reg', 'obl', 's_rc', 's_sc', 's_tc', 's_a', 'tab', 'page'];					
				},
				clearMe : function (pclear) {
					clear = clear.concat(pclear);
				}
			};
		},
		getTabPageUrlStore : function () {
			return {
				setTabPage : function (tabname, number) {
					setToHash({
						page : number,
						tab : tabname
					}, 'tabPage');
				}
			};
		},
		getFilterUrlStore : function () {
			return {
				setFilterRequest : function (request) {
					setToHash(request, 'filter');
				}
			};
		},
		getPositionUrlSetter : function () {
			return {
				setPosition : function (x, y, zoom) {
					setToHash({
						x : x,
						y : y,
						z : zoom
					}, 'position');
				}
			};
		},
		getTuristickeCileFilterUrlSetter : function () {
			return getFilterUrlSetter('f_rc');
		},
		getSluzbyFilterUrlSetter : function () {
			return getFilterUrlSetter('f_sc');
		},
		getHledaniOkoliUrlsSetter : function (searchUrlStore) {
			searchUrlStore.clearMe(['ox', 'oy', 'os', 'od']);
			return {
				setSearchRequest : function (services, x, y, distance) {
					setToHashOnRoot({ox : x,
						oy : y,
						od : distance,
						os : services
					},
					searchUrlStore.clearWith().concat(['tab', 'page']));
				}
			};			
		},
		getUrlRequestAgent : function (changeListeners) {
			function check() {
				hashChanged(function () {
					var changedParams = getChangedParams();
					var params = decodeHash(getHash());
					
					function getString(param) {
						if (!params[param]) {
							return '';
						}
						return params[param];						
					}
					jQuery.each(changeListeners, function (index, listener) {
						listener({
							getString : function (param) {
								return getString(param);
							},
							getArray : function (param) {
								return vyletnik.utils.unserializeArray(getString(param));
							},
							isChanged : function (paramsToCheck) {
								var changed = false;
								jQuery.each(paramsToCheck, function (index, param) {
									if (changedParams[param]) {
										changed = true;
										return;
									}
								});
								return changed;
							}
						}, changedParams);
					});
				});
				start();
			}
			function start() {
				setTimeout(check, 200);
			}			
			return {
				run : function () {
					start();
				}
			};
		}
	};
}();
vyletnik.PointEditer = function () {
	var qGpsLabel = jQuery('#editPoint_gps');
	var qLatHidden = jQuery('#editPoint_x');
	var qLngHidden = jQuery('#editPoint_y');
	
	return {
		setLatLng : function (lat, lng) {
			qLatHidden.val(lat);
			qLngHidden.val(lng);
			qGpsLabel.text(vyletnik.utils.getGpsString(lat) + 'N ' + vyletnik.utils.getGpsString(lng) + 'E');
		}
	};
};
/**
 * Posila tracking informace na google analytics a gemius
 */
vyletnik.PageTracker = function () {
	return {
		track : function (address) {
			pageTracker._trackPageview(address);
			//pp_gemius_hit(pp_gemius_identifier);
		}
	};
}();