/* BFInfoWindow mimics the InfoWindow class found Google Maps API v3 but allows
* the user to define their own info window styles.
* @author Peter Robinett, peter@bubblefoundry.com
* @version 0.1
*/
 
/* An BFInfoWindow is like an info window, but it displays under the marker,
* opens quicker, and has flexible styling. Overload its createElement to style the info window.
* @param {InfoWindowOptions} options An options object
* http://github.com/pr1001/BFInfoWindow/blob/master/bfinfowindow.js
*/
function BFInfoWindow(options) {
  google.maps.OverlayView.call(this);
  this.offsetVertical_ = 25;
  this.offsetHorizontal_ = -110;
  this.height_ = 90;
  this.width_ = 220;
  this.setMap(this.map_);
  this.setOptions(options);
}
BFInfoWindow.prototype = new google.maps.OverlayView();
var myMarkerNow;
BFInfoWindow.prototype.open = function(map, anchor) {
  	myMarkerNow = anchor;
	this.set_location(anchor.position);
	this.latlng_ = this.get_location();
	this.map_ = map;
	var self = this;
  	this.setMap(this.map_);
};
BFInfoWindow.prototype.close = function() {this.setMap(null);};
BFInfoWindow.prototype.setOptions = function(options) {this.setValues(options);};
BFInfoWindow.prototype.set_content = function(content) {this.set("content", content);};
BFInfoWindow.prototype.getContent = function() {return this.get("content");};
BFInfoWindow.prototype.set_url = function(myUrl) {this.set("url", myUrl);};
BFInfoWindow.prototype.get_url = function() {return this.get("url");};
BFInfoWindow.prototype.set_location = function(location) {this.set("location", location);};
BFInfoWindow.prototype.get_location = function() {return this.get("location");};
BFInfoWindow.prototype.set_zIndex = function(zIndex) {this.set("zIndex", zIndex);};
BFInfoWindow.prototype.getZIndex = function() {return this.get("zIndex");};
BFInfoWindow.prototype.remove = function() {if (this.div_) {this.div_.parentNode.removeChild(this.div_);this.div_ = null;}};
BFInfoWindow.prototype.draw = function() {
  	this.createElement();
	if (!this.div_) return;
	var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
	if (!pixPosition) return;
	this.div_.style.width = this.width_ + "px";
	this.div_.style.left = (pixPosition.x + this.offsetHorizontal_) + "px";
	this.div_.style.height = this.height_ + "px";
	this.div_.style.top = (pixPosition.y + this.offsetVertical_) + "px";
	this.div_.style.display = 'block';

	this.div_.style.width = this.width_ + "px";
	this.div_.style.left = (pixPosition.x + this.offsetHorizontal_) + "px";
	this.div_.style.height = this.height_ + "px";
	this.div_.style.top = (pixPosition.y + this.offsetVertical_) + "px";
	this.div_.style.display = 'block';
	
	var mapDiv = this.map_.getDiv();
	var mapWidth = mapDiv.offsetWidth;
	var mapHeight = mapDiv.offsetHeight;
	var bounds = this.map_.getBounds();
	var boundsSpan = bounds.toSpan();
	var longSpan = boundsSpan.lng();
	var latSpan = boundsSpan.lat();
	var degWidth = (this.width_/mapWidth) * longSpan;
	var degHeight = (this.height_/mapHeight) * latSpan;
	
	if ((this.latlng_.lng() + (degWidth/2)) > bounds.getNorthEast().lng()) {
		this.div_.style.left = pixPosition.x - (((this.latlng_.lng() + degWidth) - bounds.getNorthEast().lng())/longSpan*mapWidth) - 20 + "px";}
	if ((this.latlng_.lng() - (degWidth/2)) < (bounds.getSouthWest().lng())) {
		new_posit = pixPosition.x + this.width_  - (((this.latlng_.lng() + degWidth) - bounds.getSouthWest().lng())/longSpan*mapWidth) + 10 + "px";
		this.div_.style.left = new_posit;}
	if ((this.latlng_.lat()) < (bounds.getSouthWest().lat())+((this.offsetVertical_ + this.height_)/mapHeight*latSpan)) {
		this.div_.style.top = (pixPosition.y - this.offsetVertical_ - this.height_) + "px";
	}
};
BFInfoWindow.prototype.createElement = function() {
  	var panes = this.getPanes();
	var div = this.div_;
	if (!div) {
		div = this.div_ = document.createElement("div");
		div.style.border = "0px none";
		div.style.position = "absolute";
		//div.style.background = "#f00";
		div.style.width = this.width_ + "px";
		div.style.height = this.height_ + "px";
		div.style.zIndex = this.getZIndex();
		var contentDiv = document.createElement("div");
		contentDiv.id = "BFInfoWindow_content";
		contentDiv.innerHTML = this.getContent();
		div.appendChild(contentDiv);
		div.style.display = 'none';
		panes.floatPane.appendChild(div);
		//this.panMap();
	} else if (	div.parentNode != panes.floatPane) {
		div.parentNode.removeChild(div);
		panes.floatPane.appendChild(div);
		document.getElementById("BFInfoWindow_content").innerHTML = this.getContent();
	} else {
		document.getElementById("BFInfoWindow_content").innerHTML = this.getContent();
	}
};

BFInfoWindow.prototype.removeBFInfoWindow = function(ib) {
	return function() {
		ib.setMap(null);
	};
};
BFInfoWindow.prototype.panMap = function() {
	var map = this.map_;
	var bounds = map.getBounds();
	if (!bounds) return;
	var position = this.latlng_;
	var iwWidth = this.width_;
	var iwHeight = this.height_;
	var iwOffsetX = this.offsetHorizontal_;
	var iwOffsetY = this.offsetVertical_;
	var padX = 40;
	var padY = 40;
	var mapDiv = map.getDiv();
	var mapWidth = mapDiv.offsetWidth;
	var mapHeight = mapDiv.offsetHeight;
	var boundsSpan = bounds.toSpan();
	var longSpan = boundsSpan.lng();
	var latSpan = boundsSpan.lat();
	var degPixelX = longSpan / mapWidth;
	var degPixelY = latSpan / mapHeight;
	var mapWestLng = bounds.getSouthWest().lng();
	var mapEastLng = bounds.getNorthEast().lng();
	var mapNorthLat = bounds.getNorthEast().lat();
	var mapSouthLat = bounds.getSouthWest().lat();
	var iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
	var iwEastLng = position.lng() + (iwOffsetX + iwWidth + padX) * degPixelX;
	var iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
	var iwSouthLat = position.lat() - (iwOffsetY + iwHeight + padY) * degPixelY;
	var shiftLng = (iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) + (iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
	var shiftLat = (iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) + (iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);
	var center = map.getCenter();
	var centerX = center.lng() - shiftLng;
	var centerY = center.lat() - shiftLat;
	map.setCenter(new google.maps.LatLng(centerY, centerX));
	google.maps.event.removeListener(this.boundsChangedListener_);
	this.boundsChangedListener_ = null;
};