/*
=============================================================
						 COPY RIGHTS			
			-------------------------------------
			Przedsiebiorstwo Informatyczne WTSOFT
			-------------------------------------
=============================================================
*/

/**
 * ---------
 * WYMAGANIA
 * ---------
 * - jquery.js
 * 
 * ------------------------------------
 * OPCJE DLA ELEMENTOW HTML - NAVIGACJA
 * ------------------------------------
 * 
 * 
 * --------------------------------------
 * OPCJE DLA FUNKCJI $().googlemap({...})
 * --------------------------------------
 * - width - szerokosc mapy google - domyslnie 100%, podajemy z jednostkami (%, px, em)
 * - height - wysokosc mapy google - domyslnie 350px, podajmey z jednostkami (%, px, em)
 * - navi - nazwa atrypbutu dla elementow html do nawigacji
 * - lat, lng - dlugosc i szerokosc geograficzna poczatkowego ustawienia mapy
 * - zoom - poczatkowy zoom mapy
 * - startPoint - zaznacz poczatkowy punkt (true/false), gdy ustawiony zosatnie zaznaczony punkt poczatkowy zgodnie z startLat,startLng i startZoom, domyslnie false
 * - startLat, startLng - dlugosc i szerokosc geograficzna punktu poczatkowego
 * - startZoom - przyblizenie dla punktu poczatkowego
 * - zoombar - kontrolka z zoomem "small", "medium", "large" - domyslnie 'medium' 
 * - overwiev - kontrolka z rzutem ogolnym - domyslnie true
 * - scale - kontrolka ze skala - domyslnie true
 * - mapTypes - kontrolka z typami map - domyslnie true
 * - mapTypeNormal - typ mapy - mapa - domyslne true
 * - mapTypeSatelite - typ mapy - satelita - domyslne true
 * - mapTypeHybrida - typ mapy - hybryda - domyslne true
 * - mapTypePhysical - typ mapy - teren - domyslne true
 * - mapTypeStart - startowy typ mapy (normal, satelita, hybryda, teren) - domyslnie normal
 * - mapTypeNormalText - tekst dla typu mapy "mapa"
 * - mapTypeSateliteText - tekst dla typu mapy "satelita"
 * - mapTypeHybridaText - teskt dla typu mapy "hybryda"
 * - mapTypePhysicalText - tekst dla typu mapy "teren"
 * - dbcZoom - po podwojnym kliku przybliza true / false - domyslnie true
 * - scrollZoom - po scrolowaniu przybliza true / false - domyslnie true
 * - clickCallback - funkcja do wywolania po kliknieciu - parametry function(gMap, overlay, point)
 * --------- WYZNACZANIE TRASY --------------------
 * - access - mozliwosc wyznaczenia trasy dojazdu do miejsca - domyslnie false
 * - accessFromText - tekst dla inputa w wyznaczaniu trasy
 * - accessInfoElement - selektor jquery warstwy odpowiadajacej za informacje o trasie dojazdu
 * - accessInfoClearElement - selektro jquery do elementu po kliekniecu ktorego wyczyszczone zostana podpowiedzi dojazdu
 * - accessInfoShowAnimation - efekt pojawiania sie podpowiedzi - domyslnie "show"
 * - accessInfoShowSpeed - szybkosc wykonywania efektu
 * --------- WYZNACZANIE TRASY END ----------------
 * - defIcon - ustawienia domyslnej ikony markera {image : 'link', shadow : 'link', iconSize : 'x,y'/x, shadowSize : 'x,y'/x, iconAnchor : 'x,y'/x, infoWindowAnchor : 'x,y'/x}
 * - zoomArea - ustaw jezeli zoom ma byc dostosowany do wszystkich markerow - domyslanie true
 * - markers - lista poczatkowych marekrow na mapie [cords : 'lat,lng', title : 'tytul', desc : 'opis', icon : {image : 'link_do_ikony', shadow : 'link_do_cienia', iconSize : 'x,y', shadowSize : 'x,y', iconAnchor : 'x,y', infoWindowAnchor : 'x,y'}]
 * - markersList - jqSelector gdzie ma byc wyswietlona lista markerow
 * - draggableMarkers - jezeli true mozna przeciagac markery - domyslnie false
 * ........ FUNKCJE ZDARZENIOWE MARKERA .........
 * - markerDragstartCallback - funkcja wykonywna przy starcie przesuwania markera
 * - markerDragCallback - funkcja wykonywna podczas przesuwania markera
 * - markerDragendCallback - funkcja wykonywna po przeciagnieciu markera
 * - markerAddCallback - funkcja wykonywana po dodaniu markera
 * ---------- GEOLOKALIZACJA --------------
 * - defCountry - domyslne panstwo dla geolokalizacji
 * - noLocationText - tekst w przypadku braku lokalizacji
 */
(function($){
	$.fn.googlemap = function(settings){
		var sets = jQuery.extend({
			// Szerokosc mapy
			width : '100%',
			// Wysokosc mapy
			height : '350px',
			navi : 'jq-gmap',
			// Szerokosc i dlugosc geograficzna obszaru domyslnego
			lat: 52.173931692568,
			lng: 18.8525390625,
			// Przyblizenie domyslnego obszaru
			zoom : 6,
			// Punkt poczatkowy - jezeli ustawiony to zostanie wskazay punktu wedlug podanych lat, lng i zoom
			startPoint : false,
			// Szerokosc i dlugosc geograficzna dla punktu poczatkowego
			startLat : null,
			startLng : null,
			// Zoom dla punktu poczatkowego
			startZoom : 17,
			// Kontrolki
			zoombar : 'medium',
			overwiev : true,
			scale : true,
			mapTypes : true,
			// Typy map
			mapTypeNormal : true,
			mapTypeSatelite : true,
			mapTypeHybrid : true,
			mapTypePhysical : true,
			// Startowy typ mapy
			mapTypeStart : 'normal',
			// Typy map - tekst
			mapTypeNormalText : 'Mapa',
			mapTypeSateliteText : 'Satelita',
			mapTypeHybridText : 'Hybryda',
			mapTypePhysicalText : 'Teren',
			// Kontrola myszy
			dbcZoom : true,
			scrollZoom : true,
			// Funkcja do wykonania po kliku na mape
			clickCallback : null,
			// Trasa dojazdu
			access : false,
			accessFromText : 'Pokaż trasę do tego miejsca z:',
			accessInfoElement : null,
			accessInfoClearElement : null,
			accessInfoShowAnimation : "show",
			accessInfoShowSpeed : 300,
			// Domyslna ikona
			defIcon : null,	// {image : 'link', shadow : 'link', iconSize : 'x,y', shadowSize : 'x,y', iconAnchor : 'x,y', infoWindowAnchor : 'x,y'}
			// Ustaw zoom aby byly widoczne wszystkie markery
			zoomArea : true,
			// Poczatkowe markery
			markers : null,
			// JqSelector dla listy markerow
			markersList : null,
			// Mozliwosc przeciagania markerow
			draggableMarkers : false,
			// Funkcje zdarzeniowe dla markerow
			markerDragstartCallback : null,
			markerDragCallback : null,
			markerDragendCallback : null,
			markerAddCallback : null,
			// GEOLOKALIZACJA
			defCountry : 'Polska'
		},settings);
		
		// Przepisanie pasujacych elementow
		var self = this;
		// Zmienna przechowujaca obiekt(y) mapy
		var gMap = null;
		// Geokodowanie
		var geocoder = null;
		// Dostosuj zoom uwzgledniajac wszystkie markery widoczne
		var zoomArea = null;
		var zoomAreaPoint = null;
		
		// LOKALIZACJA
		var _location = {};
		
		//---------------------------------
		// Ustaw widok - parametry warstwy
		//---------------------------------
		function setView(obj){
			if(!obj || obj.length == 0) return false;
			// Ustaw rozmiar warstwy na mape
			obj.css({
				width : sets.width,
				height : sets.height
			});
			return true;
		}
		
		// Pokaz
		function show(obj){
			if(!obj || typeof(obj) != 'object') return false;
			switch(sets.accessInfoShowAnimation){
				case 'slide':
					obj.slideDown(sets.accessInfoShowSpeed);
					break;
				case 'show':
					obj.show(sets.accessInfoShowSpeed);
					break;
				case 'fade':
				default:
					obj.fadeIn(sets.accessInfoShowSpeed);
					break;
			}
		}
		// Schowaj
		function hide(obj){
			if(!obj || typeof(obj) != 'object') return false;
			switch(sets.accessInfoShowAnimation){
				case 'slide':
					obj.slideUp(sets.accessInfoShowSpeed);
					break;
				case 'fade':
					obj.fadeOut(sets.accessInfoShowSpeed);
					break;
				case 'hide':
				default:
					obj.hide(sets.accessInfoShowSpeed);
				break;
			}
		}
		
		//-----------------------------------
		// Funkcje generuje ikone dla markera
		//-----------------------------------
		function getIcon(opt){
			if(!opt) opt = sets.defIcon;
			if(!opt || typeof(opt.image) != 'string' || !opt.iconSize) return G_DEFAULT_ICON;
			// Ustaw rozmiar ikony
			var iconSize = {};
			if(typeof(opt.iconSize) == 'string'){
				iconSize = opt.iconSize.split(',');
				if(!iconSize[1]) iconSize[1] = iconSize[0];
			}else if(typeof(opt.iconSize) == 'number'){
				iconSize[0] = opt.iconSize;
				iconSize[1] = opt.iconSize;
			}
			// Ustaw cien
			var shadowSize = {};
			if(!opt.shadow || typeof(opt.shadow) != 'string' || !opt.shadowSize) opt.shadow = '';
			else{
				if(typeof(opt.shadowSize) == 'string'){
					shadowSize = opt.shadowSize.split(',');
					if(!shadowSize[1]) shadowSize[1] = shadowSize[0];
				}else if(typeof(opt.shadowSize) == 'number'){
					shadowSize[0] = opt.shadowSize;
					shadowSize[1] = opt.shadowSize;
				}
			}
			
			// Ustaw icon anchor
			var iconAnchor = {};
			if(typeof(opt.iconAnchor) == 'string'){
				iconAnchor = opt.iconAnchor.split(',');
				if(!iconAnchor[1]) iconAnchor[1] = iconAnchor[0];
			}else if(typeof(opt.iconAnchor) == 'number'){
				iconAnchor[0] = opt.iconAnchor;
				iconAnchor[1] = opt.iconAnchor;
			}else{
				iconAnchor[0] = iconSize[0] / 2;
				iconAnchor[1] = iconSize[1];
			}
			
			// Ustaw info window anchor
			var infoWindowAnchor = {}
			if(typeof(opt.infoWindowAnchor) == 'string'){
				infoWindowAnchor = opt.infoWindowAnchor.split(',');
				if(!infoWindowAnchor[1]) infoWindowAnchor[1] = infoWindowAnchor[0];
			}else if(typeof(opt.infoWindowAnchor) == 'number'){
				infoWindowAnchor[0] = opt.infoWindowAnchor;
				infoWindowAnchor[1] = opt.infoWindowAnchor;
			}else{
				infoWindowAnchor[0] = iconSize[0] / 2;
				infoWindowAnchor[1] = 0;
			}
			
			// Sprawdz czy sa dobre ustawienia
			if(!opt.image || iconSize.length != 2) return G_DEFAULT_ICON;
			// Generuj ikone
			var icon = new GIcon();
			icon.image = opt.image;
			icon.iconSize = new GSize(iconSize[0], iconSize[1]);
			icon.shadow = opt.shadow;
			if(opt.shadow && shadowSize.length == 2)
				icon.shadowSize = new GSize(shadowSize[0], shadowSize[1]);
			icon.iconAnchor = new GPoint(iconAnchor[0], iconAnchor[1]);
			icon.infoWindowAnchor = new GPoint(infoWindowAnchor[0], infoWindowAnchor[1]);
			
			return icon;
		}
		
		//----------------------
		// Funkcja dodaje marker
		//----------------------
		function addMarker(lat, lng, title, desc, iconSets){
			if(!lat || !lng) return false;
			// Ustaw punkt zgodnie ze wspolzednymi
			var point = new GLatLng(lat,lng);
			
			var marker = new GMarker(point,{
				title : title,
				icon : getIcon(iconSets),
				draggable : sets.draggableMarkers
			});
			marker.txt = title;
			marker.lat = lat;
			marker.lng = lng;
			
			if(!desc) desc = title;
			
			var uniqAccessFormId = 'wts-form-google-access';
			GEvent.addListener(marker,'click',function(){
				info  = '<div style="width: 220px;">'+desc;
				// Dodaj formularz wyznaczajacy trase dojazdu
				if(sets.access && sets.accessInfoElement){
					info += '<br /><br />'+sets.accessFromText+'<br />';
					info += '<form id="'+uniqAccessFormId+'" style="width: 200px;" onsubmit="return false;">';
					info += '<input type="hidden" name="to" class="to" value="'+marker.lat+','+marker.lng+'" />'
					info += '<input type="text" class="from" value="" name="from" style="width: 100%; font-family: Verdana;" />';
					info += '</form>';
				}
				info += '</div>';
				marker.openInfoWindowHtml(info);
			});
			
			//------------------------------------------
			// Ustawienie nawigacj dla wyznaczania trasy
			//------------------------------------------
			if(sets.access && sets.accessInfoElement){
				// Wyznaczanie trasy
				GEvent.addListener(marker,'infowindowopen',function(){
					$('#'+uniqAccessFormId).submit(function(){
						from 	= $(':input.from', this).val();
						to 		= $(':input.to', this).val();
						sets.access.load('from: '+from+' to: @'+to);
						show($(sets.accessInfoElement));
						return false;
					})
				});
				// Czyszczenie trasy
				if(sets.accessInfoClearElement){
					$(sets.accessInfoClearElement).click(function(){
						sets.access.clear();
						// Wroc do poczatkowego polozenia mapy
						if(zoomAreaPoint && zoomAreaBounds)
							gMap.setCenter(zoomAreaPoint,zoomAreaBounds);
						else if(sets.startPoint){
							// Wycentruj mape
							gMap.setCenter(new GLatLng(parseFloat(sets.startLat),parseFloat(sets.startLng)), sets.startZoom);
						}else{
							// Wycentruj mape
							gMap.setCenter(new GLatLng(sets.lat,sets.lng),sets.zoom);
						}
						// Schowaj warstwe
						hide($(sets.accessInfoElement));
						marker.closeInfoWindow();
						return false;
					});
				}
			}
			
			//--------------------------------
			// FUNKCJE ZDARZENIOWE DLA MARKERA
			//--------------------------------
			if(sets.draggableMarkers){
				// Wykonaj funkcje przed przesunieciem markera
				if(typeof(sets.markerDragstartCallback) == 'function'){
					GEvent.addListener(marker, 'dragstart', function(){
						// Wykonaj funkcje po przesunieciu
						sets.markerDragstartCallback(marker);
					});
				}
				// Wykonaj funkcje podczas przesuwania markera
				if(typeof(sets.markerDragCallback) == 'function'){
					GEvent.addListener(marker, 'drag', function(){
						// Wykonaj funkcje po przesunieciu
						sets.markerDragCallback(marker);
					});
				}
				// Wykonaj funkcje po przesunieciu markera
				if(typeof(sets.markerDragendCallback) == 'function'){
					GEvent.addListener(marker, 'dragend', function(){
						// Wykonaj funkcje po przesunieciu
						sets.markerDragendCallback(marker);
					});
				}
			}
			
			// Dodaj marker do mapy
			gMap.addOverlay(marker);
			
			// Wykonaj funkjce po dodaniu markera
			if(typeof(sets.markerAddCallback) == 'function'){
				sets.markerAddCallback(marker);
			}
			
			return true;
		}
		
		//----------------------
		// FUNKCJA USUWA MARKERY
		//----------------------
		function clearMarkers(){
			// Wyczysc markery
			gMap.clearOverlays();
		}
		
		
		//----------------------------------------
		// Funkcja generuje mape google w obiekcie
		//----------------------------------------
		function generate(obj){
			if(!obj || obj.length == 0) return false;
			
			if(sets.zoomArea) zoomArea = new GLatLngBounds();
			
			// Jezeli obiekg google nie jest kompatybilny przerwij dzialanie
			if(!GBrowserIsCompatible()) return false;
			
			// Ustaw widok mapy
			setView(obj);
			// Tworzy obiekt mapy z wybranymi typami mapy
			gMap = new GMap2(obj.get(0),{mapTypes : []});
			
			// Obsluga dojazdu
			if(sets.access){
				var aice = $(sets.accessInfoElement).get(0);
				sets.access = new GDirections(gMap, (aice? aice : null));
				// Obsluga bledow wyznaczania trasy
				GEvent.addListener(sets.access, "error", function(){
					switch(sets.access.getStatus().code){
						case G_GEO_MISSING_QUERY:
						case G_GEO_MISSING_ADDRESS: 
							var er = 'Nie podano adresu!'; 
							break;
						case G_GEO_UNAVAILABLE_ADDRESS:
						case G_GEO_BAD_REQUEST:
						case G_GEO_SERVER_ERROR:
						case G_GEO_UNKNOWN_ADDRESS: 
							var er = 'Nie udało się geokodować adresu'; 
							break;
						case G_GEO_TOO_MANY_QUERIES: 
							var er = 'Przekroczono limit zapytań do strony Google'; 
							break;
						default: 
							var er = 'Nie udało się znaleźć przejazdu pomiędzy podanymi punktami';
					}
					$(accessInfoElement).append('<div class="errorMessage">Bład '+sets.access.getStatus().code+': '+accessInfoElement+'</div>');
				});
			}
			
			// Ustaw odpowiednie typy mapy
			var mapType = null;
			var mapTypeNames = {
				normal : 'Map',
				satalite : 'Satelite',
				hybrid : 'Hybrid',
				physical : 'Physical'
			};
			// NORMAL
			if(sets.mapTypeNormal){
				// Ustaw tlumaczenie nazwy
				if(sets.mapTypeNormalText) mapTypeNames.normal = sets.mapTypeNormalText; 
				// Stworz typ mapy
				mapType = new GMapType([G_NORMAL_MAP.getTileLayers()[0]], G_NORMAL_MAP.getProjection(), mapTypeNames.normal);
				// Dodaj mape
				gMap.addMapType(mapType);
			}
			// SATELITE
			if(sets.mapTypeSatelite){
				// Ustaw tlumaczenie nazwy
				if(sets.mapTypeSateliteText) mapTypeNames.satelite = sets.mapTypeSateliteText; 
				// Stworz typ mapy
				mapType = new GMapType([G_SATELLITE_MAP.getTileLayers()[0]], G_SATELLITE_MAP.getProjection(), mapTypeNames.satelite);
				// Dodaj mape
				gMap.addMapType(mapType);
			}
			// PHISICAL
			if(sets.mapTypePhysical){
				// Ustaw tlumaczenie nazwy
				if(sets.mapTypePhysicalText) mapTypeNames.physical = sets.mapTypePhysicalText; 
				// Stworz typ mapy
				mapType = new GMapType(G_PHYSICAL_MAP.getTileLayers(), G_PHYSICAL_MAP.getProjection(), mapTypeNames.physical);
				// Dodaj mape
				gMap.addMapType(mapType);
			}
			// HYBRID
			if(sets.mapTypeHybrid){
				// Ustaw tlumaczenie nazwy
				if(sets.mapTypeHybridText) mapTypeNames.hybrid = sets.mapTypeHybridText; 
				// Stworz typ mapy
				mapType = new GMapType(G_HYBRID_MAP.getTileLayers(), G_HYBRID_MAP.getProjection(), mapTypeNames.hybrid);
				// Dodaj mape
				gMap.addMapType(mapType);
				
			} 
			
			// Ustaw startowy typ mapy
			switch(sets.mapTypeStart){
				case 'satelite':
					gMap.setMapType(G_SATELLITE_MAP);
					break;
				case 'hybrid':
					gMap.setMapType(G_HYBRID_MAP);
					break;
				case 'physical':
					gMap.setMapType(G_PHYSICAL_MAP);
					break;
				case 'normal':
				default:
					break;
			}
			
			// Centruj mape
			gMap.setCenter(new GLatLng(sets.lat,sets.lng),sets.zoom);
			
			// Kontrolki
			// Typy mapy
			if(sets.mapTypes)
				gMap.addControl(new GMapTypeControl());
			// Zoom
			if(sets.zoombar == 'small')
				gMap.addControl(new GSmallZoomControl());
			else if(sets.zoombar == true || sets.zoombar == 'medium')
				gMap.addControl(new GSmallMapControl());
			else if(sets.zoombar == 'large')
				gMap.addControl(new GLargeMapControl());
			
			// Mini mapa
			if(sets.overwiev == true)
				gMap.addControl(new GOverviewMapControl());
			if(sets.scale == true)
				gMap.addControl(new GScaleControl());
			
			
			// Obsluga myszy
			// Przyblizanie po podwojnym kliknieciu
			gMap.enableContinuousZoom();
			if(sets.dbcZoom)
				gMap.enableDoubleClickZoom();
			// Przyblizanie za pomoca scrolla
			if(sets.scrollZoom)
				gMap.enableScrollWheelZoom();
			
			// Dodaj markery
			if(typeof(sets.markers) == 'object' && sets.markers != null){
				for(i in sets.markers){
					// Pobierz opcje markera
					var marker = sets.markers[i];
					// Jezeli sa wsystkie opcje dodaj marker
					if(typeof(marker['cords']) == 'string' && marker['cords'].length > 0){
						// Pobierz wspolrzedne markera
						var cords = marker['cords'].split(',');
						cords[0] = $.trim(cords[0]);
						cords[1] = $.trim(cords[1]);
						// Dodaj marker
						addMarker(cords[0],cords[1],marker['title'],marker['desc'],marker['icon']);
						// Jezeli jest wlaczona opca dostosowania zoom
						if(zoomArea && sets.zoomArea){
							zoomArea.extend(new GLatLng(cords[0],cords[1]));
						}
					}
				}
				if(zoomArea && sets.zoomArea){
					var zoomAreaBounds = gMap.getBoundsZoomLevel(zoomArea);
					zoomAreaPoint = zoomArea.getCenter();
					gMap.setCenter(zoomAreaPoint,zoomAreaBounds);
				}
			}
			
			//---------------------------
			// FUNKCJE DODATKOWE DLA MAPY
			//---------------------------
			// Wykonaj funkcje po kliknieciu na mape
			if(typeof(sets.clickCallback) == 'function'){
				GEvent.addListener(gMap, 'click', function(overlay, point){
					// Wykonaj funkcje po kliknieciu
					sets.clickCallback(gMap,overlay,point);
				});
			}
			
			// Obiekt geokodowania
			geocoder = new GClientGeocoder();
		}
		
		// WYSZUKAJ ADRES NA MAPIE
		function getLocationsByAddress(address, zoom, precision){
			if(!address || typeof(address) != 'string' || address.length == 0) return false;
			if(typeof(zoom) != 'number') zoom = 15;
			
			
			geocoder.getLocations(address, function(result){
				// Geokodowanie zakonczylo sie sukcesem - znaleziono lokalizacje
				if(result.Status.code == G_GEO_SUCCESS){
					if(result.Placemark.length > 1){
						// Wiecej niz jedna lokalizacja
					}else{
						// Pobierz wspolrzedne punkut [0] = lat, [1] = lng
						var point = result.Placemark[0].Point.coordinates;
						// Centruj mape
						gMap.setCenter(new GLatLng(parseFloat(point[1]),parseFloat(point[0])), zoom);
						// Dodaj marker
						addMarker(parseFloat(point[1]),parseFloat(point[0]));
					}
				}else{
					// Nie znaleziono zadnej lokalizacji
					if(precision == -1){
						clearMarkers();
						gMap.setCenter(new GLatLng(parseFloat(sets.lat),parseFloat(sets.lng)), sets.zoom);
					}else if(precision >= 0 && precision <= 3){
						// Sprawdz dla gorszej precyzji
						// Pobierz adres
						var newPrec = precision - 1;
						var addData = getAddress(_location, newPrec);
						// Ustaw marker wedlug adresu
						getLocationsByAddress(addData['address'], addData['zoom'], newPrec);
					}
				}
			});
		}
		
		// POBIERZ TYP LOKALIZACJI
		function getLocType(attr){
			if(!attr || typeof(attr) != 'string' || attr.length == 0) return false;
			
			var locType = '';
			if(attr.indexOf('loc-country') != -1) locType = 'country';
			else if(attr.indexOf('loc-state') != -1) locType = 'state';
			else if(attr.indexOf('loc-city') != -1) locType = 'city';
			else if(attr.indexOf('loc-address') != -1) locType = 'address';
				
			return locType;
		}
		// POBIERZ WARTOSC DO ODSWIERZENIA
		function getValue(obj,attr,type){
			if(!obj || typeof(obj) != 'object' || !attr || typeof(attr) != 'string') return false;
			
			var value = null;
			if(attr.indexOf('val-field') != -1){
				switch(type){
					case 'select':
						$('option',obj).each(function(){
							if($(this).get(0).selected == true){
								value = $(this).html();
							}
						});
						break;
					default:
						value = obj.html();
					break;
				}
			}else value = obj.val();
			
			return value;
		}
		// USTAW ADRES NA PODSTAWIE LOKALIZACJI
		/*
		 * PRECISION
		 * 1 - panstwo, wojewodztwo
		 * 2 - panstwo, wojewodztwo, miasto
		 * 3 - panstwo, wojewodztwo, miasto, adres
		 */
		function getAddress(location, precision){
			if(typeof(location) != 'object') return false;
			
			// Zoom
			var zoom = 5;
			var adr = typeof(location['country']) != 'undefined'? location['country'] : sets.defCountry;
			
			if(!precision || (precision && precision >= 1)){
				if(typeof(location['state']) != 'undefined' && location['state'].length > 0){
					adr += ' '+location['state'];
					zoom = 6;
				}
			}
			if(!precision || (precision && precision >= 2)){
				if(typeof(location['city']) != 'undefined' && location['city'].length > 0){
					adr += ' '+location['city'];
					zoom = 11;
				}
			}
			if(!precision || (precision && precision >= 3)){
				if(typeof(location['address']) != 'undefined' && location['address'].length > 0){
					adr += ' '+location['address'];
					zoom = 15;
				}
			}
			
			return {
				'address' : adr,
				'zoom' : zoom
			};
		}
		
		
		//--------------
		// WYKONAJ AKCJE 
		//--------------
		function action(obj, type){
			if(typeof(obj) != 'object' || obj.length == 0) return false;
			
			// Pobierz atrybuty obiektu
			var attributes = obj.attr(sets.navi);
			
			// Pobierz typ lokalizacji
			var locType = getLocType(attributes);
			// Pobierz wartosc typu
			_location[locType] = getValue(obj,attributes,type);
			
			// Pobierz adres
			var addData = getAddress(_location);
			// Wyczysc markery
			clearMarkers();
			// Ustaw marker wedlug adresu
			getLocationsByAddress(addData['address'], addData['zoom'], 3);
		}
		
		//----------------
		// Ustaw nawigacje
		//----------------
		function setNavigation(){
			// Odswierzanie wspolrzednych markera
			// CHANGE
			$('select['+sets.navi+'*="refresh"]').change(function(){
				action($(this),'select');
			});
			$(':text['+sets.navi+'*="refresh"], textarea['+sets.navi+'*="refresh"], :checkbox['+sets.navi+'*="refresh"], :radio['+sets.navi+'*="refresh"]').change(function(){
				action($(this));
			});
		}
		
		//-----------------------
		// USTAW POCZATKOWY ADRES
		//-----------------------
		function setStartAddress(){
			// Dla select
			$('select['+sets.navi+'*="loc-country"], select['+sets.navi+'*="loc-state"], select['+sets.navi+'*="loc-city"], select['+sets.navi+'*="loc-address"]').each(function(){
				// Pobierz atrybuty
				var attributes = $(this).attr(sets.navi);
				// Pobierz typ lokalizacji
				var locType = getLocType(attributes);
				// Pobierz wartosc typu
				_location[locType] = getValue($(this),attributes,'select');
			});
			$(':text['+sets.navi+'*="loc-country"], :text['+sets.navi+'*="loc-state"], :text['+sets.navi+'*="loc-city"], :text['+sets.navi+'*="loc-address"], textarea['+sets.navi+'*="loc-country"], textarea['+sets.navi+'*="loc-state"], textarea['+sets.navi+'*="loc-city"], textarea['+sets.navi+'*="loc-address"], :checkbox['+sets.navi+'*="loc-country"], :checkbox['+sets.navi+'*="loc-state"], :checkbox['+sets.navi+'*="loc-city"], :checkbox['+sets.navi+'*="loc-address"], :radio['+sets.navi+'*="loc-country"], :radio['+sets.navi+'*="loc-state"], :radio['+sets.navi+'*="loc-city"], :radio['+sets.navi+'*="loc-address"],').each(function(){
				// Pobierz atrybuty
				var attributes = $(this).attr(sets.navi);
				// Pobierz typ lokalizacji
				var locType = getLocType(attributes);
				// Pobierz wartosc typu
				_location[locType] = getValue($(this),attributes);
			});
			
			// Sprawdz czy jest ustawiony punkut poczatkowy
			if(sets.startPoint == true){
				// Wyczysc markery
				clearMarkers();
				// Wycentruj mape
				gMap.setCenter(new GLatLng(parseFloat(sets.startLat),parseFloat(sets.startLng)), sets.startZoom);
				// Dodaj marker dla punktu poczatkowego
				addMarker(parseFloat(sets.startLat),parseFloat(sets.startLng));
			}else if(_location['country'] || _location['city'] || _location['state'] || _location['address']){
				// Nie ma punktu poczatkowego, wyznacz lokalizacje zgodnie z ustawieniami formularza
				// Pobierz adres
				var addData = getAddress(_location);
				// Wyczysc markery
				clearMarkers();
				// Ustaw marker wedlug adresu
				getLocationsByAddress(addData['address'], addData['zoom']);
			}
		}
		
		// Funkcja ustawiajaca dane poczatkowe
		function initialize(){
			// Jezeli nie ma obiektow to wyjdz z funkcji
			if(!self) return false;
			if(!self.is(':visible')){
				var intervalId = setInterval(function(){
					if(self.is(':visible')){
						// Wyczysc interval
						clearInterval(intervalId);
						// Generuj mape google
						generate(self);
						// Ustaw nawigacje
						setNavigation();
						// Ustaw poczatkowa lokalizacje
						setStartAddress();
					}
				},500);
			}else{
				// Generuj mape google
				generate(self);
				// Ustaw nawigacje
				setNavigation();
				// Ustaw poczatkowa lokalizacje
				setStartAddress();
			}
		}
		initialize();
	}
})(jQuery);

/**
 * Funkcja do pobierania wspolzednych podanego adresu
 * 
 */
(function($){
	$.fn.gmapGetLatLng = function(settings){
		var sets = jQuery.extend({
			// GEOLOKALIZACJA
			// Panstwo
			country : 'Polska',
			// Wojewodztwo
			state : null,
			// Miasto
			city : null,
			// Adres
			address : null,
			// Selektory elementow z ktorych pobieramy wartosci
			countrySel : null,
			stateSel : null,
			citySel : null,
			address : null
		},settings);
		
		// Przepisanie pasujacych elementow - element do ktorego ma byc przpisana wartosc wspolzednych lokalizacji
		var self = this;
		// Geokodowanie
		var geocoder = null;
		
		
		// WYSZUKAJ ADRES NA MAPIE
		function getLocationsByAddress(address){
			if(!address || typeof(address) != 'string') return false;
			geocoder.getLocations(address, function(result){
				// Geokodowanie zakonczylo sie sukcesem - znaleziono lokalizacje
				if(result.Status.code == G_GEO_SUCCESS){
					if(result.Placemark.length == 1){
						// Pobierz wspolrzedne punkut [0] = lat, [1] = lng
						var point = result.Placemark[0].Point.coordinates;
						self.val(parseFloat(point[1])+','+parseFloat(point[0]));
					}
				}
			})
		}
		
		// Funkcja ustawia adres do pobrania wspolzednych
		function setAddress(){
			// Pobierz panstwo
			var country = null;
			if(sets.countrySel != null){
				country = $(sets.countrySel).val();
			}
			if(!country) country = sets.country;
			// Pobierz wojewodztwo
			var state = null;
			if(sets.stateSel != null) state = $(sets.stateSel).val();
			if(!state) state = sets.state;
			// Pobierz miasto
			var city = null;
			if(sets.citySel != null) city = $(sets.citySel).val();
			if(!city) city = sets.city;
			// Pobierz adres
			var address = null;
			if(sets.addressSel != null) city = $(sets.addressSel).val();
			if(!address) address = sets.address;
			
			var addr = '';
			if(country) addr += country;
			if(state){
				addr += (addr? ', ' : '')+state;
			}
			if(city){
				addr += (addr? ', ' : '')+city;
			}
			if(address){
				addr += (addr? ', ' : '')+address;
			}
			
			getLocationsByAddress(addr);
		}
		
		// Ustaw nawigacje
		function setNavigation(){
			// Panstwo
			if(sets.countrySel){
				$(sets.countrySel).change(function(){
					setAddress();
				})
				$(sets.countrySel).keyup(function(){
					setAddress();
				})
			}
			// Wojewodztwo
			if(sets.stateSel){
				$(sets.stateSel).change(function(){
					setAddress();
				})
				$(sets.stateSel).keyup(function(){
					setAddress();
				})
			}
			// Miasto
			if(sets.citySel){
				$(sets.citySel).change(function(){
					setAddress();
				})
				$(sets.citySel).keyup(function(){
					setAddress();
				})
			}
			// Adres
			if(sets.addressSel){
				$(sets.addressSel).change(function(){
					setAddress();
				})
				$(sets.addressSel).keyup(function(){
					setAddress();
				})
			}
		}
		
		// Funkcja ustawiajaca dane poczatkowe
		function initialize(){
			// Jezeli nie ma obiektow to wyjdz z funkcji
			if(!self) return false;
			// Jezeli obiekg google nie jest kompatybilny przerwij dzialanie
			if(!GBrowserIsCompatible()) return false;
			// Obiekt geokodowania
			geocoder = new GClientGeocoder();
			// Ustaw nawigacje
			setNavigation();
		}
		
		initialize();
	}
})(jQuery);
