
function GoogleMAP (id, lat, lon, zoom, type)
{
	this._iSaveLocationId = 0; // override this
	this._sLoadingId = '';

	this._iId = id;
	this._fLat = lat.length ? parseFloat (lat) : 0;
	this._fLon = lon.length ? parseFloat (lon) : 0;
	this._iZoom = zoom.length ? parseInt (zoom) : 1;

	this._map = null;

	this._iMapType = type.length ? parseInt(type) : 0;
	this._iMapControl = 1;
	this._isTypeControl = true;
	this._isScaleControl = true;
	this._isOverviewControl = true;
	this._isDragable = true;
	this._sCustomType = 'all';

    this._iSaveMapType = this._iMapType;
    this._iSaveZoom = this._iZoom;
    this._fSaveLat = this._fSaveLng = 0;

    this._iClickable = 0;

    this.sLangPositionSaved = 'Location has been succesfully saved';
    this.sLangPositionSaveFailed = 'Location saving failed';
    this.sLangGeocodeFailed = "Can not geocode following location:\n";
    this.sLangSelectLocation = "Please select location first";

    this.sActionsFile = 'override this';
    this.sActionShowLocations = 'override this';
}

GoogleMAP.prototype.init = function ()
{
	google.load("maps", "2.x");

	var $this = this;

	var h = function ()
	{
		if (!GBrowserIsCompatible()) {
			alert ("Sorry your browser is incompatible with Google Maps");
			return;
		}	

        $this.preload();

		glGoogleMAP_MAP = new GMap2(document.getElementById($this._iId));
		$this._map = glGoogleMAP_MAP;		

		$this._iMapControl = parseInt($this._iMapControl);
		switch ($this._iMapControl)
		{
			case 2: $this._map.addControl(new GLargeMapControl()); break;
			case 1: $this._map.addControl(new GSmallMapControl()); break;
		}

		if ($this._isTypeControl) $this._map.addControl(new GMapTypeControl());
		if ($this._isScaleControl) $this._map.addControl(new GScaleControl());
		if ($this._isOverviewControl) $this._map.addControl(new GOverviewMapControl ());

		$this._map.setCenter(new GLatLng($this._fLat, $this._fLon), $this._iZoom);

		if (!$this._isDragable)
			$this._map.disableDragging();


		switch ($this._iMapType) 
		{
			case 1: $this._map.setMapType(G_SATELLITE_MAP); break;
			case 2: $this._map.setMapType(G_HYBRID_MAP); break;
			default: $this._map.setMapType(G_NORMAL_MAP); break;
		}

        if (0 == $this._iClickable || undefined == $this._iClickable)
		    $this.showLocations ();

		$this._map._gmk = $this;

        if (0 == $this._iClickable || undefined == $this._iClickable)        
		GEvent.addListener($this._map, "dragend", function() { 
			this._gmk.showLocations();
		});

        if (0 == $this._iClickable || undefined == $this._iClickable)        
		GEvent.addListener($this._map, "zoomend", function(oldLevel,  newLevel) { 
			if (newLevel < oldLevel)
				this._gmk.showLocations();
		});

		
        if (1 == $this._iClickable)        
            $this.initClickable();

		$this.onload();
	}

	google.setOnLoadCallback(h);
	
}

GoogleMAP.prototype.saveLocation = function ()
{
    var oPos = this._map.getCenter();        
    this.saveLocationFull ('save_location', "&id=" + this.getLocationId(), oPos.lat(), oPos.lng());
}

GoogleMAP.prototype.saveLocationFull = function (sAction, sParams, fLat, fLng)
{
    var $this = this;
	var request = GXmlHttp.create();
	var iMapType = 0;
	var fZoom = this._map.getZoom();
	switch (this._map.getCurrentMapType())
	{
		case G_SATELLITE_MAP: iMapType = 1; break;
		case G_HYBRID_MAP: iMapType = 2; break;
	};	

    if (undefined == sParams) sParams = '';

    if (undefined == fLat) fLat = this._fSaveLat;
    if (undefined == fLng) fLng = this._fSaveLng;

    if ('save_location' != sAction && ((undefined == fLat || undefined == fLng) || (0 == fLat && 0 == fLng)))
    {
        alert (this.sLangSelectLocation);
        return;
    }    

    if (!this.onsavelocation (fLat, fLng, fZoom, iMapType, sParams)) return false;

	request.open("GET", this.sActionsFile + "?action=" + sAction + "&lat=" + fLat + "&lng=" + fLng + "&zoom=" + fZoom + "&type=" + iMapType + sParams, true);

	request.onreadystatechange = function() 
	{
		if (request.readyState == 4) 
		{
			if (request.responseText == '<ret>1</ret>')
            {                
				alert ($this.sLangPositionSaved);
                $this.onsavelocationsuccess (fLat, fLng, fZoom, iMapType, sParams);
            }
			else
            {
				alert ($this.sLangPositionSaveFailed);
                $this.onsavelocationfailed (fLat, fLng, fZoom, iMapType, sParams);
            }
		}
	}	

	request.send(null);
}

GoogleMAP.prototype.showLocations = function ()
{
	var bounds = this._map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var span = bounds.toSpan();
	var request = GXmlHttp.create();
	var $this = this;

    if (!this.onshowlocationsbegin(southWest, northEast, span)) return;

	this._map.clearOverlays();

	request.open("GET", this.sActionsFile + "?action=" + this.sActionShowLocations + "&type="+this._sCustomType+"&minLat="+southWest.lat()+"&maxLat="+(southWest.lat()+span.lat())+"&minLng="+southWest.lng()+"&maxLng="+(southWest.lng()+span.lng()), true);

	request.onreadystatechange = function() 
	{
		if (request.readyState == 4) 
		{

			var xml = GXml.parse(request.responseText);
			var aProfiles = xml.documentElement.getElementsByTagName("loc");
			for (var i = 0; i < aProfiles.length; i++) 
			{
				var point = new GLatLng(parseFloat(aProfiles[i].getAttribute("lat")), parseFloat(aProfiles[i].getAttribute("lng")));
				var e = aProfiles[i];
				var sData = e.textContent ? e.textContent : e.nodeValue;
				if (null == sData) sData = e.firstChild.nodeValue;				
				$this._map.addOverlay($this.createMarker(point, sData));
			}
			$this.loading(0);
            $this.onshowlocations(aProfiles);
		}
	}
	this.loading(1);
	request.send(null);
}

GoogleMAP.prototype.createMarker = function (point, html) 
{
    var $this = this;
	var marker = new GMarker(point);
	if (html.length)
	GEvent.addListener(marker, "click", function() { if (!$this.onshowinfowindow(marker, html)) return; marker.openInfoWindowHtml(html); });
    return marker;
}

GoogleMAP.prototype.setMapType = function (iMapType) 
{
	this._iMapType = iMapType;
}

GoogleMAP.prototype.setMapControl = function (iMapControl) 
{
	this._iMapControl = iMapControl;
}

GoogleMAP.prototype.setTypeControl = function (isTypeControl) 
{
	this._isTypeControl = isTypeControl == 'on' ? true : false;
}

GoogleMAP.prototype.setScaleControl = function (isScaleControl) 
{
	this._isScaleControl = isScaleControl == 'on' ? true : false;
}
	
GoogleMAP.prototype.setOverviewControl = function (isOverviewControl) 
{
	this._isOverviewControl = isOverviewControl == 'on' ? true : false;
}
	
GoogleMAP.prototype.setDragable = function (isDragable) 
{
	this._isDragable = isDragable == 'on' ? true : false;
}

GoogleMAP.prototype.setCustomType = function (s) 
{
	this._sCustomType = s;
}
	
GoogleMAP.prototype.setLocationId = function (i) 
{
	this._iSaveLocationId = i;
}

GoogleMAP.prototype.getLocationId = function () 
{
	return this._iSaveLocationId;
}

GoogleMAP.prototype.setLoadingId = function (sId)
{
	this._sLoadingId = sId;
}

GoogleMAP.prototype.loading = function (bShow)
{
	var e = document.getElementById(this._sLoadingId);
	if (!e) return;
	e.style.display = bShow ? 'block' : 'none';
}

function gmk_move_prev (id)
{
	var iCurrent = parseInt(document.getElementById(id).innerHTML);
	if (!document.getElementById(id+(iCurrent-1))) return;
	document.getElementById(id+iCurrent).style.display = 'none';
	--iCurrent;
	document.getElementById(id+iCurrent).style.display = 'block';
	document.getElementById(id).innerHTML = iCurrent;
}

function gmk_move_next (id)
{
	var iCurrent = parseInt(document.getElementById(id).innerHTML);
	if (!document.getElementById(id+(iCurrent+1))) return;
	document.getElementById(id+iCurrent).style.display = 'none';
	++iCurrent;
	document.getElementById(id+iCurrent).style.display = 'block';
	document.getElementById(id).innerHTML = iCurrent;
}

GoogleMAP.prototype.setClickable = function () 
{
    this._iClickable = 1;
}

GoogleMAP.prototype.initClickable = function () 
{		
    	var $this = this;

		var hh = function(marker, point) 
		{			
			var iMapType = 0;
			switch ($this._map.getCurrentMapType())
			{
				case G_SATELLITE_MAP: iMapType = 1; break;
				case G_HYBRID_MAP: iMapType = 2; break;
			};	
            if (!$this.onsavemaptypezoombefore (iMapType, $this._map.getZoom())) return;
			$this._iSaveMapType = iMapType;
			$this._iSaveZoom = $this._map.getZoom();
            $this.onsavemaptypezoomafter (iMapType, $this._map.getZoom());
		};

		var h = function(marker, point) 
		{            
            if (!point) return;            
            if (!$this.onclickbefore(marker, point)) return;
    		$this._fSaveLat = point.lat();
	    	$this._fSaveLng = point.lng();
		    $this._map.clearOverlays();
			$this._map.addOverlay($this.createMarker(point, ''));
            $this.onclickafter(marker, point);
		};

		GEvent.addListener(this._map, "click", h);
		GEvent.addListener(this._map, "zoomend", hh);
		GEvent.addListener(this._map, "maptypechanged", hh);


        if (this._fLat != 0 && this._fLon != 0)
        {
    		var point = new GLatLng(this._fLat, this._fLon);
	    	this._map.clearOverlays();
		    this._map.addOverlay(this.createMarker(point, ''));
            this._fSaveLat = this._fLat;
            this._fSaveLng = this._fLng;
        }
}

GoogleMAP.prototype.findLocation = function (sAddress) 
{
	if (undefined == this._geocoder)
		this._geocoder = new GClientGeocoder();

    this.onfindlocation (sAddress);

	$this = this;
	var h = function (response)
	{
		if (!response || 200 != response.Status.code)
		{
			alert ($this.sLangGeocodeFailed + sAddress);
            $this.onfindlocationfailed (response, sAddress);
			return;
		}

        if (!$this.onfindlocationsuccess (response, sAddress)) return;

      	var place = response.Placemark[0];
      	var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);

      	$this._map.setCenter(point, 6);
		$this._map.clearOverlays();
		$this._map.addOverlay($this.createMarker(point, ''));

		$this._fSaveLat = point.lat();
		$this._fSaveLng = point.lng();
		$this._iSaveMapType = 6;

        $this.onfindlocationsuccesscomplete (response, sAddress);
	}

    this._geocoder.getLocations(sAddress, h);
}

GoogleMAP.prototype.preload = function ()
{

}

GoogleMAP.prototype.onload = function ()
{

}

GoogleMAP.prototype.onshowlocations = function (aProfiles)
{

}

GoogleMAP.prototype.onshowlocationsbegin = function (southWest, northEast, span)
{
    return true;
}

GoogleMAP.prototype.onshowinfowindow = function (marker, html)
{
    return true;
}

GoogleMAP.prototype.onclickbefore = function (market, point)
{
    return true;
}

GoogleMAP.prototype.onclickafter = function (market, point)
{

}

GoogleMAP.prototype.onsavemaptypezoombefore = function (iMapType, fZoom)
{
    return true;
}

GoogleMAP.prototype.onsavemaptypezoomafter = function (iMapType, fZoom)
{

}

GoogleMAP.prototype.onsavelocation = function (fLat, fLng, fZoom, iMapType, sParams)
{
    return true;
}

GoogleMAP.prototype.onsavelocationsuccess = function (fLat, fLng, fZoom, iMapType, sParams)
{

}

GoogleMAP.prototype.onsavelocationfailed = function (fLat, fLng, fZoom, iMapType, sParams)
{

}

GoogleMAP.prototype.onfindlocation = function (sAddress)
{

}

GoogleMAP.prototype.onfindlocationfailed = function (response, sAddress)
{

}

GoogleMAP.prototype.onfindlocationsuccess = function (response, sAddress)
{
    return true;
}

GoogleMAP.prototype.onfindlocationsuccesscomplete = function (response, sAddress)
{

}

