
var Maps =
{
  mapsArray: new Array(),
  init: function()
  {
    for (var i = 0; i < this.mapsArray.length; i++)
    {
      gmap = this.mapsArray[i];
      gmap.load();
    }
  },
  newMap: function(id)
  {
    return new Map(id);
  },
  newMarker: function()
  {
    return new Marker();
  },
  newCustomControl: function(args)
  {
    return new CustomControl(args);
  },
  getMapById: function(id)
  {
    for (var i = 0; i < this.mapsArray.length; i++)
    {
      var map = this.mapsArray[i];
      if (map.div.id == id)
      {
        return map;
      }
    }
    return false;
  },
  addMapToArray: function(map)
  {
    map.posInArray = this.mapsArray.length;
    this.mapsArray.push(map);
  },
  getAnchor: function(rawAnch)
  {
    var anchor;
    switch (rawAnch)
    {
      case 'top-right':
        {
          anchor = G_ANCHOR_TOP_RIGHT;
          break;
        }
      case 'top-left':
        {
          anchor = G_ANCHOR_TOP_LEFT;
          break;
        }
      case 'bottom-right':
        {
          anchor = G_ANCHOR_BOTTOM_RIGHT;
          break;
        }
      case 'bottom-left':
        {
          anchor = G_ANCHOR_BOTTOM_LEFT;
          break;
        }
      default:
        {
          anchor = G_ANCHOR_TOP_RIGHT;
        }
    }
    return anchor;
  }
}

//Gmap object
function Map(id)
{
  this.div = document.getElementById(id); 
  this.controls = new Array();
  this.events = new Array();  
  this.markers = new Array();
  this.icons = new Array();
};
Map.prototype =
{
  gmap: null,
  div: null,
  posInArray: null,
  controls: null,
  events: null,
  markers: null,
  icons: null,
  originalPosition: null,
  query: null,
  lng: null,
  lat: null,
  bounds: null,
  type: null,
  zoomlevel: 5,
  load: function() {
    if (GBrowserIsCompatible()) {
      //      //fix for the display none bug
      //      var sibling = this.div.nextSibling;
      //      var parent = this.div.parentNode;
      //      parent.removeChild(this.div);
      //      this.div.style.marginLeft = '-1500em';
      //      document.body.appendChild(this.div);               
      //end of fix

      this.gmap = new GMap2(this.div);

      if (this.type != null)
        this.gmap.setMapType(window[this.type]);

      this.setCenter();
      this.loadIcons();
      this.loadControls();
      this.loadEvents();
      this.loadMarkers();

      //fix for the display none bug
      //      this.div.parentNode.removeChild(this.div);
      //      this.div.style.marginLeft = '';
      //      parent.insertBefore(this.div, sibling);
      //end of fix
    }
  },
  addControlToArray: function(c) {
    this.controls.push(c);
  },
  addEventToArray: function(e, f) {
    this.events.push(new Array(e, f));
  },
  addIconToArray: function(icon) {
    this.icons.push(icon);
  },
  addMarkerToArray: function(marker) {
    marker.posInArray = this.markers.length;
    this.markers.push(marker);
  },
  loadControls: function() {
    for (var i = 0; i < this.controls.length; i++) {
      var control = this.controls[i];
      if (typeof (control) == 'object') {
        if (control.args.position) {
          var anchor = Maps.getAnchor(control.args.position.anchor);
          var rawPadding = control.args.position.padding.replace(' ', '');
          paddingArr = rawPadding.split(',');
          var left = paddingArr[0];
          var top = paddingArr[1];
          this.gmap.addControl(control, new GControlPosition(anchor, new GSize(1 * left, 1 * top)));
        }
        else
          this.gmap.addControl(control);
      }
      else
        this.gmap.addControl(new window[control]);
    }
  },
  loadEvents: function() {
    for (var i = 0; i < this.events.length; i++) {
      var eventName = this.events[i][0];
      var functionName = this.events[i][1];
      var gmap = this.gmap;
      GEvent.addListener(this.gmap, eventName, function() {
        var obj = window;
        var functionNameParts = functionName.split('.');
        for (var i = 0; i < functionNameParts.length; i++)
          obj = obj[functionNameParts[i]];
        obj(gmap, arguments);
      });
    }
  },
  loadIcons: function() {
    for (var i = 0; i < this.icons.length; i++) {
      var icon = this.icons[i];
      var gIcon = new GIcon(G_DEFAULT_ICON, icon.src);
      gIcon.iconSize = new GSize(1 * icon.width, 1 * icon.height);
      gIcon.shadow = null;
      icon.gIcon = gIcon;
    }
  },
  loadMarkers: function() {
    for (var i = 0; i < this.markers.length; i++) {
      marker = this.markers[i];
      if (marker.lng != null && marker.lat != null) {
        var LatLng = new GLatLng(marker.lat, marker.lng);
        this.setMarker(LatLng, marker);
      }
      else if (marker.query != null) {
        this.getMarkerLatLng(marker);
      }
    }
  },
  getMarkerLatLng: function(marker) {
    var pos = this.posInArray;
    var geocoder = new GClientGeocoder();
    geocoder.getLatLng(marker.query, function(LatLng) { Maps.mapsArray[pos].setMarker(LatLng, Maps.mapsArray[pos].markers[marker.posInArray]) });
  },
  setCenter: function() {
    if (this.areBoundsValid(this.bounds)) {
      var boundsArr = this.bounds.split('|');
      var sw = new GLatLng(boundsArr[0], boundsArr[1]);
      var ne = new GLatLng(boundsArr[2], boundsArr[3]);
      var bounds = new GLatLngBounds(sw, ne);
      var latlng = bounds.getCenter();
      this.zoomlevel = this.gmap.getBoundsZoomLevel(bounds);
      this.setCenterFromLatLng(latlng);
    }
    else if (this.lng && this.lat && this.lng != '' && this.lat != '') {
      var LatLng = new GLatLng(this.lat, this.lng);
      this.setCenterFromLatLng(LatLng);
    }
    else if (this.query) {
      this.setCenterFromQuery(this.query);
    }
  },
  setCenterFromQuery: function(query) {
    var geocoder = new GClientGeocoder();
    var pos = this.posInArray;
    geocoder.getLatLng(query, function(LatLng) { Maps.mapsArray[pos].setCenterFromLatLng(LatLng) });
  },
  setCenterFromLatLng: function(LatLng)
  {
    this.gmap.setCenter(LatLng, 1 * this.zoomlevel);
    if (!this.originalPosition)
      this.originalPosition = LatLng;
  },
  setMarker: function(LatLng, marker) {
    var opts = {};
    if (marker.draggable == "true")
      opts.draggable = true;

    if (LatLng != null) {
      marker.lat = LatLng.lat();
      marker.lng = LatLng.lng();

      if (marker.icon && marker.icon != '') {
        var icon = this.getIconByName(marker.icon);
        marker.gmarker = new GMarker(LatLng, icon.gIcon);
      }
      else
        marker.gmarker = new GMarker(LatLng, opts);

      marker.loadEvents();
      this.gmap.addOverlay(marker.gmarker);

      if (marker.draggable == "true")
        marker.gmarker.enableDragging();
    }
  },
  areBoundsValid: function(bounds) {
    if (bounds && bounds != '') {
      var boundsArr = bounds.split('|');
      for (var i = 0; i < boundsArr.length; i++) {
        if (!Number(boundsArr[i]))
          return false;
      }
      return true;
    }
    else
      return false;
  },
  doesMarkerExistsOnLatLng: function(lat, lng) {
    for (var i = 0; i < this.markers.length; i++) {
      var marker = this.markers[i];
      if (marker.isLocationEqual(lat, lng))
        return marker;
    }
    return null;
  },
  getIconByName: function(name) {
    for (var i = 0; i < this.icons.length; i++) {
      var icon = this.icons[i];
      if (icon.name == name) {
        return icon;
      }
    }
    return null;
  }
};

//custom control
function CustomControl(args) 
{ 
  this.args = args;
};
CustomControl.prototype = new GControl();
CustomControl.prototype.args = null;
CustomControl.prototype.position = null;

CustomControl.prototype.initialize = function(map)
{
  var container = document.createElement('div');
  container.className = this.args.className;
  container.id = this.args.id;
    
  var eventName = this.args.eventName;  
  var functionName = this.args.functionName;

  GEvent.addDomListener(container, eventName, function() 
  {
    var obj = window;
    // Ook als er geen . in de functionName zit, wordt de array gevuld.
    // In dat geval met de gehele string.
    var functionNameParts = functionName.split('.');
    for (var i = 0; i < functionNameParts.length; i++)    
      obj = obj[functionNameParts[i]];    
    obj(map, arguments);
  });
  
  var html = this.args.html;
  container.innerHTML = html.replace(/#dblq;/g, '"');
  
  map.getContainer().appendChild(container);
  return container;
}

CustomControl.prototype.getDefaultPosition = function() 
{
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 7));
}

function Icon() { };
Icon.prototype =
{  
  gIcon: null,
  src: null,
  width: null,
  height: null,
  name: null
}

function Marker()
{
  this.events = new Array();   
};
Marker.prototype =
{
  gmarker: null,
  posInArray: null,
  events: null,
  icon: null,
  query: null,
  lat: null,
  lng: null,
  draggable: null,
  addEvent: function(e, f, args)
  {
    this.events.push(new Array(e, f, args));
  },
  loadEvents: function()
  {
    for (var i = 0; i < this.events.length; i++)
    {
      var gmarker = this.gmarker;

      var eventName = this.events[i][0];
      var functionName = this.events[i][1];
      var functionArgs = this.events[i][2];

      this.addListener(gmarker, eventName, functionName, functionArgs);

    }
  },
  addListener: function(gmarker, eventName, functionName, functionArgs)
  {
    GEvent.addListener(gmarker, eventName, function()
    {
      var obj = window;
      // Ook als er geen . in de functionName zit, wordt de array gevuld.
      // In dat geval met de gehele string.
      var functionNameParts = functionName.split('.');

      for (var i = 0; i < functionNameParts.length; i++)
      {
        obj = obj[functionNameParts[i]];
      }
      obj(gmarker, functionArgs, arguments);
    });
  },
  isLocationEqual: function(lat, lng)
  {
    if (this.lng == lng && this.lat == lat)
    { return true; }
    else { return false; }
  }
}

Spif.DOMEvents.attach(window, "load", function(){Maps.init()});
Spif.DOMEvents.attach(window, "unload", function() { GUnload(); });
