// Copyright © 2007 by Chris Marx <chrismarx@gmail.com>
// All rights reserved.
//
//Thanks to Mike Williams for many of the contributing examples
//and Bill Chadwick for his work on the svg/vml extensions
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE. 
/*
GoogleDigitizerToolpack Polygon control. Version 0.4 Released 11/22/07

To use:
  map.addControl(new GPolygonControl());
  
  If access to the polygon array is desired, create a global variable from which to access it:
  var polyCtrl = new addPolygonControl();
  map.addControl(polyCtrl);
  
  //after objects have been added
  var polygonArray = polyCtrl.G.prmPolygons;

Note:
	In order to use the GoogleDigitizerToolpack controls, the following scripts must also be included in the html page:
	    
	    <script src="farbtastic/jQuery.js" type="text/javascript"></script>
		<script src="farbtastic/farbtastic.js" type="text/javascript" ></script>
		<script src="BDCCPolyline.js" type="text/javascript"></script>
		<script src="BDCCPolygon.js" type="text/javascript"></script>
	
	Stylesheets (added to the html page):
	
		<link rel="stylesheet" type="text/css" href="google.css" />
		<link rel="stylesheet" href="farbtastic/farbtastic.css" type="text/css" />
		
	Add the farbtastic package to a directory like /farbtastic. The full download (only 28kb, unpacked) can be found here
	
		http://acko.net/dev/farbtastic
		
		Note: There are several help files (.html) included that can be deleted from farbtastic directory
		
	And the following images must be available in a folder called images(unless otherwise specified) at this path "images/" 
		
		addashape.png;
		addashapeP.png;
		inflection.png;
		inflectionP.png;
		transparent.gif;
  
*/

/**
 * @extends GControl 
 */     
GPolygonControl.prototype = new GControl();

/**
 * Called by GControl 
 * @param {GMap2} map The map used by this control
 */
GPolygonControl.prototype.initialize = function(map) {
  var me=this;
  var G = me.G;
  // create the background graphic as a <div> containing an image
  var containerP = document.createElement("div");
   containerP.style.width="34px";
   containerP.style.height="34px";
   containerP.style.cursor="pointer";
   containerP.id = "polygonControl";
   
  if(G.buttonId == 'polygonControl'){
   // store a reference to the map so that we can call setZoom() on it
   me.map = map;
   // Is this MSIE, if so we need to use AlphaImageLoader
   var agent = navigator.userAgent.toLowerCase();
   if ((agent.indexOf("msie") > -1) && (agent.indexOf("opera") < 1)){me.ie = true;} else {me.ie = false}
   // Handle transparent PNG files in MSIE
   if(me.ie) {
     var loader = '<a id="addPolygon" href="javascript:void(0)"><span id="addPolygonSpan" style="width:33px;height:33px;display:inline-block;' ;
     loader +=  "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='addashape.png');" ;
     loader +=  '"><img id="addPolygonPic" style="filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" src="addashape.png" width="33" height="33" border="0" alt=""></span></a>'; 
     containerP.innerHTML = '<div id="addPolygonDiv" style="height:33px; width:33px; cursor="pointer">'+loader+'</div>';
   } else {
     containerP.innerHTML = '<a id="addPolygon" href="javascript:void(0)"><img id="addPolygonPic" src="addashape.png"  width=33 height=33 border="0" ></a>';
   }
   // attach the control to the map
   me.map.getContainer().appendChild(containerP);
   me.containerP = containerP;
   // add toggle event polygon tool button
   //GEvent.addDomListener(me.containerP, 'click', me.polygButtonClick.on);
   $("#polygonControl").toggle(function(){me.polygButtonClick.on();},function(){me.polygButtonClick.off();});
  } else {
  	//for non standard object initialization
  	if(typeof(G.initCallback) == "function") { G.initCallback(); }
  }
  return containerP;
}
       
/**
 * Called By GControl
 */
GPolygonControl.prototype.getDefaultPosition = function(){
     return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(240, 0));
}      

/**
 * @constructor 
 * @param String - id of html element used to the toggle the control
 * @param Function - callback for initialization
 * @param Function - callback for end of digitization
 */
function GPolygonControl(opt_opts) {
	var me = this;
	this.options = (opt_opts == null)?{}:opt_opts;

	/**
	 * @return {GIcon} coordIcon The icon used to represent vertexes on the polygon
	 */
	this.icon = function() {
		var coordIcon = new GIcon();
		coordIcon.iconSize = new GSize(12,12);
		coordIcon.iconAnchor = new GPoint(6,9);
		coordIcon.infoWindowAnchor = new GPoint(8,0);
		coordIcon.image = "inflection.png";
		coordIcon.imageP = "inflectionP.png";
		return coordIcon;
	}
		
	/**
	 * @class
	 * @static
	 */
	this.G = {
        me:this,
        on:false,
        buttonId:(typeof(this.options.id) == "undefined")?"polygonControl":this.options.id,
        ie:(navigator.userAgent.indexOf("MSIE")==-1)?false:true,
        icon:this.icon(),
        polygon:null,
        polygon_handler:null,
        addnewpolygonline_handler:null,
        polygonMarkers:new Array(),
        polygonPoints:new Array(),
        newline:null,
        prmPolygons:new Array(),		//permanent polygons, stored in multi-dimensional array	
        newGLinePoints:new Array(),
        newGLinePoints2:new Array(),
        newline1:null,
        newline2:null,
        adjustvertex_handler:null,
        currentcolor:"#0000ff",
        lineColor:"#0000ff",
        lineWeight:4,
        lineOpacity:.5,
        fillColor:"#0000ff",
        fillOpacity:.4,
        editFlag:false,
        initCallback:this.options.initCallback,
        endCallback:this.options.endCallback,
        //primary info window html is broken up into 4 pieces -- NOOO use this.variables and function(){return etc.} dont need to be broken up!!!!
        editInfoWindowHtml1:'<div id="editInfoWindow"  style="position: relative; left: 6px; top: 7px; width: 279px;"><div><div class="msedit"><table class="iwspan"><tbody><tr><td><table class="inputField"><tbody><tr><td class="label">Title</td><td><input id="titlePoly" class="title" type="text" maxlength="250" value="',
        editInfoWindowHtml2:'"/></td><td><div id="colorIcon" class="icon" onmouseover="javascript:this.style.borderColor = \'#0000FF\'" onmouseout="javascript:this.style.borderColor = \'#DDDDDD\'"><div id="currentColor" class="poly" style="border-color: rgb(191, 191, 191); background-color:',  /*+G.prmPolygons[k][2]+*/
        editInfoWindowHtml3:'"/></a></div></td></tr></tbody></table><table class="inputField"><tbody><tr><td class="label">Description</td><td class="tabs"><table><tbody><tr><td><span class="stab">Plain text</span></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table><div><div id="rtfield" class="textField description"/><textarea id="descPoly" name="textarea" class="textField description">',  /*+G.prmPolygons[k][4]+*/
        editInfoWindowHtml4:'</textarea></div><table style="margin-top:20px"><tbody><tr><td class="navLeft"><span class="lk"></span><a id="polyDelete" style="cursor: pointer;" href="javascript:void(0)">Delete </a>&nbsp;&nbsp;<span class="lk"></span><a id="polyEdit" style="cursor: pointer;" href="javascript:void(0)"> Edit</a></td><td class="navRight"><button id="cancelPoly">Cancel</button></td><td class="navRight"><button id="okPoly">OK</button></td></tr></tbody></table></div><div class="msstyle" style="display:none; position: absolute; left: 0px; top: 0px;"/></div></div>'  /*+G.prmPolygons[k][3]+*/																	
	}
	        
	/**
	 * @class
	 * @static
	 */
	this.polygButtonClick = {
		me: me,
		/**
		 * Initializes the polygon control to be used
		 */
		on: function(){
			var me = this.me;
			var G = me.G;
			
			//***** call to turn off any other digitizer tools. needs to be added depending on what other tools are being used *******//
		 	//toggleGToolsOff(); 
		 	
		 	//change the button pic
		 	if(G.ie) {
			 	var loader = '<a id="addPolygon" href="javascript:void(0)"><span id="addPolygonSpan" style="width:33px;height:33px;display:inline-block;' ;
		       	loader +=  "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='addashapeP.png');" ;
		      	loader +=  '"><img id="addPolygonPic" style="filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" src="addashapeP.png" width="33" height="33" border="0" alt=""></span></a>'; 
		      	$('#addPolygonDiv').html(loader);	
		 	} else {
		 		$('#addPolygonPic').attr("src","addashapeP.png");
		 	}
		 	
		 	//start the click handler
		 	me.polygpointClick.add();
		 	
		 	//add a custom tooltip
		 	me.cursorTooltip.show("Click to add points, click the last marker to end the polygon");
			    			 
		},
		/**
		 * Turns of polygon control and cleans up
		 */
		off:function(){
			var me = this.me;
			var G = me.G;
	   		if(G.ie){
	   			var loader = '<a id="addPolygon" href="javascript:void(0)"><span id="addPolygonSpan" style="width:33px;height:33px;display:inline-block;' ;
	       		loader +=  "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='addashape.png');" ;
	      		loader +=  '"><img id="addPolygonPic" style="filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" src="addashape.png" width="33" height="33" border="0" alt=""></span></a>';
	      		$('#addPolygonDiv').html(loader);
	   		} else {
	    	 	$('#addPolygonPic').attr("src","addashape.png");			 	
	    	}
	 		$('#map>div>div').css("cursor","default");
	 		if(G.polygon || G.polygonMarkers.length > 0){ me.removePolygon(); }
			if(G.polygon_handler) {	me.polygpointClick.remove(); }
	       	if(G.addnewpolygonline_handler) { me.newLine.remove(); }
			if(me.cursorTooltip.tooltip_handler) { me.cursorTooltip.hide(); }
			G.polygon = null;
	 		//need to add additional object removal if the button is clicked before the polygon is finished??
	 		if(typeof(G.endCallback) == "function"){ G.endCallback(); }
		}        		
	} 
	
	//== toggle map click listener ==//
	this.polygpointClick = {
	    me: me, 
		add:function(){	
			//add the marker listener
			var me = this.me;
			var G = me.G;
		    G.polygon_handler = GEvent.addListener(map,"click", function(overlay,point){me.polygonHandlerM(overlay,point);});	
		},
		
		remove:function(){
			//remove the cursor tooltip, listeners, etc.
			var me = this.me;
			var G = me.G; 
			me.cursorTooltip.hide();
			GEvent.removeListener(G.polygon_handler);
			G.polygon_handler = null;
		}
	}
	
	// == access the polygonHandler function depending on whether the click was on the map or on the line tracking mouse movement === //
	this.polygonHandlerM = function(overlay,point){
		if(point){
			this.polygonHandler(point);	
		}
	}
	
	// == as above ==//
	this.polygonHandlerL = function(para){
		if(para){
			this.polygonHandler(para);	
		}
	}
	
	this.polygonHandler = function(click) {
		var me = this;
		var G = me.G;
		if(click){
			var point = click;
			//change cursor type
			$('#map>div>div').css("cursor","crosshair");
			var marker = me.addMarkerListeners(point);
			G.polygonMarkers.push(marker);        			 
			G.polygonPoints.push(point);
			 
			map.addOverlay(marker);
			
			if(G.addnewpolygonline_handler==null) {me.newLine.add(G.lineColor);}
		
			if(G.polygonMarkers.length > 1) {
				if(G.polygon){map.removeOverlay(G.polygon);}
			 	G.polygon = new BDCCPolygon(G.polygonPoints, G.lineColor,G.lineWeight,G.lineOpacity,G.fillColor,G.fillOpacity); 
			 	map.addOverlay(G.polygon);
			}
		 }
	}
	
	this.cursorTooltip={
		me: me,
		tooltip:null,
	    tooltip_handler:null,
		showMarkerTooltip:function(point) {
			var point1=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.getBounds().getSouthWest(),map.getZoom());
			var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(point,map.getZoom());
			var anchor= new GPoint(-20,15);
			var width = -12;
			var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point1.x - anchor.x + width,- offset.y + point1.y +anchor.y)); 
			pos.apply(this.tooltip);
	    },
		show:function(message){
			var cursorTooltip = this;
			if(!cursorTooltip.tooltip_handler) {	 	
		 		cursorTooltip.tooltip = document.createElement("div");
		 		document.getElementById("map").appendChild(cursorTooltip.tooltip);
		 		cursorTooltip.tooltip.innerHTML = '<div style="border: 1px solid #666666; background-color: #ffffff; color: #666666;">'+ message +'</div>';					     
		    	cursorTooltip.tooltip_handler = GEvent.addListener(map, "mousemove", function(point) {
		      	    cursorTooltip.showMarkerTooltip(point);
		     	});
		     }    			
		},		
		hide:function(){
		    var cursorTooltip = this;
	      	GEvent.removeListener(cursorTooltip.tooltip_handler);
	      	cursorTooltip.tooltip_handler = null;
	      	document.getElementById("map").removeChild(cursorTooltip.tooltip);
	    }
	}
	
	this.addMarkerListeners = function(point) {
		var me = this;
		var G = me.G;	
		var marker = new GMarker(point, {icon:G.icon, title:"Click a marker to end."});
		GEvent.addListener(marker,"mouseover",function(){marker.setImage(G.icon.imageP);});
		GEvent.addListener(marker,"mouseout",function(){marker.setImage(G.icon.image);});		
		GEvent.addListener(marker,"click",function() {
				if(G.polygonPoints.length >= 2){ 
						me.polygonEnd();
				}
		});	
	 return marker;
	}
	
	//== add tracking line listener Note: ie bdccpoly vml bug adds a dashed line to first polygon object!!???!!! ==//
	this.newLine = {
		me: me,
		add:function(lineColor){
			var me = this.me;
			var G = me.G; 
			G.addnewpolygonline_handler = GEvent.addListener(map, "mousemove", function(point) {
		    		if(G.polygonMarkers.length > 0) { 
						if(point){
							var newGLinePoints = new Array();
							newGLinePoints[0] = G.polygonPoints[G.polygonMarkers.length-1];
							if(G.newline){map.removeOverlay(G.newline);} 
							newGLinePoints[1] = point;
							//Hack: there is a bdcc vml bug here, that recreates the polyline after it has been removed, and it loses the mousemove events.
							var linestyle = (G.ie)?null:"dash";
							G.newline = new BDCCPolyline(newGLinePoints,lineColor,3,0.5,"Line",linestyle);
							GEvent.addListener(G.newline, "click", function(overlay,marker){me.polygonHandlerL(overlay,marker);});
							map.addOverlay(G.newline); 
						}
					}
			});
		},
		
		remove:function() {
			var me = this.me;
			var G = me.G; 
		    GEvent.removeListener(G.addnewpolygonline_handler);
		    if (G.newline) {map.removeOverlay(G.newline);G.newline=null;}
		    G.addnewpolygonline_handler = null;
		}
	}
	
	this.polygonEnd = function(){ 		
		var G = this.G;
		if(G.addnewpolygonline_handler && G.polygonMarkers.length > 2) {
			if(G.polygon){map.removeOverlay(G.polygon);G.polygon=null;}//should this call the full removePolygon function???
			G.polygonPoints[G.polygonMarkers.length] = G.polygonPoints[0];
			var prmPolygon = this.createPolygon(G.polygonPoints, G.lineColor,G.lineWeight,G.lineOpacity,G.fillColor,G.fillOpacity);
			var length = G.prmPolygons.length;
			G.prmPolygons[length] = new Array();
			G.prmPolygons[length][1] = prmPolygon;
			G.prmPolygons[length][2] = "";             //reserved for title
			G.prmPolygons[length][3] = "";             //reserved for description
		    G.prmPolygons[length][4] = ""+G.lineColor+"";
		    G.prmPolygons[length][5] = ""+G.lineWeight+"";
		    G.prmPolygons[length][6] = ""+G.fillOpacity+"";
		    G.prmPolygons[length][7] = ""+G.fillColor+"";
			map.addOverlay(prmPolygon);              							
			this.newLine.remove();
			this.polygpointClick.remove();
			document.getElementById("map").firstChild.firstChild.style.cursor = "default";
			for (i=0;i<G.polygonMarkers.length;i++) {map.removeOverlay(G.polygonMarkers[i]);}
			G.polygonMarkers = new Array();
			G.polygonPoints = new Array();
			// note: the following calls this.polygButtonClick.off() by triggering the button toggle with a click to maintain correct button state
			if(G.buttonId=="polgonControl"){
				$("#polygonControl").trigger("click");
			} else {
				$("#"+G.buttonId+"").trigger("click");
			}
		}		 								
	}
	
	//== creates markers used when editing polygon ==//
	this.createMarkerG = function(point,number,color,k,last){ 
		var me = this;
		var G = me.G;
		var marker = new GMarker(point,{icon: G.icon, draggable: true, bouncy: false, title:"Drag to move vertex. Click to end editing."});
		marker.number = parseInt(number); //retain state information for use in the listener
		GEvent.addListener(marker,"mouseover",function(){marker.setImage(G.icon.imageP);});
		GEvent.addListener(marker,"mouseout",function(){marker.setImage(G.icon.image);});
		
		GEvent.addListener(marker, "dragstart", function() {
				//start/end points need to get their respective before/after points
				G.newGLinePoints[0] = (marker.number != 0)? G.polygonPoints[parseInt(marker.number)-1]:G.polygonPoints[parseInt(last)]; 
				G.newGLinePoints2[0] = (marker.number != last)?G.polygonPoints[parseInt(marker.number+1)]:G.polygonPoints[0]; 
				
				G.adjustvertex_handler = GEvent.addListener(map, "mousemove", function(point) {
						G.newGLinePoints[1] = point;
						G.newGLinePoints2[1] = point;					
						if (G.newline1) {map.removeOverlay(G.newline1);}
						if (G.newline2) {map.removeOverlay(G.newline2);}
						
						if(marker.number != 0 && marker.number != last){
							G.newline1 = new BDCCPolyline(G.newGLinePoints.slice(0,2),color,4,0.5,"New Line","dot");
							map.addOverlay(G.newline1);					
							G.newline2 = new BDCCPolyline(G.newGLinePoints2.slice(0,2),color,4,0.5,"New Line","dot");
							map.addOverlay(G.newline2);
						} else if(marker.number == 0 || marker.number == last){
							G.newline1 = new BDCCPolyline(G.newGLinePoints.slice(0,2),color,4,0.5,"New Line","dot");
							map.addOverlay(G.newline1);
							G.newline2 = new BDCCPolyline(G.newGLinePoints2.slice(0,2),color,4,0.5,"New Line","dot");
							map.addOverlay(G.newline2);
						}
				});
		});
		
		GEvent.addListener(marker, "dragend", function() {
				var point = G.newline1.getVertex(1);
				if (G.newline1) {map.removeOverlay(G.newline1);}
				if (G.newline2) {map.removeOverlay(G.newline2);}
				G.polygonPoints.splice(parseInt(marker.number),1,point)
				G.polygonPoints.splice(0,0,G.polygonPoints[parseInt(last)]);  //overlap start and end points to close polygon
				G.polygon = me.createPolygon(G.polygonPoints, color,G.lineWeight,G.lineOpacity,color,G.fillOpacity,k); 
				G.polygonPoints.shift(); //delete overlapping point
				map.addOverlay(G.polygon);
				map.removeOverlay(G.prmPolygons[k][1]);
				G.prmPolygons[k][1] = G.polygon;
				GEvent.removeListener(G.adjustvertex_handler);
		});
		
		GEvent.addListener(marker, "click", function() {
			if(G.polygonMarkers.length > 0){
				for(var i=0; i<G.polygonMarkers.length; i++) {
					map.removeOverlay(G.polygonMarkers[i]);
				}
				G.polygonMarkers = new Array();
				G.polygonPoints = new Array();
				G.polygon = null;
				G.editFlag = false;
			}
		});
		
	  return marker;
	}
	
	this.returnVertices = function(polygon) {
		var vertices = new Array();
		  for (var i=0; i < polygon.getVertexCount(); i++) {
		  	var point = polygon.getVertex(i);
		  	vertices[i] = new GLatLng(parseFloat(point.lat()),parseFloat(point.lng()));
		  }
	  return vertices;
	}
	
	//== external polygon creation function ==/	      
	this.createPolygon = function(polygonPoints,lineColor,lineWeight,lineOpacity,fillColor,fillOpacity,k){ 
		var me = this;
		var G = this.G;
		if(typeof(k)=="undefined"){var k = G.prmPolygons.length;} //new polygons need to find k, existing polygons use preexisting k
		var prmPolygon = new BDCCPolygon(polygonPoints,lineColor,lineWeight,lineOpacity,fillColor,fillOpacity);
	    GEvent.addListener(prmPolygon,"mouseover",function(){
	    		prmPolygon.setFillOpacity(parseFloat(fillOpacity)+.3);
	    });
	    GEvent.addListener(prmPolygon,"mouseout",function(){prmPolygon.setFillOpacity(fillOpacity);});
	    GEvent.addListener(prmPolygon,"click",function(para){
				if(para){
					map.openInfoWindowHtml(para,(G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4));
					me.addInfoWindowListeners(para, k);
				} else {//mac firefox hack -- bug in normal poly click event, use getCenter instead
					var hackClick_handler = GEvent.addListener(map,"click",function(overlay,point){
						if(overlay){
							var center = overlay.getBounds().getCenter();
							map.openInfoWindowHtml(center,(G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4));
							me.addInfoWindowListeners(center, k);
							GEvent.removeListener(hackClick_handler);
						}
					});
				}
		});
	 return prmPolygon;
	}
	
	/**
	 * Allows editing of Polygon
	 * @param {GPolygon} currentPolygon
	 * @param {String} lineColor
	 * @param {int} k The reference to the current polygon's position in the global array
	 * Note: need to remove editFlag -- (prevents clicking edit twice to bring up 2 sets of editabvle markers)
	 */
	this.adjustline = function(currentPolygon, lineColor, k){ 
		var me = this;
		var G = this.G;	
		if(!G.editFlag){
			G.editFlag = true;
			var vertices = me.returnVertices(currentPolygon);
			G.polygonPoints = new Array();
			G.polygonMarkers = new Array();
			
			//Note: Don't return start vertex, since start/end vertices overlap
			for (var m=1; m<vertices.length; m++) {
				var marker = me.createMarkerG(vertices[m],m-1,lineColor,k,vertices.length-2); 				
				G.polygonPoints.push(vertices[m]);
				G.polygonMarkers.push(marker);
				map.addOverlay(marker);
			}
		}					
	}
	
	this.recreatePolygon = function(polygon,lineColor,lineWeight,lineOpacity,fillColor,fillOpacity,k){ 
		var me = this;
		var G = this.G;
		var vertices = this.returnVertices(polygon);
		map.removeOverlay(polygon);
		var newPolygon = new BDCCPolygon(vertices,lineColor,lineWeight,lineOpacity,fillColor,fillOpacity);
		GEvent.addListener(newPolygon,"mouseover",function(){
	    		newPolygon.setFillOpacity(parseFloat(fillOpacity)+.3);
	    });
	    GEvent.addListener(newPolygon,"mouseout",function(){
	    		newPolygon.setFillOpacity(fillOpacity);
	    });
	    GEvent.addListener(newPolygon,"click",function(para){
				if(para){
					map.openInfoWindowHtml(para,G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4);
					me.addInfoWindowListeners(para, k);
				} else {//mac firefox hack -- bug in normal poly click event
					var hackClick_handler = GEvent.addListener(map,"click",function(overlay,point){
						if(overlay){
							var center = overlay.getBounds().getCenter();
							map.openInfoWindowHtml(center,G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4);
							me.addInfoWindowListeners(center, k);
							GEvent.removeListener(hackClick_handler);
						}
					});
				}
		});
	 return newPolygon;
	} 
	
	this.addInfoWindowListeners = function(point, k) {
		var me = this;
		var G = this.G;
		var currentPolygon = G.prmPolygons[k][1]
		G.currentcolor = G.prmPolygons[k][7];
	
		//onchange listeners for title and description values
		$('#titlePoly').change(function() {
			G.prmPolygons[k][2] = $('#titlePoly').val();
		});
		
		$('#descPoly').change(function() {
			G.prmPolygons[k][3] = $('#descPoly').val();
		});
		
		var colorHtml = '<div id="colorPickerDiv" style="position: relative; z-index:100; top:0px; left:0px; width:284px; height:344px; background-image:url(transparent.gif)"><form action="javascript:void(0);" style="width: 274px;">  <div class="form-item"><label for="color"></label><input type="text" style="display:none" id="color" name="color" value="#123456" /></div><div id="picker2"></div></form><table class="msstyle" style="height: 118px;"><tbody><tr><td style="vertical-align: top;"><table class="msline"><tbody><tr><td colspan="2"><b class="title">Edit line style</b></td></tr><tr><td class="label">Line width (pixels, 1-20)</td><td><input id="polygonWeight" class="numberfield" type="text" size="3" value="'+G.prmPolygons[k][5]+'"/></td></tr><tr><td class="label">Fill opacity (10-100)</td><td><input class="numberfield" id="polygonOpacity" type="text" size="3" value="'+G.prmPolygons[k][6]*100+'"/></td></tr></tbody></table></td></tr><tr><td><table><tbody><tr><td class="navLeft"/><td class="navRight"><button id="cancelPoly2">Cancel</button></td><td class="navRight"><button id="okPoly2">OK</button></td></tr></tbody></table></td></tr></tbody></table></div>';
					
		//bind color link
		$('#colorIcon').click(function(){
	    		map.openInfoWindowHtml(point,colorHtml);
	    		var farb = $.farbtastic('#picker2','#color');
	    		farb.setColor(G.prmPolygons[k][7]);
				$("#okPoly2").click(function(){
					
					G.lineWeight = G.prmPolygons[k][5] = (parseInt($("#polygonWeight").val()) > 20 || parseInt($("#polylgonWeight").val()) < 1 || isNaN($("#polygonWeight").val()) )?G.prmPolygons[k][5]:$("#polygonWeight").val();
					G.fillOpacity = G.prmPolygons[k][6] = (parseInt($("#polygonOpacity").val()) > 100 || parseInt($("#polygonOpacity").val()) < 10 || isNaN($("#polygonOpacity").val()) )?G.prmPolygons[k][6]:($("#polygonOpacity").val()/100);
					G.fillColor = G.prmPolygons[k][7] = G.currentcolor = G.lineColor = $('#color').val();
					//restart original process
					map.openInfoWindowHtml(point,G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4);
					me.addInfoWindowListeners(point,k);
					$('#currentColor').css("background-color", G.currentcolor);
				});
				$("#cancelPoly2").click(function(){
					map.openInfoWindowHtml(point,G.editInfoWindowHtml1+G.prmPolygons[k][2]+G.editInfoWindowHtml2+G.prmPolygons[k][4]+G.editInfoWindowHtml3+G.prmPolygons[k][3]+G.editInfoWindowHtml4);
					me.addInfoWindowListeners(point,k);
				});
				$("#polygonWeight").change(function(){
					if(parseInt($("#polygonWeight").val()) > 20 || parseInt($("#polygonWeight").val()) < 1 || isNaN($("#polygonWeight").val()) ) {
						alert("Out of Range. Please select a number between 1 & 20");
						$("#polygonWeight").val(""+G.prmPolygons[k][5]+"");
					}
				});
				$("#polygonOpacity").change(function(){
					if(parseInt($("#polygonOpacity").val()) > 100 || parseInt($("#polygonOpacity").val()) < 10 || isNaN($("#polygonOpacity").val()) ) {
						alert("Out of Range. Please select a number between 10 & 100");
						$("#polygonOpacity").val(""+G.prmPolygons[k][6]+"");
					}
				});
	      	return false;
		}); 
		
		//bind delete link
		$("#polyDelete").click(function(){
			 map.removeOverlay(currentPolygon);
			 G.prmPolygons[k]=null;
			 
			 //remove edit markers if present
			 for (i=0;i<G.polygonMarkers.length;i++) {
			 	map.removeOverlay(G.polygonMarkers[i]);
			  }
			   
			 map.closeInfoWindow();
			 $('#colorPickerDiv').css("display", "none");
			 G.polygonMarkers = new Array();
			 G.polygonPoints = new Array();
		});  
	 			 
	 	//bind edit link
	 	$("#polyEdit").click(function(){		
		   	me.adjustline(currentPolygon,G.prmPolygons[k][7],k);
		   	map.closeInfoWindow();
			$('#colorPickerDiv').css("display", "none");
		}); 
	 		   
		//cancel button
		$("#cancelPoly").click(function() {
		   		map.closeInfoWindow();
		   		$('#colorPickerDiv').css("display", "none");
		});
		   	
		// ok button
		$("#okPoly").click(function() {
		   	var newPolygon = me.recreatePolygon(currentPolygon,G.lineColor,G.lineWeight,G.lineOpacity,G.currentcolor,G.fillOpacity,k); 
		   	map.addOverlay(newPolygon);
		   	G.prmPolygons[k][1] = newPolygon;
		   	G.prmPolygons[k][2] = $("#titlePoly").val();
		   	G.prmPolygons[k][3] = $("#descPoly").val();
		   	G.prmPolygons[k][4] = G.currentcolor;
		   	//G.prmPolygons[k][5] = G.lineWeight; //set above in color ok button
		   	//G.prmPolygons[k][6] = G.fillOpacity;
		   	//G.prmPolygons[k][7] = G.currentcolor;
		   	map.closeInfoWindow();
		   	$('#colorPickerDiv').css("display", "none");
		 });  								
	}
	
	this.removePolygon = function(){
		 var G = this.G;
		 if(G.polygon){map.removeOverlay(G.polygon);}
		 for (i=0;i<G.polygonMarkers.length;i++) {
			map.removeOverlay(G.polygonMarkers[i]);
		}
		 map.closeInfoWindow();
		 if(G.newline){map.removeOverlay(G.newline);G.newline=null;}
		 G.polygonMarkers = new Array();
		 G.polygonPoints = new Array();
		 map.closeInfoWindow();
		 GEvent.removeListener(G.addnewpolygonline_handler);
		 GEvent.removeListener(G.polygon_handler);
	}
}
 
/*this is what the editing infoWindow actually looks like (uses google.css)
<div id="editInfoWindow"  style="position: relative; left: 7px; top: 10px; width: 279px; height: 228px; z-index: 10; background-image:url(transparent.gif)">
	<div>
		<div class="msedit">
			<table class="iwspan">
				<tbody>
					<tr>
						<td>
							<table class="inputField">
								<tbody>
									<tr>
										<td class="label">Title</td>
										<td>
										<input class="title" type="text" maxlength="250"/>
										</td>
										<td>
										<div class="icon">
											<a id="changeColor" href="javascript:void(0)"><div class="poly" style="border-color: rgb(191, 191, 191); background-color: rgb(140, 140, 255);"/>
											</a>
										</div>
										</td>
									</tr>
								</tbody>
							</table>
							<table class="inputField">
								<tbody>
									<tr>
										<td class="label">Description</td>
										<td class="tabs">
											<table>
												<tbody>
													<tr>
														<td>
														<span class="stab">Plain text</span>
														</td>
													</tr>
												</tbody>
											</table>
										</td>
									</tr>
								</tbody>
							</table>
						</td>
					</tr>
				</tbody>
			</table>
		<div>
		<div id="rtfield" class="textField description"/>
			<textarea name="textarea" class="textField description"></textarea>
		</div>
		<table style="margin-top:20px">
			<tbody>
				<tr>
					<td class="navLeft">
					<span class="lk"></span><a id="polyDelete" style="cursor: pointer;" href="javascript:void(0)">Delete </a>
					</td>
					<td class="navLeft"><span class="lk"></span><a id="polyEdit" style="cursor: pointer;" href="javascript:void(0)"> Edit</a></td>
					<td class="navRight">
					<button>Cancel</button>
					</td>
					<td class="navRight">
					<button>OK</button>
					</td>
				</tr>
			</tbody>
		</table>
	</div>
	<div class="msstyle" style="display:none; position: absolute; left: 0px; top: 0px;"/>
	</div>
</div>*/

//here it is compacted
//<div id="editInfoWindow"  style="position: absolute; left: 16px; top: 16px; width: 279px; height: 228px; z-index: 10; background-image:url(transparent.gif)"><div><div class="msedit"><table class="iwspan"><tbody><tr><td><table class="inputField"><tbody><tr><td class="label">Title</td><td><input class="title" type="text" maxlength="250"/></td><td><div class="icon"><div class="poly" style="border-color: rgb(191, 191, 191); background-color: rgb(140, 140, 255);"/></div></td></tr></tbody></table><table class="inputField"><tbody><tr><td class="label">Description</td><td class="tabs"><table><tbody><tr><td><span class="stab">Plain text</span></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table><div><div id="rtfield" class="textField description"/><textarea name="textarea" class="textField description"></textarea></div><table style="margin-top:20px"><tbody><tr><td class="navLeft"><span class="lk"></span><a id="polyDelete" style="cursor: pointer;" href="javascript:void(0)">Delete</a></td><td class="navRight"><button>Cancel</button></td><td class="navRight"><button>OK</button></td></tr></tbody></table></div><div class="msstyle" style="display:none; position: absolute; left: 0px; top: 0px;"/></div></div>  

//full editColor window
/*<div id="colorPickerDiv" style="position: relative; z-index:100; top:0px; left:0px; width:284px; height:344px; background-image:url(transparent.gif)">
	<form action="javascript:void(0);" style="width: 274px;">
	  <div class="form-item">
	  	<label for="color"></label>
	  		<input type="text" style="display:none" id="color" name="color" value="#123456" />
	  </div>
	  <div id="picker2">
	  </div>
	</form>
	<table class="msstyle" style="height: 118px;">
		<tbody>
			<tr>
				<td style="vertical-align: top;">
					<table class="msline">
						<tbody>
							<tr>
								<td colspan="2">
									<b class="title">Edit line style</b>
								</td>
							</tr>
							<tr>
								<td class="label">
									Line width (pixels, 1-20)
								</td>
								<td>
									<input id="polygonWeight" class="numberfield" type="text" size="3" value="'+G.prmPolygons[k][5]+'"/>
								</td>
							</tr>
							<tr>
								<td class="label">
									Fill opacity (10-100)
								</td>
								<td>
									<input class="numberfield" id="polygonOpacity" type="text" size="3" value="'+G.prmPolygons[k][6]*100+'"/>
								</td>
							</tr>
						</tbody>
					</table>
				</td>
			</tr>
			<tr>
				<td>
					<table>
						<tbody>
							<tr>
								<td class="navLeft"/>
								<td class="navRight">
									<button id="cancelPoly2">Cancel</button>
								</td>
								<td class="navRight">
									<button id="okPoly2">OK</button>
								</td>
							</tr>
						</tbody>
					</table>
				</td>
			</tr>
		</tbody>
	</table>
</div>');*/

//compacted	editColor     	
//<div id="colorPickerDiv" style="position: relative; z-index:100; top:0px; left:0px; width:284px; height:344px; background-image:url(transparent.gif)"><form action="javascript:void(0);" style="width: 274px;">  <div class="form-item"><label for="color"></label><input type="text" style="display:none" id="color" name="color" value="#123456" /></div><div id="picker2"></div></form><table class="msstyle" style="height: 118px;"><tbody><tr><td style="vertical-align: top;"><table class="msline"><tbody><tr><td colspan="2"><b class="title">Edit line style</b></td></tr><tr><td class="label">Line width (pixels, 1-20)</td><td><input id="polygonWeight" class="numberfield" type="text" size="3" value="'+G.prmPolygons[k][5]+'"/></td></tr><tr><td class="label">Fill opacity (10-100)</td><td><input class="numberfield" id="polygonOpacity" type="text" size="3" value="'+G.prmPolygons[k][6]*100+'"/></td></tr></tbody></table></td></tr><tr><td><table><tbody><tr><td class="navLeft"/><td class="navRight"><button id="cancelPoly2">Cancel</button></td><td class="navRight"><button id="okPoly2">OK</button></td></tr></tbody></table></td></tr></tbody></table></div>');
	     	