function FakeMenuControl() {}
FakeMenuControl.prototype = new GControl();
FakeMenuControl.prototype.initialize = function(map) {
  var container = document.createElement("div");
  map.getContainer().appendChild(container);
  return container;
}
FakeMenuControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize($('map').getWidth(), 150));
}
//------------------------------------------------------------------------------
function FakeOnMapListControl() {}
FakeOnMapListControl.prototype = new GControl();
FakeOnMapListControl.prototype.initialize = function(map) {
  var container = document.createElement("div");
  map.getContainer().appendChild(container);
  return container;
}
FakeOnMapListControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(365, $('map').getHeight()));
}
//------------------------------------------------------------------------------
var fakeOnMapListControl = new FakeOnMapListControl();
//------------------------------------------------------------------------------

// TODO clean up and delete unused stuff
Map = function (centerX, centerY, zoom) {
  // scroll at least 30 pixels to invoke a new fetchmarker()
  this.fetchThreshold = 30;

  this.clusterIcon = new GIcon();
  this.clusterIcon.image = "/images/icons/cluster.png";
  this.clusterIcon.transparent = "/images/icons/cluster-transparent.png";
  this.clusterIcon.shadow = "/images/icons/iconshadow.png";
  this.clusterIcon.iconSize=new GSize(22,32);
  this.clusterIcon.shadowSize=new GSize(34,34);
  this.clusterIcon.iconAnchor=new GPoint(11,29);
  this.clusterIcon.infoWindowAnchor=new GPoint(13,0);
  this.clusterIcon.imageMap = [0,0, 21,0, 21,31, 0,31];
  
  this.miniClusterIcon = new GIcon();
  this.miniClusterIcon.image = "/images/icons/minicluster.png";
  this.miniClusterIcon.transparent = "/images/icons/marker-transparent.png";
  this.miniClusterIcon.shadow = "/images/icons/iconshadow.png";
  this.miniClusterIcon.iconSize=new GSize(18,26);
  this.miniClusterIcon.shadowSize=new GSize(34,34);
  this.miniClusterIcon.iconAnchor=new GPoint(8,25);
  this.miniClusterIcon.infoWindowAnchor=new GPoint(11,0);
  this.miniClusterIcon.imageMap = [0,0, 17,0, 17,25, 0,25];

  this.markerIcon = new Array(11);
  for(var i = 0; i < this.markerIcon.length; i++) {
    this.markerIcon[i] = new GIcon();
    this.markerIcon[i].image = "/images/icons/" + (i + 1) + ".png";
    this.markerIcon[i].transparent = "/images/icons/marker-transparent.png";
    this.markerIcon[i].shadow = "/images/icons/iconshadow.png";
    this.markerIcon[i].iconSize=new GSize(18,26); 
    this.markerIcon[i].shadowSize=new GSize(34,34);
    this.markerIcon[i].iconAnchor=new GPoint(8,25);
    this.markerIcon[i].infoWindowAnchor=new GPoint(11,0);
    this.markerIcon[i].imageMap = [0,0, 17,0, 17,25, 0,25];
  }

  this.openId = 0;
  this.oldZoom = 0;

  if(!GBrowserIsCompatible()) {
    alert("Ihr Browser wird zur Zeit leider nicht unterstuetzt.");
    return;
  }
  this.fetched = false;
};

Map.prototype.load = function(x, y, z, preload) {
  this.map = new GMap2(document.getElementById("map"));
  this.currentZoomLevel = this.map.getZoom();
  this.map.enableDoubleClickZoom();
  
  this.map.enableScrollWheelZoom();
  
  this.upperMapControlPosition = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(37,140));
  this.lowerMapControlPosition = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(37,280));
  this.upperZoomControlPosition = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(37,410));
  this.lowerZoomControlPosition = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(37,550));
  
  this.mapControl      = new GLargeMapControl();
  this.dragZoomControl = new DragZoomControl({}, {buttonHTML: '', buttonZoomingHTML: ''});
  
  this.map.addControl(this.mapControl, this.upperMapControlPosition);
  this.map.addControl(this.dragZoomControl, this.upperZoomControlPosition);
  this.map.addControl(new FakeMenuControl());
  this.map.addControl(fakeOnMapListControl);

  this.map.setCenter(new GLatLng(x, y), z);
  this.manager = new ClusterManager(this.map, this.miniClusterIcon);

  var tmp = new GKeyboardHandler(this.map);
  
  GEvent.bind(this.map, "moveend", this, this.moveend);
  GEvent.bind(this.map, "movestart", this, this.movestart);
  GEvent.bind(this.map, "zoomend", this, this.zoomfetch);

  if(preload) { this.fetch(true); }
};

Map.prototype.setMapControlPositionUp = function(up) {
  this.map.removeControl(this.mapControl);
  this.map.removeControl(this.dragZoomControl);
  if(up) {
    this.map.addControl(this.mapControl, this.upperMapControlPosition);
    this.map.addControl(this.dragZoomControl, this.upperZoomControlPosition);
  } else {
    this.map.addControl(this.mapControl, this.lowerMapControlPosition);
    this.map.addControl(this.dragZoomControl, this.lowerZoomControlPosition);
  }
}

Map.prototype.resize = function () {
  this.map.checkResize();
  this.fetch(true);
}

// fetch new markers, only if moved more then a specific threshold
Map.prototype.moveend = function() {
  var point = this.map.fromLatLngToDivPixel(this.map.getCenter());
  if(Math.abs(point.x - this.x) > this.fetchThreshold || Math.abs(point.y - this.y) > this.fetchThreshold) {
    this.x = point.x;
    this.y = point.y;
    this.fetch(false);
  }
};

// save start of movement for threshold
Map.prototype.movestart = function() {
  if(this.fetched === true) {
    var point = this.map.fromLatLngToDivPixel(this.map.getCenter());
    this.x = point.x;
    this.y = point.y;
    this.fetched = false;
  }
};

Map.prototype.fetch = function(full) {
  notify('');
  this.fetched = true;

  var bounds = this.map.getBounds();
  var center = this.map.getCenter();
  var tmp = new Ajax.Request('/map/fetchmarker', { // TODO pfad anpassen
    method:'get',
    parameters: {minlat: bounds.getSouthWest().lat(), maxlat: bounds.getNorthEast().lat(),
                  minlng: bounds.getSouthWest().lng(), maxlng: bounds.getNorthEast().lng(),
                  zoom: this.map.getZoom(), lat:center.lat(), lng:center.lng(), full:full },
    onSuccess: function(transport){
      var json = eval('(' + transport.responseText + ')');
      if(json.length === 100) { // TODO sync with app_max_marker_to_cluster
        notify("Zoomen f&uuml;r weitere Artikel");
      }
      map.putMarkers(json);
    }
  });
};

Map.prototype.clear = function () {
  this.manager.clearMarkers();

  var table = $("onmaplist-table")
  while(table.rows.length > 1)
    table.deleteRow(1);
  
  //$('onmaplist').innerHTML = '';
  // does not work in IE :(
}

Map.prototype.zoomfetch = function () {
  this.clear();
  this.fetch(true);
  if((this.oldZoom < 11 && this.map.getZoom() >= 11)
    || (this.oldZoom >= 11 && this.map.getZoom() < 11)) {
  new Ajax.Updater("search-notifier", "map/getSearchNotifier", {evalScripts: true});
  }
  this.oldZoom = this.map.getZoom();
};

Map.prototype.setOpenId = function(id) {  
  this.openId = id;
  if(id != 0 && this.manager.hasId(id)) {
    this.manager.openInfoWindow(id);
    this.openId = 0;
  }
  
};

Map.prototype.putMarkers = function(markers) {
  var bounds = this.map.getBounds();
  this.manager.strip(bounds, function(id) { if($('list_' + id)) Element.remove('list_' + id) });
  
  for (var i = 0; i < markers.length; i++) {
    var current = markers[i];
    var point = new GLatLng(current.lat, current.lon);
    var marker = null;
    if(current.type === 'cluster' && this.map.getZoom() < 11) { // TODO set to max_zoom_to_cluster
      if(!this.manager.hasId(current.id)) {
        marker = this.createCluster(point, current.id, current.cat, current.title, current.lat, current.lon);              
        this.manager.addMarker(marker);
        if(!$('onmaplist-cluster')) {
          var tr = '<tr id="onmaplist-cluster"><td><div class="nofavs">Die <img src="/images/icons/cluster-small.gif" align="top" /> zeigen Dir, wo wieviele Artikel liegen.</div></td></tr>';
          new Insertion.Top('onmaplist', tr);
        }
      }
    } else if(current.type !== 'cluster' && this.map.getZoom() >= 11) {  // TODO set to max_zoom_to_cluster      
      if(!this.manager.hasId(current.id)) {
        marker = this.createMarker(point, current.title, current.text, current.id, current.cat, current.price);        
        this.manager.addMarker(marker);

        var tr = '<tr id="list_' + current.id + '"><td><a class=\"icon fav\" title=\"Zu Favoriten hinzuf&uuml;gen\" href=\"#\" onclick="add_fav('+ current.id +'); return false;" onmouseover="Tip(\'&lt;div class=&quot;tooltip&quot;&gt;Als Favorit speichern&lt;/div&gt;\');" onmouseout="UnTip();"/><a href="#" onclick="show_article('
          + current.id + ','
          + current.lat+ ','
          + current.lon+ ', false); return false;">'
          + current.title.stripTags().unescapeHTML().truncate(35).escapeHTML()
          + "</a></td></tr>";        
        new Insertion.Top('onmaplist', tr);
      }
    }
  }
  if(this.openId != 0) {
    this.manager.openInfoWindow(this.openId);
    this.setOpenId(0);
  }
};

Map.prototype.createMarker = function(point,title,bubble,id,cat,price) {
  var marker = new GMarker(point, this.markerIcon[cat - 1]);
  GEvent.addListener(marker, "mouseover", function() {
    marker.openInfoWindowHtml('<div style="height:1.6em; overflow: hidden;">' + title + "</div>" + bubble);
  });
  GEvent.addListener(marker, "click", function() { fetch_article(id); });
  return {overlay: marker, id: id, title: title, bubble: bubble, cat: cat, price: price};
};

// zoom into a cluster
Map.prototype.zoomCluster = function(point) {
  this.map.savePosition()
  this.map.setCenter(point, 11); // TODO set to max_zoom_to_cluster
};

// create a special marker for clusters
Map.prototype.createCluster = function(point, id, cat, title, lat, lng) {
  var marker = new GMarker(point, this.clusterIcon);
  GEvent.addListener(marker, "mouseover", function() {
      marker.openInfoWindowHtml("<p><b>Es gibt<br/>" + title + "</b><br/><span class=\"info\" style=\"font-size:.9em;\">(Klick um n&auml;her zu Zoomen.)</span></p>");
  });
  GEvent.addListener(marker, "click", function() {
    map.zoomCluster(new GLatLng(lat,lng));
  });
  return {overlay: marker, id: id, title: title};
}
