/* A Bar is a simple overlay that outlines a lat/lng bounds on the
 * map. It has a border of the given weight and color and can optionally
 * have a semi-transparent background color.
 * @param latlng {GLatLng} Point to place bar at.
 * @param opts {Object Literal} Passes configuration options - 
 *   weight, color, height, width, text, and offset.
 */
function LightMarker(latlng, opts) {
  this.latlng = latlng;

  if (!opts) opts = {};

  this.height_    = opts.height    || 20;
  this.width_     = opts.width     || 20;
  this.className_ = opts.className || null;
  this.clicked_   = 0;  
  
  this.prototype = new GOverlay();
}

/* LightMarker extends GOverlay class from the Google Maps API
 */
//LightMarker.prototype = new GOverlay();

/* Creates the DIV representing this LightMarker.
 * @param map {GMap2} Map that the overlay is added to.
 */
LightMarker.prototype.initialize = function(map) {
  var me = this;

  // Create the DIV representing our LightMarker
  var markerDiv = document.createElement('div');
  markerDiv.className = 'jmarker';
  if(this.className_) {    
    markerDiv.className += ' ' + this.className_;
  }
  
  GEvent.addDomListener(markerDiv, "mouseover", function(event) {
    me.clicked_ = 1;
    GEvent.trigger(me, "mouseover");
  });
  
  GEvent.addDomListener(markerDiv, "mouseout", function(event) {
    me.clicked_ = 0;
    GEvent.trigger(me, "mouseout");
  });

  map.getPane(G_MAP_MARKER_PANE).appendChild(markerDiv);

  this.map_ = map;
  this.div_ = markerDiv;  
};


/* Remove the main DIV from the map pane
 */
LightMarker.prototype.remove = function() {
  GEvent.clearInstanceListeners(this.div_);
  this.div_.parentNode.removeChild(this.div_);
};

/* Copy our data to a new LightMarker
 * @return {LightMarker} Copy of bar
 */
LightMarker.prototype.copy = function() {
  var opts = {};
  opts.height = this.height_;
  opts.width  = this.width_;
  return new LightMarker(this.latlng, opts);
};

/* Redraw the LightMarker based on the current projection and zoom level
 * @param force {boolean} Helps decide whether to redraw overlay
 */
LightMarker.prototype.redraw = function(force) {

  // We only need to redraw if the coordinate system has changed
  if (!force) return;

  // Calculate the DIV coordinates of two opposite corners 
  // of our bounds to get the size and position of our LightMarker
  var divPixel = this.map_.fromLatLngToDivPixel(this.latlng);

  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width  = this.width_ + 'px';
  this.div_.style.left   = (divPixel.x - (this.width_/2)) + 'px'
  this.div_.style.height = (this.height_) + 'px';
  this.div_.style.top    = (divPixel.y) - (this.height_/2) + 'px';
};

LightMarker.prototype.getZIndex = function(m) {
  return GOverlay.getZIndex(m.getPoint().lat())-m.clicked_*10000;
}

LightMarker.prototype.getPoint = function() {
  return this.latlng;
};

LightMarker.prototype.getLatLng = function() {
  return this.latlng;
};

LightMarker.prototype.setStyle = function(style) {
  for (s in style) {
    this.div_.style[s] = style[s];
  }
};

LightMarker.prototype.setImage = function(image) {
  this.div_.style.backgroundImage = 'url("' + image + '")';
}

LightMarker.prototype.highlight = function() {
  this.div_.className   += ' highlight';
  this.div_.style.zIndex = 99999;
}

LightMarker.prototype.removeHighlight = function() {
  this.div_.className    = this.div_.className.replace(/ highlight/, '');
  this.div_.style.zIndex = this.getZIndex(this);
}




function myInfoWindow(marker, contentNode) {
  this.prototype      = new GOverlay();
  this.marker_        = marker      || null;
  this.contentNode_   = contentNode || null;
  this.container_     = null;
  this.map_           = null;
}

//called everytime an infowindow is created
myInfoWindow.prototype.initialize = function(map) {	
 
	//create the container
  var iwCont    = document.createElement('div');
  iwCont.id     = 'iw-window';
  iwCont.style.display = 'none';	
  
	//the corners and the content
	var htmlContent = '<b class="iw-tl"><b class="iw-tr">&nbsp;</b></b>'
            	    + '<div class="iw"></div>'
            	    + '<b class="iw-bl"><b class="iw-br">&nbsp;</b></b>';
            	    
	iwCont.innerHTML = htmlContent;  	
  map.getPane(G_MAP_FLOAT_PANE).appendChild(iwCont);
  
  //get the node of the content div
  var iwContent = iwCont.getElementsByTagName('div')[0];
    
	this.map_       = map;
  this.container_ = iwCont;
  this.content_   = iwContent;
}


myInfoWindow.prototype.remove = function() {
	this.container_.parentNode.removeChild(this.container_);
}

myInfoWindow.prototype.copy = function() {
	return new myInfoWindow(this.marker_, this.contentNode_);
}

myInfoWindow.prototype.redraw = function(force) {
	if (!force) return;
	
	if(!this.contentNode_) {
	  return;
	}
	
	//determine the height and the width of the content node
		
	//avoid having the same id twice in the document
	var parentNodeOri = this.contentNode_.parentNode;
	if(parentNodeOri) {
	  parentNodeOri.removeChild(this.contentNode_);	
	}
	else {
	  return;
	}
	this.map_.getContainer().appendChild(this.contentNode_);
	
	this.contentNode_.style.visibility = 'hidden';	
	this.contentNode_.style.width      = 'auto';
	this.contentNode_.style.height     = 'auto';
	this.contentNode_.style.display    = 'block';
	this.contentNode_.style.styleFloat = 'left';
	this.contentNode_.style.cssFloat   = 'left';
	
	//retrieve the rendered width and height and add the corners height to the height
	var contentWidth  = this.contentNode_.offsetWidth;
	var contentHeight = this.contentNode_.offsetHeight + 10;
	
	//the content width should be an even number, otherwise there are css problems
	if(contentWidth % 2 != 0) {
	  contentWidth = contentWidth + 1;
	}
	
	//move the node back		
	this.contentNode_.parentNode.removeChild(this.contentNode_);
	parentNodeOri.appendChild(this.contentNode_);
	
	this.contentNode_.style.visibility = 'visible';	
	
	//now put the innerhtml from the content node into the infowindow
	this.content_.innerHTML = this.contentNode_.innerHTML;
	
	//and position the window	
	var pxPos = this.map_.fromLatLngToDivPixel(this.marker_.getPoint());
		
	this.container_.style.display = 'block';
	this.container_.style.position = 'absolute';
	this.container_.style.left     = (pxPos.x) + "px";
	this.container_.style.top      = (pxPos.y - contentHeight - 5 - this.marker_.height_) + "px";
	
	this.container_.style.width   = contentWidth  + 'px';
	this.container_.style.height  = contentHeight + 'px';

	//pan if necessary so it shows on the screen
	var mapNE = this.map_.fromLatLngToDivPixel(this.map_.getBounds().getNorthEast());
  var mapSW = this.map_.fromLatLngToDivPixel(this.map_.getBounds().getSouthWest());
  
	var panX = 0;
	var panY = 0;
	
  //top of window is above the top edge of the map container
	if(this.container_.offsetTop - 10 < mapNE.y) {
		panY = (mapNE.y - (this.container_.offsetTop - 10)) + 20;
	}	
	
  //right edge of window is outside the right edge of the map container
	if(this.container_.offsetLeft+contentWidth+10 > mapNE.x) {
		panX = ((this.container_.offsetLeft+contentWidth+10) - mapNE.x) + 20;
	}
	
//	//bottom edge is to close to the bottom
//	if(this.container_.offsetTop + contentHeight + 50 > mapSW.y) {
//		panY = (mapSW.y - (this.container_.offsetTop + contentHeight + 50)) - 20;
//	}

//  //left edge of window is to close the left edge of the map container
//	if(this.container_.offsetLeft - 20 < mapSW.x) {
//		panX = (mapSW.x - (this.container_.offsetLeft + 20)) - 20;
//	}

  //pan the map
	if(panX != 0 || panY != 0) {
		this.map_.panBy(new GSize(-panX,panY));
	}
}

//@todo: fix this
myInfoWindow.prototype.addAction = function(eventString, eventHandler) {
  if(this.container_) {
    eventHandler(this.container_);
  }
}

myInfoWindow.prototype.getPoint = function() {
  if(this.marker_) {
    return this.marker_.getLatLng();
  }
}

myInfoWindow.prototype.hide = function() {
  if(this.container_) {
    this.container_.style.display = 'none';
  }
}

myInfoWindow.prototype.show = function() {
  if(this.container_) {
    this.container_.style.display = 'block';
  }
}