function InfoBox(latlng, opts) {
  this.latlng_ = latlng;
  this.content_ = opts.content || "Hello World";
  this.offsetVertical_ = opts.offsetVertical || -5;
  this.offsetHorizontal_ = opts.offsetHorizontal || -5;

  this.className_ = opts.className || "";  
  this.height_ = opts.height || 200;
  this.width_ = opts.width || 300;
}

InfoBox.prototype = new GOverlay();

InfoBox.prototype.initialize = function(map) {
  var div = document.createElement("div");

  if (this.className_ != "") {
    div.className = this.className_;
  }

  var contentDiv = document.createElement("div");
  contentDiv.innerHTML = this.content_;


  function removeInfoBox(ib, m) {
    return function() { 
      GEvent.trigger(ib, "closeclick");
      m.removeOverlay(ib);
    };
  }
  
  div.appendChild(contentDiv);
  div.style.display = 'none';

  map.getPane(G_MAP_MARKER_PANE).appendChild(div);

  this.map_ = map;
  this.div_ = div;
}

InfoBox.prototype.remove = function() {
  this.div_.parentNode.removeChild(this.div_);
}

InfoBox.prototype.copy = function() {
  var opts = {};
  opts.latlng = this.latlng_;
  opts.content = this.content_;
  opts.offsetVertical = this.offsetVertical_;
  opts.offsetHorizontal = this.offsetHorizontal_;

  opts.className = this.className_ || "";  
  opts.height = this.height_;
  opts.width = this.width_;
  return new InfoBox(this.latlng, opts);
}

InfoBox.prototype.redraw = function(force) {
  if (!force) return;
  var pixPosition = this.map_.fromLatLngToDivPixel(this.latlng_);

  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 mapWidth = this.map_.getSize().width;
  var mapHeight = this.map_.getSize().height;
  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) - 10 + "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.div_.offsetHeight+20)/mapHeight*latSpan)) {
	this.div_.style.top = (pixPosition.y - this.div_.offsetHeight - this.height_) + "px";
  }

  var bottompt = new GLatLng( (this.latlng_.lat() - degHeight), this.latlng_.lng());
  if (!bounds.contains(bottompt)) {
    //this.map_.panTo(this.latlng_);
  }
}