function InfoBox(args) {
	this.opts = {
		offsetVertical		: -31,
		offsetHorizontal	: -279,
		className			: "infobox pngfix",
		spacing				: 10
	};

	this.map_				= args.map;
	this.latlng_			= args.latlng;
	this.url_				= args.url;
		
	this.setMap(this.map_);
}

/* InfoBox extends GOverlay class from the Google Maps API */
InfoBox.prototype = new google.maps.OverlayView();

InfoBox.prototype.remove = function() {
	if (this.div_) {
		this.div_.remove();
		this.div_ = null;
	}
};

InfoBox.prototype.hide = function() {
	if (this.div_) {
		this.div_.hide();
	}
};

InfoBox.prototype.show = function() {
	if (this.div_) {
		this.div_.show();
		this.panMap();
	}
};

InfoBox.prototype.toggle = function() {
	if (this.div_) {
		if (this.div_.is(":hidden")) {
			this.show();
		} else {
			this.hide();
		}
	}
};

InfoBox.prototype.draw = function() {
	// Creates the element if it doesn't exist already.
	if (!this.div_) this.createElement();

	// Calculate the DIV coordinates of two opposite corners of our bounds to
	// get the size and position of our Box
	var pixPosition = this.getProjection().fromLatLngToDivPixel(this.latlng_);
	if (!pixPosition) return;

	// Now position our DIV based on the DIV coordinates of our bounds
	this.div_.css({
		left: (pixPosition.x + this.opts.offsetHorizontal) + "px",
		top: (pixPosition.y + this.opts.offsetVertical) + "px"
	});
};

InfoBox.prototype.createElement = function() {
	var pane = $(this.getPanes().floatPane);
	var div = this.div_;
	if (!div) {
		// This does not handle changing panes.  You can set the map to be null and
		// then reset the map to move the div.
		div = this.div_ = $('<div />');
		div.addClass(this.opts.className);
		div.css({
			position: "absolute",
			zIndex: 1000
		});
		
		var that = this;
		pane.append(div);
		that.panMap();
		
		div.load(that.url_, function(data, status) {
			$('.close', div).click(function(e) {
				that.hide();
				e.stopPropagation();
				e.preventDefault();
			});
		});
		
	} else if (div.parent() != pane) {
		// The panes have changed.  Move the div.
		div.remove();
		pane.append(div);
	} else {
		// The panes have not changed, so no need to create or move the div.
	}
};

/* Pan the map to fit the InfoBox.*/
InfoBox.prototype.panMap = function() {
	// if we go beyond map, pan map
	var projection = this.getProjection();
	var position = projection.fromLatLngToDivPixel(this.latlng_);

	var nePix = new google.maps.Point(position.x + this.opts.offsetHorizontal + this.div_.outerWidth() + this.opts.spacing, position.y + this.opts.offsetVertical - this.opts.spacing);
	var swPix = new google.maps.Point(position.x + this.opts.offsetHorizontal - this.opts.spacing, position.y + this.opts.offsetVertical + this.div_.outerHeight() + this.opts.spacing);

	var ne = projection.fromDivPixelToLatLng(nePix);
	var sw = projection.fromDivPixelToLatLng(swPix);

	var boxBounds = new google.maps.LatLngBounds(sw,ne);

	this.map_.panToBounds(boxBounds);
};


