/*
	Version: 1.1, dhn: 18.09.2008
*/

function CPolyObject(vMap, vObjectName)
{
	// Variablen
	this.objectName=vObjectName;

	this.mapObject=vMap;
	this.polyObject=null;
	this.mouseoverHandler=null;

	this.points=new Array();
	this.markers=new Array();
	this.markersDraggable=true;
	this.markerInfoWindow=true;

	this.redrawDirectly=false;
	this.useObjects={markers: true, polyObjects: true};
	this.style={borderWeight: 5, borderColor: "#FF0000", borderOpacity: 0.35, backgroundColor: "#FF0000", backgroundOpacity: 0.25};
	this.tooltipText="";

	// Funktionen
	this.AddPoint=CPolyObject_AddPoint;
	this.AddPrevPoint=CPolyObject_AddPrevPoint;
	this.AddNextPoint=CPolyObject_AddNextPoint;
	this._addPointAtIndex=CPolyObject__addPointAtIndex;
	this.RemovePoint=CPolyObject_RemovePoint;
	this.Show=CPolyObject_ShowPolyObject;
	this.ShowPolyObject=CPolyObject_ShowPolyObject;
	this.Hide=CPolyObject_HidePolyObject;
	this.HidePolyObject=CPolyObject_HidePolyObject;
	this.Clear=CPolyObject_Clear;
	this.ShowMarkers=CPolyObject_ShowMarkers;
	this.HideMarkers=CPolyObject_HideMarkers;
	this.SetTooltipText=CPolyObject_SetTooltipText;
	this.CenterZoomToMap=CPolyObject_CenterZoomToMap;
	
	this.Circle=CPolyObject_Circle;
}

// Punkt hinzufügen
function CPolyObject_AddPoint(vPoint)
{
	if (typeof vPoint!="undefined")
	{
		if (typeof vPoint.length=="undefined") // Nur ein Punkt, dann Array erzeugen, dadurch mehrere Punkte als Parameter ermöglichen
		{vPoint=new Array(vPoint);
		}

		if (vPoint.length>0)
		{
			for (var pZ=0; pZ<vPoint.length; pZ++)
			{
				if (typeof vPoint[pZ].x!="undefined" && typeof vPoint[pZ].y!="undefined")
				{
					tmpX=vPoint[pZ].x;
					tmpY=vPoint[pZ].y;
				}
				// Im Geoabgrenzung.php kam in .lat und .lng immer eine Funktion an!?!? (CT 22.09.2008)
				if (typeof vPoint[pZ].lat!="undefined" && typeof vPoint[pZ].lng!="undefined" && typeof vPoint[pZ].lat!="function" && typeof vPoint[pZ].lng!="function")
				{
					tmpX=vPoint[pZ].lng;
					tmpY=vPoint[pZ].lat;
				}
				
				// Marker
				if (this.useObjects.markers)
				{this.markers.push(new GMarker(new GLatLng(tmpY, tmpX), {draggable: this.markersDraggable}));
				}
				
				// Punkt
				this.points.push({x: tmpX, y: tmpY});
			}
		}
	}

	if (this.redrawDirectly)
	{
		if (this.useObjects.markers)
		{this.ShowMarkers();
		}
		if (this.useObjects.polyObjects)
		{this.ShowPolyObject();
		}
	}
}

function CPolyObject_AddPrevPoint(vPointIndex)
{
	return this._addPointAtIndex(vPointIndex, -1);
}

function CPolyObject_AddNextPoint(vPointIndex)
{
	return this._addPointAtIndex(vPointIndex, +1);
}

function CPolyObject__addPointAtIndex(vPointIndex, vDirection)
{
	var tmpPointA, tmpPointB, tmpNewPoint, tmpAddIndex;

	// Nicht hinzufügen, wenn nur ein Punkt vorhanden ist
	if (this.points.length<2)
	{return null;
	}

	// Punkt "vor" einfügen
	if (vDirection<0)
	{
		vDirection=-1;
		tmpAddIndex=(vPointIndex==0?this.points.length:vPointIndex);
		tmpPointA=this.points[(vPointIndex==0?this.points.length-1:vPointIndex-1)];
		tmpPointB=this.points[vPointIndex];
	}

	// Punkt "nach" einfügen
	if (vDirection>0)
	{
		vDirection=1;
		tmpAddIndex=(vPointIndex==this.points.length-1?0:vPointIndex+1);
		tmpPointA=this.points[vPointIndex];
		tmpPointB=this.points[tmpAddIndex];
	}

	newPoint={x: (tmpPointA.x+tmpPointB.x)/2.0, y: (tmpPointA.y+tmpPointB.y)/2.0};
	//alert(newPoint.x+", "+newPoint.y);

	this.points.splice(tmpAddIndex, 0, newPoint);
	
	if (this.useObjects.markers)
	{this.markers.splice(tmpAddIndex, 0, new GMarker(new GLatLng(newPoint.y, newPoint.x), {draggable: this.markersDraggable}) );
	}

	return tmpAddIndex;
}

// Punkt löschen
function CPolyObject_RemovePoint(vPoint)
{
	if (typeof vPoint=="undefined")
	{this.markers.pop();
	}
	else
	{
		if (typeof vPoint=="number")
		{
			this.points.splice(vPoint, 1);
			this.mapObject.removeOverlay(this.markers[vPoint]);
			
			if (this.useObjects.markers)
			{this.markers.splice(vPoint, 1);
			}
		}

		if (typeof vPoint=="object")
		{
			for (pZ=0; pZ<this.points.length; pZ++)
			{
				if (this.points[pZ].x==vPoint.x && this.points[pZ].y==vPoint.y)
				{
					this.points.splice(pZ, 1);
					this.mapObject.removeOverlay(this.markers[pZ]);
					
					if (this.useObjects.markers)
					{this.markers.splice(pZ, 1);
					}

					break;
				}
			} // End-for
		}
	}

	if (this.redrawDirectly)
	{
		if (this.useObjects.markers)
		{this.ShowMarkers();
		}
		if (this.useObjects.polyObjects)
		{this.ShowPolyObject();
		}
	}
}

// Objekt zeichnen
function CPolyObject_ShowPolyObject()
{
	if (this.useObjects.polyObjects)
	{
		var tmpGPoints=new Array();
		
		if (this.polyObject!=null)
		{
			this.mapObject.removeOverlay(this.polyObject);
			this.polyObject=null;
		}
	
		for (pZ=0; pZ<this.points.length; pZ++)
		{tmpGPoints.push(new GLatLng(this.points[pZ].y, this.points[pZ].x));
		} // End-for
	
		if (tmpGPoints.length>0)
		{tmpGPoints.push(tmpGPoints[0]);
		}
	
		this.polyObject=new GPolygon(tmpGPoints, this.style.borderColor, this.style.borderWeight, this.style.borderOpacity, this.style.backgroundColor, this.style.backgroundOpacity);

		this.mapObject.addOverlay(this.polyObject);
		
		// Tooltip-Text vorhanden ?
		if (this.tooltipText!="")
		{
			// Mouseover-Handler entfernen
			if (this.mouseoverHandler!=null)
			{
				GEvent.removeListener(this.mouseoverHandler);
				this.mouseoverHandler=null;
			}

			this.SetTooltipText(this.tooltipText);
						
			// Mouseover-Handler hinzufügen
			if (this.mouseoverHandler==null)
			{
				// Event erzeugen
				this.mouseoverHandler=GEvent.addListener(this.polyObject, "mouseover", new  Function("", "{ \
						document.getElementById('CPolyObjectTooltip_"+this.objectName+"').style.display='block'; \
					}")
				);
				
				this.mouseoverHandler=GEvent.addListener(this.polyObject, "mouseout", new  Function("", "{ \
						document.getElementById('CPolyObjectTooltip_"+this.objectName+"').style.display='none'; \
					}")
				);
				
			}
		}
		
	}
}

// Objekt entfernen
function CPolyObject_HidePolyObject()
{
	if (this.useObjects.polyObjects)
	{
		if (this.polyObject!=null)
		{
			// Aus Karte entfernen, ausblenden
			this.mapObject.removeOverlay(this.polyObject);
			this.polyObject=null;
		}
	}
}

// Marker zeichnen
function CPolyObject_ShowMarkers(vMarkerIndexPos)
{
	if (this.useObjects.markers)
	{
		var mapBounds=null;
	
		if (typeof vMarkerIndexPos!="undefined")
		{mapBounds=this.mapObject.getBounds(); // Map-Bounds ermitteln
		}
	
		for (mZ=(typeof vMarkerIndexPos!="undefined"?vMarkerIndexPos:0); mZ<(typeof vMarkerIndexPos!="undefined"?vMarkerIndexPos+1:this.points.length); mZ++)
		{
			// Nur anzeigen, wenn Punkt in Map-BoundsRect
			if ((mZ!=0 && mZ!=this.points.length-1) && mapBounds!=null)
			{
				if (!mapBounds.contains(new GLatLng(this.points[mZ]["y"], this.points[mZ]["x"])))
				{
					mZ++; // Einen Punkt überspringen, damit die Anzeige schneller geht.
					continue;
				}
			}
	
			// Listener entfernen
			// Markers entfernen
			this.mapObject.removeOverlay(this.markers[mZ]);
	
			// Markers hinzufügen
			this.markers[mZ]=new GMarker(new GLatLng(this.points[mZ].y, this.points[mZ].x), {draggable: this.markersDraggable, title: mZ+1});
			this.mapObject.addOverlay(this.markers[mZ]);
	
			// Marker Draggable machen
			if (this.markersDraggable)
			{GEvent.addListener(this.markers[mZ], (document.all /* IE ? */?"dragend":"drag"), new Function("", "{"+this.objectName+".points["+mZ+"]={x: this.getPoint().lng(), y: this.getPoint().lat()}; if ("+this.objectName+".redrawDirectly) {"+this.objectName+".ShowPolyObject();} }") );
			}
	
			// Marker-Optionsmenü hinzufügen
			if (this.markerInfoWindow)
			{
				var tmpMarkerInfoHTML="<small><b>Optionen</b><br><br>";
				//tmpMarkerInfoHTML+="("+mZ+": lat "+this.points[mZ].y+", lng "+this.points[mZ].x+")<br><br>";
				tmpMarkerInfoHTML+="<a href=\"javascript:void(0);\" onclick=\""+this.objectName+".mapObject.closeInfoWindow(); tmpNewMarkerIndexPos="+this.objectName+".AddPrevPoint("+mZ+"); if ("+this.objectName+".redrawDirectly) {"+this.objectName+".ShowPolyObject();} "+this.objectName+".ShowMarkers(tmpNewMarkerIndexPos);\">Punkt <u>vor</u> diesem einfügen</a><br>";
				tmpMarkerInfoHTML+="<a href=\"javascript:void(0);\" onclick=\""+this.objectName+".mapObject.closeInfoWindow(); tmpNewMarkerIndexPos="+this.objectName+".AddNextPoint("+mZ+"); if ("+this.objectName+".redrawDirectly) {"+this.objectName+".ShowPolyObject();} "+this.objectName+".ShowMarkers(tmpNewMarkerIndexPos);\">Punkt <u>nach</u> diesem einfügen</a><br>";
				tmpMarkerInfoHTML+="<a href=\"javascript:void(0);\" onclick=\""+this.objectName+".mapObject.closeInfoWindow(); "+this.objectName+".RemovePoint("+mZ+"); if ("+this.objectName+".redrawDirectly) {"+this.objectName+".ShowPolyObject();} /*"+this.objectName+".ShowMarkers();*/ \">Punkt Entfernen</a><br><br>";
				
				tmpMarkerInfoHTML+="<a href=\"javascript:void(0);\" onclick=\"if (confirm(\\'Wirklich alle Punkte entfernen ?\\')) {"+this.objectName+".Clear();}\">Alle Punkte Entfernen</a><br>";
	
				tmpMarkerInfoHTML+="</small>";
	
				//alert(tmpMarkerInfoHTML);
	
				GEvent.addListener(this.markers[mZ], "click", new Function("", "{this.openInfoWindowHtml('"+tmpMarkerInfoHTML+"');}") );
			}
	
		} // End-for
	}
}

function CPolyObject_HideMarkers(vMarker)
{
	if (this.useObjects.markers)
	{
		for (mZ=0; mZ<this.markers.length; mZ++)
		{this.mapObject.removeOverlay(this.markers[mZ]);
		} // End-for
	}
}

function CPolyObject_Clear()
{
	// Points entfernen
	this.points=new Array();

	if (this.useObjects.polyObjects)
	{
		// PolyObjekt entfernen
		if (this.polyObject!=null)
		{
			this.mapObject.removeOverlay(this.polyObject);
			this.polyObject=null;
		}
	}

	if (this.useObjects.markers)
	{
		// Markers entfernen
		for (mZ=0; mZ<this.markers.length; mZ++)
		{this.mapObject.removeOverlay(this.markers[mZ]);
		} // End-for
		this.markers=new Array();
		
		this.mapObject.closeInfoWindow();
	}
}

function CPolyObject_SetTooltipText(vTooltipText)
{
	this.tooltipText=vTooltipText;
	
	// Ggfs. Tooltip-Div erzeugen
	if (!document.getElementById("CPolyObjectTooltip_"+this.objectName+""))
	{addNewGControl_Tooltip(this.mapObject, "CPolyObjectTooltip_"+this.objectName+"");
	}

	centerPoint=this.polyObject.getBounds().getCenter();
	divPoint=this.mapObject.fromLatLngToContainerPixel(centerPoint);
	document.getElementById("CPolyObjectTooltip_"+this.objectName).style.top=divPoint.y;
	document.getElementById("CPolyObjectTooltip_"+this.objectName).style.left=(divPoint.x-(this.tooltipText.length/2*8) );
	
	document.getElementById("CPolyObjectTooltip_"+this.objectName+"").innerHTML=this.tooltipText;
}

/* vPoint, vKMRadius, vKMRadiusInner?, vNumberOfPoints? */
function CPolyObject_Circle(vPoint, vKMRadius, vKMRadiusInner, vNumberOfPoints)
{
	if (!this.useObjects.polyObjects)
	{return;
	}
	
	// Elemente (PolyObject, Markers) entfernen
	this.Clear();
	
	var center=null;
	var circlePoints=new Array();
	
	// Radius
	var radiusArray=[];
	if (typeof vKMRadius!="undefined")
	{radiusArray.push(vKMRadius);
	}
	if (typeof vKMRadiusInner!="undefined")
	{radiusArray.push(vKMRadiusInner);
	}
	
	// Mittelpunkt
	if (typeof vPoint.x!="undefined" && typeof vPoint.y!="undefined")
	{center=new GLatLng(vPoint.y, vPoint.x);
	}
	if (typeof vPoint.lat!="undefined" && typeof vPoint.lng!="undefined")
	{center=new GLatLng(vPoint.lat, vPoint.lng);
	}
	
	// Anzahl Punkte des Kreises
	if (typeof vNumberOfPoints=="undefined")
	{vNumberOfPoints=360;
	}
	else
	{
		if (vNumberOfPoints<0)
		{vNumberOfPoints=1;
		}
		if (vNumberOfPoints>360)
		{vNumberOfPoints=360;
		}
	}
	
	for (var rZ=0; rZ<radiusArray.length; rZ++)
	{
		with (Math)
		{
			var d=radiusArray[rZ]/6378.8;
	
			var lat1 = (PI/180)* center.lat(); // radians
			var lng1 = (PI/180)* center.lng(); // radians
			
			for (var a = 0 ; a<361; a+=(360/vNumberOfPoints) )
			{
				var tc=(PI/180)*a;
				var y=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
				var dlng=atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
				var x=((lng1-dlng+PI) % (2*PI)) - PI ; // MOD function
				var point=new GLatLng(parseFloat(y*(180/PI)),parseFloat(x*(180/PI)));
				
				// Punkt hinzufügen
				this.AddPoint({lat: point.lat(), lng: point.lng()});
				
				// Als Dummy speichern
				circlePoints.push({lat: point.lat(), lng: point.lng()});
			}
		} // End with
	} // End for radiusArray
	
	// Anzeigen
	if (this.redrawDirectly)
	{
		this.ShowPolyObject();
		this.ShowMarkers();
	}
}

function CPolyObject_CenterZoomToMap()
{
	// Ausmaße des PolyObjekts ermitteln
	var polyObjectBounds=this.polyObject.getBounds();
	// Karte anhand der googletools-Funktion setzen
	setLatLngRect(this.mapObject, {minLat: polyObjectBounds.getSouthWest().lat(), minLng: polyObjectBounds.getSouthWest().lng(), maxLat: polyObjectBounds.getNorthEast().lat(), maxLng: polyObjectBounds.getNorthEast().lng()});
}


/* DrawObject - Ende */

// Für den Tooltip, das GControl-Object zurückliefern
function addNewGControl_Tooltip(vMap, vId)
{
	function Tooltip() {}
	Tooltip.prototype=new GControl();
	Tooltip.prototype.initialize=function (vMap) {
		// Div erzeugen
		var tooltipDiv=document.createElement("div");
		
		var id=document.createAttribute("id");
		id.nodeValue=vId;
		tooltipDiv.setAttributeNode(id);
		
		var style=document.createAttribute("style");
		style.nodeValue="border: 1px solid #505050; display: none; color: #505050; background-color: #FFC600; padding: 2;";
		tooltipDiv.setAttributeNode(style);
		
		map.getContainer().appendChild(tooltipDiv);
		return tooltipDiv;
	};
	
	Tooltip.prototype.getDefaultPosition=function ()
	{return new GControlPosition(null, new GSize(0, 0));
	}
	
	vMap.addControl(new Tooltip());
}	
