function LabeledMarker(latlng, opt_opts){
  this.latlng_ = latlng;
  this.opts_ = opt_opts;

  this.labelText_ = opt_opts.labelText || "";
  this.labelClass_ = opt_opts.labelClass || "LabeledMarker_markerLabel";
  this.labelOffset_ = opt_opts.labelOffset || new GSize(0, 0);
  
  this.clickable_ = opt_opts.clickable || true;
  this.title_ = opt_opts.title || "";
  this.labelVisibility_  = true;
   
  if (opt_opts.draggable) {
  	// This version of LabeledMarker doesn't support dragging.
  	opt_opts.draggable = false;
  }
  
  GMarker.apply(this, arguments);
}


// It's a limitation of JavaScript inheritance that we can't conveniently
// inherit from GMarker without having to run its constructor. In order for 
// the constructor to run, it requires some dummy GLatLng.
LabeledMarker.prototype = new GMarker(new GLatLng(0, 0));

/**
 * Is called by GMap2's addOverlay method. Creates the text div and adds it
 * to the relevant parent div.
 *
 * @param {GMap2} map the map that has had this labeledmarker added to it.
 */
LabeledMarker.prototype.initialize = function(map) {
  // Do the GMarker constructor first.
  GMarker.prototype.initialize.apply(this, arguments);
  
  this.map_ = map;
  this.div_ = document.createElement("div");
  this.div_.className = this.labelClass_;
  this.div_.innerHTML = this.labelText_;
  this.div_.style.position = "absolute";
  this.div_.style.cursor = "pointer";
  this.div_.title = this.title_;
  
  map.getPane(G_MAP_MARKER_PANE).appendChild(this.div_);

  if (this.clickable_) {
    /**
     * Creates a closure for passing events through to the source marker
     * This is located in here to avoid cluttering the global namespace.
     * The downside is that the local variables from initialize() continue
     * to occupy space on the stack.
     *
     * @param {Object} object to receive event trigger.
     * @param {GEventListener} event to be triggered.
     */
    function newEventPassthru(obj, event) {
      return function() { 
        GEvent.trigger(obj, event);
      };
    }
  
    // Pass through events fired on the text div to the marker.
    var eventPassthrus = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout'];
    for(var i = 0; i < eventPassthrus.length; i++) {
      var name = eventPassthrus[i];
      GEvent.addDomListener(this.div_, name, newEventPassthru(this, name));
    }
  }
}

/**
 * Move the text div based on current projection and zoom level, call the redraw()
 * handler in GMarker.
 *
 * @param {Boolean} force will be true when pixel coordinates need to be recomputed.
 */
LabeledMarker.prototype.redraw = function(force) {
  GMarker.prototype.redraw.apply(this, arguments);
  
  // Calculate the DIV coordinates of two opposite corners of our bounds to
  // get the size and position of our rectangle
  var p = this.map_.fromLatLngToDivPixel(this.latlng_);
  var z = GOverlay.getZIndex(this.latlng_.lat());
  
  // Now position our div based on the div coordinates of our bounds
  this.div_.style.left = (p.x + this.labelOffset_.width) + "px";
  this.div_.style.top = (p.y + this.labelOffset_.height) + "px";
  this.div_.style.zIndex = z; // in front of the marker
}

/**
 * Remove the text div from the map pane, destroy event passthrus, and calls the
 * default remove() handler in GMarker.
 */
 LabeledMarker.prototype.remove = function() {
  GEvent.clearInstanceListeners(this.div_);
  if (this.div_.outerHTML) {
    this.div_.outerHTML = ""; //prevent pseudo-leak in IE
  }
  if (this.div_.parentNode) {
    this.div_.parentNode.removeChild(this.div_);
  }
  this.div_ = null;
  GMarker.prototype.remove.apply(this, arguments);
}

/**
 * Return a copy of this overlay, for the parent Map to duplicate itself in full. This
 * is part of the Overlay interface and is used, for example, to copy everything in the 
 * main view into the mini-map.
 */
LabeledMarker.prototype.copy = function() {
  return new LabeledMarker(this.latlng_, this.opt_opts_);
}


/**
 * Shows the marker, and shows label if it wasn't hidden. Note that this function 
 * triggers the event GMarker.visibilitychanged in case the marker is currently hidden.
 */
LabeledMarker.prototype.show = function() {
  GMarker.prototype.show.apply(this, arguments);
  if (this.labelVisibility_) {
    this.showLabel();
  } else {
    this.hideLabel();
  }
}


/**
 * Hides the marker and label if it is currently visible. Note that this function 
 * triggers the event GMarker.visibilitychanged in case the marker is currently visible.
 */
LabeledMarker.prototype.hide = function() {
  GMarker.prototype.hide.apply(this, arguments);
  this.hideLabel();
}


/**
 * Sets the visibility of the label, which will be respected during show/hides.
 * If marker is visible when set, it will show or hide label appropriately.
 */
LabeledMarker.prototype.setLabelVisibility = function(visibility) {
  this.labelVisibility_ = visibility;
  if (!this.isHidden()) { // Marker showing, make visible change
    if (this.labelVisibility_) {
      this.showLabel();
    } else {
      this.hideLabel();
    }
  }
}


/**
 * Returns whether label visibility is set on.
 * @return {Boolean}  
 */
LabeledMarker.prototype.getLabelVisibility = function() {
  return this.labelVisibility_;
}


/**
 * Hides the label of the marker.
 */
LabeledMarker.prototype.hideLabel = function() {
  this.div_.style.visibility = 'hidden';
}


/**
 * Shows the label of the marker.
 */
LabeledMarker.prototype.showLabel = function() {
  this.div_.style.visibility = 'visible';
}





/**
 * MapIconMaker v1.0
 * Copyright (c) 2008 Pamela Fox
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 *
 *
 *  Author: Pamela Fox
 *
 *  This gives you static function(s) for creating dynamically sized and
 *  colored marker icons using the Charts API marker output.
 */

var MapIconMaker = {};

MapIconMaker.createMarkerIcon = function(opts) {
  var width = opts.width || 32;
  var height = opts.height || 32;
  var primaryColor = opts.primaryColor || "#ff0000";
  var strokeColor = opts.strokeColor || "#000000";
  var cornerColor = opts.cornerColor || "#ffffff";
   
  var baseUrl = "http://chart.apis.google.com/chart?cht=mm";
  var iconUrl = baseUrl + "&chs=" + width + "x" + height + 
      "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "") + "&ext=.png";
  var icon = new GIcon(G_DEFAULT_ICON);
  icon.image = iconUrl;
  icon.iconSize = new GSize(width, height);
  icon.shadowSize = new GSize(Math.floor(width*1.6), height);
  icon.iconAnchor = new GPoint(width/2, height);
  icon.infoWindowAnchor = new GPoint(width/2, Math.floor(height/12));
  icon.printImage = iconUrl + "&chof=gif";
  icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";
  var iconUrl = baseUrl + "&chs=" + width + "x" + height + 
      "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "");
  icon.transparent = iconUrl + "&chf=a,s,ffffff11&ext=.png";

  icon.imageMap = [
      width/2, height,
      (7/16)*width, (5/8)*height,
      (5/16)*width, (7/16)*height,
      (7/32)*width, (5/16)*height,
      (5/16)*width, (1/8)*height,
      (1/2)*width, 0,
      (11/16)*width, (1/8)*height,
      (25/32)*width, (5/16)*height,
      (11/16)*width, (7/16)*height,
      (9/16)*width, (5/8)*height
  ];
  for (var i = 0; i < icon.imageMap.length; i++) {
    icon.imageMap[i] = parseInt(icon.imageMap[i]);
  }

  return icon;
}


var iconTarget = new GIcon();
iconTarget.image = 'assets/images/googlemap/image.png';
iconTarget.shadow = '';
iconTarget.iconSize = new GSize(25,25);
iconTarget.shadowSize = new GSize(30,20);
iconTarget.iconAnchor = new GPoint(10,20);
iconTarget.infoWindowAnchor = new GPoint(10,0);

var iconOptions = {};
iconOptions.width = 50;
iconOptions.height = 50;
iconOptions.primaryColor = "##D5CFB7";
iconOptions.cornerColor = "##FFFFFFFF";
iconOptions.strokeColor = "##000000FF";
var icon = MapIconMaker.createMarkerIcon(iconOptions);

function createMarker1(point,html,label) {
	// === use LabeledMarker to add text to the marker ===
	opts = {
		//"icon": icon,
		"icon": iconTarget,
		"labelText": "<b>"+label+"</b>",      // you can use HTML inside the {labelText}, or you can style it with {labelClass}
		"labelOffset": new GSize(-8, -45)
	};

	var marker1 = new LabeledMarker(point, opts);
	GEvent.addListener(marker1, "click", function() {
		marker1.openInfoWindowHtml(html);
	});

	return marker1;
}

var gMapVar,timerID;

function createMarker2(map,point,html,label) {
	// === use LabeledMarker to add text to the marker ===
	opts = {"icon": iconTarget};
	gMapVar = map;

	var marker1 = new LabeledMarker(point, opts);
	
	GEvent.addListener(marker1, "mouseover", function() {
		marker1.openExtInfoWindow(
			map,
			"devWindow",
			html
		); 

		clearTimeout(timerID);

		newWindow = document.getElementById("devWindow");

		newWindow.onmouseover = function(){
			clearTimeout(timerID);
		}
		
		newWindow.onmouseout = function(){
			timerID = setTimeout("closeMapWindow()", 2000);
		}		
	});
	
	GEvent.addListener(marker1, "mouseout", function() {
		timerID = setTimeout("closeMapWindow()", 2000);
	});	
	
	return marker1;
}

function closeMapWindow(){
	gMapVar.closeExtInfoWindow();
}
	
function createMarker(point, url,descr, label, image,icon) {
	var marker = new LabeledMarker(point, {icon: customIcons[icon], labelText:url, labelOffset: new GSize(-6, -10)});
	markerGroups[icon].push(marker);
	
	var html="<span class='textbold'>" +label+ "</span><br><span class='textlabel'>" +descr + "<br></span>" ;
	
	GEvent.addListener(marker, 'click', function() {
		marker.openInfoWindowHtml(html, { maxWidth: 400});
	});
	
	return marker;
}

function toggleGroup(icon) {
  for (var i = 0; i < markerGroups[icon].length; i++) {
	var marker = markerGroups[icon][i];
	if (marker.isHidden()) {
	  marker.show();
	} else {
	  marker.hide();
	}
  }
}

function makeDataOnMap(data,map) {
  var xml = GXml.parse(data);
  var markers = xml.getElementsByTagName("marker");

  for(var i=0 ; i<markers.length ; i++) {

	var url = markers[i].getAttribute("url");
	var descr = markers[i].getAttribute("descr");
	var label = markers[i].getAttribute("label");
	var image = markers[i].getAttribute("image");
	var icon = markers[i].getAttribute("icon");

	var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
	parseFloat(markers[i].getAttribute("lng")));
	var marker = createMarker(point, url,descr, label, image,icon);
	map.addOverlay(marker);
  }
}
