/**
 * IE Workaround for getElementById function
 */   
  if (/msie/i.test (navigator.userAgent)) 
  {
    document.nativeGetElementById = document.getElementById; 
    document.getElementById = function(id)
    {
      var elem = document.nativeGetElementById(id);
      if(elem)
      {
        if(elem.attributes['id'].value == id)
        {
          return elem;
        }
        else
        {
          for(var i=1;i<document.all[id].length;i++)
          {
            if(document.all[id][i].attributes['id'].value == id)
            {
              return document.all[id][i];
            }
          }
        }
      }
      return null;
    }
  }

    
/**
 *  Main declarations
 */   

  //<![CDATA[
  var CONST_DRAWLINE_MODE = 1;
  var CONST_DRAWROUTE_MODE = 2;
  var CONST_DRAWPOINT_MODE = 3;
  
  var markers = [];
  var drawingMode;
  var markerCluster;
  var map;
  var gdir;
  var route;
  var loaded = false;
  var mapClickListener;
  var tooltip;
  var layers = [];     
  var layerControl; 

  
    
      function MoreControl() {}
      MoreControl.prototype = new GControl();
      
      MoreControl.prototype.initialize = function(map) {
        var container = document.createElement("div");
        container.id = "menumtctlmore";
        container.innerHTML = "More...";
      
        map.getContainer().appendChild(container);
        
        GEvent.addDomListener(container, "mouseover", function() {
          map.addControl(layerControl);
        });
        return container;
      }
      
      MoreControl.prototype.getDefaultPosition = function() {
        return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(91, 7));
      }
      
      function LayerControl(opts) {
        this.opts = opts;
      }
      LayerControl.prototype = new GControl();
      
      LayerControl.prototype.initialize = function(map) {
        var container = document.createElement("div");
        container.id = "menumtctlmore";
        container.innerHTML = "More...<br\/>";
        for (var i=0; i<this.opts.length; i++) {
          if (layers[i].Visible) {
            var c = 'checked';
          } else {
            var c = '';
          }
          container.innerHTML += '<input type="checkbox" onclick="toggleLayer('+i+')" ' +c+ ' /> '+this.opts[i]+'<br>';
        }
      
        map.getContainer().appendChild(container);
        
        setTimeout("map.removeControl(layerControl)",5000);
        
        return container;
      }
      
      LayerControl.prototype.getDefaultPosition = function() {
        return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(91, 7));
      }
      
      function toggleLayer(i) {
        if (layers[i].Visible) {
          layers[i].hide();
        } else {
          if(layers[i].Added) {
            layers[i].show();
          } else {
            map.addOverlay(layers[i]);
            layers[i].Added = true;
          }
        }
        layers[i].Visible = !layers[i].Visible;
      }
      
      
/**
 *  Gmap load function
 */   
  function load(user_id,mytrip_id) {
    if (!loaded && (typeof(user_id) == 'number')) {} else return; 
    if (GBrowserIsCompatible()) {
  
      map = new GMap2(document.getElementById("map"));
      var customUI = map.getDefaultUI();
      customUI.maptypes.physical = true;
      customUI.controls.maptypecontrol = false;
      customUI.controls.scalecontrol = false;
      customUI.controls.menumaptypecontrol = true;
      map.setUI(customUI);
      map.setMapType(G_PHYSICAL_MAP);
      map.disableScrollWheelZoom();
      
      map.addControl(new google.maps.LocalSearch(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,20)));
      
      // ====== set up marker mouseover tooltip div ======
      tooltip = document.createElement("div");
      map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
      tooltip.style.visibility="hidden";

      layers[0] = new GLayer("org.wikipedia.en");
      layers[0].Visible = false;
      layers[0].Added = false;
      
      layers[1] = new GLayer("com.panoramio.all");
      layers[1].Visible = false;
      layers[1].Added = false;

      layers[2] = new GLayer("com.panoramio.popular");
      layers[2].Visible = true;
      layers[2].Added = true;
      
      layerControl = new LayerControl(["Wikipedia", "Photos", "Popular"]);
      map.addControl(new MoreControl());
      

      route = new Route();
      clusterMarkers(user_id, mytrip_id);
      
      loaded = true;
    }
  }
    
  function clearMap ()
  {
//    if (markerCluster) markerCluster.clearMarkers();
    //map.clearOverlays();
    //markers.splice(0,markers.length);
    route.clear();
    if (document.getElementById("activeRouteID")) document.getElementById("activeRouteID").value = 0;
  }
    
  function clusterMarkers (user_id, mytrip_id)
  {
    var theIcon = new GIcon();
    theIcon.shadow = "/map/images/shadow_m.png";
    theIcon.iconSize = new GSize(24.0, 41.0);
    theIcon.shadowSize = new GSize(45.0, 41.0);
    theIcon.iconAnchor = new GPoint(11.0, 34.0);
    theIcon.infoWindowAnchor = new GPoint(24.0, 0.0);
          

    var bounds = map.getBounds();
    var sw = bounds.getSouthWest();
    var ne = bounds.getNorthEast();
          
    var currentTimestamp = new Date(); 
    var url = "map/loadRouteStart.php?time=" + currentTimestamp.getTime();
    if (user_id != 0) url += "&user_id=" + user_id;
    if (mytrip_id != 0) url += "&mytrip_id=" + mytrip_id;
    GDownloadUrl(url, function(arrMarkers) {
      if (arrMarkers.length > 0)
      {
        var bounds = new GLatLngBounds();
        markers.splice(0,markers.length);
        var mySplit = arrMarkers.split('|');
        for (var i = 0; i < mySplit.length-1; ++i) 
        {
          var markerData = mySplit[i].split('^');
          theIcon.image = "map/images/triptype"+markerData[8]+".png";
          
          var thePoint = new GLatLng(markerData[0],markerData[1]);
          var theMarker = new GMarker(thePoint, {icon: theIcon, draggable:false});
          bounds.extend(thePoint);

          var img = '<img width="13" height="11" src="img/icons/';
          if (markerData[4] == 1) img += "zalias_t";
          if (markerData[4] == 2) img += "blue_t";
          if (markerData[4] == 3) img += "red_t";
          img += '.png" />';
          
          theMarker.tooltip = '<div id="mtooltip"><h1>'+markerData[3]+'</h1><p>'+markerData[6]+' km.&nbsp;'+img+'&nbsp;|&nbsp;<span class="author">'+markerData[7]+'</span></p>';
          theMarker.id = markerData[2];
          GEvent.addListener(theMarker, "click", function(latlng) { 
            myMarkerClick(latlng);
          });
          GEvent.addListener(theMarker, "mouseover", function(latlng) { 
            myMarkerOver(latlng);
          });
          GEvent.addListener(theMarker, "mouseout", function(latlng) { 
            myMarkerOut ();
          });

          markers.push(theMarker);
        }
        markerCluster = new MarkerClusterer(map, markers, {maxZoom:10});
        map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
      }
      else
        map.setCenter(new GLatLng(54.895564790773385,23.873291015625),7);
    });
  }
  
  function getMarkerId (latlng)
  {
    for (var i = 0; i < markers.length; i++)
      if (latlng.equals(markers[i].getLatLng())==true)
        return i; 
    return 0;
  }
  
  function myMarkerClick (latlng)
  {
    tooltip.style.visibility = "hidden";
    window.location = "http://"+window.location.hostname +"/trip.asp?trip=" + markers[getMarkerId(latlng)].id;
  }  
  
  function myMarkerOver (latlng)
  {
    var id = getMarkerId(latlng);
    showTooltip(id);
    loadRoute(markers[id].id);
  }  
  
  function myMarkerOut ()
  {
    tooltip.style.visibility = "hidden";
    setTimeout('clearMap ()', 200);
  }  
    
  function showTooltip(id)
  {
    tooltip.innerHTML = markers[id].tooltip;
    var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
    var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(markers[id].getPoint(),map.getZoom());
    var anchor=markers[id].getIcon().iconAnchor;
    var width=markers[id].getIcon().iconSize.width;
    var height=tooltip.clientHeight;
    var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
    pos.apply(tooltip);
    tooltip.style.visibility="visible";
  }


    /**
     *  Loads route from DB
     */         
    function loadRoute(id)
    {
      if (document.getElementById("activeRouteID").value == id) return;
      var currentTimestamp = new Date();
      GDownloadUrl("map/loadRoute.php?id="+id + "&time=" + currentTimestamp.getTime(), function(data, responseCode) {
        if(responseCode == 200) {
          route.clear();
          if (data == '') return;
          // split to routes info and points info
          var myData = data.split('#', 2);
          //parse routes
          var myRoutes = myData[0].split('@');
          for (var i=0; i<myRoutes.length; i++) {
            var myRoute = myRoutes[i].split('$', 3);
            drawingMode = myRoute[0];
            route.setTripType(myRoute[2]);
            if (myRoute[1] != ''){
              var myPoints = myRoute[1].split('|');
              for (var j=0; j<myPoints.length; j++) {
                var myPointsLatLng = myPoints[j].split(';', 2);
                var thePoint = new GLatLng(parseFloat(myPointsLatLng[0]), parseFloat(myPointsLatLng[1]));
                route.addPoint(thePoint);
              }
            }
            route.draw();
          }
          
          /*if (myData[1] != undefined)
          {
            var myPoints = myData[1].split('@');
            for (var i=0; i<myPoints.length; i++) {
              var myMarker = myPoints[i].split('$', 3);
              markers.push (createMarker(new GLatLng(myMarker[1], myMarker[2])));
              markers[i].tooltip = myMarker[0];
              map.addOverlay(markers[i]);
            }
          }*/
        }
      });
    }
    
   
    
/**
 *
 * Class RouteRange for one range of the route. Possible range types: 1 - line, 2 - direction
 *  
 */
 
  function RouteRange(type, no, trip) {
    this.type = type;
    this.trip = trip;
    this.points = [];
    this.markers = [];
    this.gd;
    this.no = no;
    this.poly;
    this.distance;
    
    if (this.type == CONST_DRAWROUTE_MODE) {
      this.gd = new GDirections(map);
      GEvent.addListener(this.gd, "addoverlay", function (){
        route.redrawOverlay(this.no);
      });
    }
    
    this.createMarker = function (latlng, type) {
      var theIcon = new GIcon();
      if (type == 0)
      {
        theIcon.image = "map/images/triptype"+this.trip+".png";
        theIcon.shadow = "map/images/shadow_m.png";
        theIcon.iconSize = new GSize(24.0, 41.0);
        theIcon.shadowSize = new GSize(45.0, 41.0);
        theIcon.iconAnchor = new GPoint(12.0, 41.0);
        theIcon.infoWindowAnchor = new GPoint(12.0, 20.0);
      }
      else if (type == 2)
      {
        theIcon.image = "map/images/finish_t.png";
        theIcon.shadow = "map/images/shadow_start.png";
        theIcon.iconSize = new GSize(24.0, 26.0);
        theIcon.shadowSize = new GSize(38.0, 26.0);
        theIcon.iconAnchor = new GPoint(2.0, 26.0);
        theIcon.infoWindowAnchor = new GPoint(2.0, 13.0);
      }
      else
      {
        theIcon.image = "map/images/map_point.gif";
        theIcon.iconSize = new GSize(10.0, 10.0);
        theIcon.iconAnchor = new GPoint(5.0, 5.0);
        theIcon.infoWindowAnchor = new GPoint(5.0, 5.0);
      }
      
      var thisMarker;
      if (type == 1 || type == 0)
        thisMarker = new GMarker(latlng, {hide:true, icon: theIcon, draggable: false});
      else
        thisMarker = new GMarker(latlng, {hide:false, icon: theIcon, draggable: false});
        
      return thisMarker;
    }
    
    this.addPoint = function(point) {
      this.points.push(point);
      if (this.no > 0 && this.points.length == 1) return;
      
      var theMarker = this.createMarker(point, (this.no == 0 && this.points.length == 1) ? 0 : 2);
      this.markers.push(theMarker);
      map.addOverlay(theMarker);

      if (this.no > 0 && this.points.length == 2)// && route.ranges[route.getRangesCount()-2].markers.length != 1)
      {
        var place = route.ranges[route.getRangesCount()-2].markers.length-1;
        var tempMarker = this.createMarker(route.ranges[route.getRangesCount()-2].markers[place].getLatLng(),1);
        map.removeOverlay(route.ranges[route.getRangesCount()-2].markers[place]);
        route.ranges[route.getRangesCount()-2].markers[place] = tempMarker;
        map.addOverlay(tempMarker);
      }
      if (this.points.length > 2)
      {
        var place = this.markers.length - 2;
        var tempMarker = this.createMarker(this.markers[place].getLatLng(),1);
        map.removeOverlay(this.markers[place]);
        this.markers[place] = tempMarker;
        map.addOverlay(tempMarker);
      }
    }
    
    this.getType = function() {
      return this.type
    }
    
    this.clear = function() {
      this.points.splice(0,this.points.length);
      for (var i = 0; i < this.markers.length; i++)
        map.removeOverlay(this.markers[i])
      this.markers.splice(0,this.markers.length);
      if (this.gd) this.gd.clear();
      else map.removeOverlay(this.poly);
    }
    
    this.toString = function() {
      var tempString = '';
      for (var i = 0; i < this.points.length; i++)
        tempString += ((i != 0) ? "|" : "") + this.points[i].lat() + ";" + this.points[i].lng();  
      return tempString;
    }
    
    this.remark = function() {
      this.points.splice(0,this.points.length);
      for (var i = 0; i < this.markers.length; i++)
      {
        if (this.no > 0 && i == 0)
          this.points.push (route.ranges[this.no-1].points[route.ranges[this.no-1].points.length-1]);
        this.points.push(this.markers[i].getLatLng());
      }
      this.draw();
    }
    
    this.draw = function() {
      if (this.points.length > 1) 
        if (this.type == CONST_DRAWLINE_MODE) {
          if (this.poly) map.removeOverlay(this.poly);
          var color = (this.trip==1) ? "#0000ff" : "#ff0000"
          this.poly = new GPolyline(this.points, color, 5, 0.4, {geodesic:true});
          map.addOverlay(this.poly);
        }
        else if (this.type == CONST_DRAWROUTE_MODE)
        {
          this.gd.loadFromWaypoints(this.points, {preserveViewport:true});
        }
    }
    
    this.redrawOverlay = function() {
      if (this.type == CONST_DRAWROUTE_MODE) 
      {
        if (this.gd.getStatus().code != 200) return;
        for (var i = 0; i <= this.gd.getNumRoutes(); i++)
        {
          var originalMarker = this.gd.getMarker(i);
          if (originalMarker != null)
            map.removeOverlay(originalMarker);
        }
      }
      else
        this.draw()
    }
    
    this.getDistance = function() {
      if (this.points.length > 1) 
      {
        if (this.type == CONST_DRAWLINE_MODE) {
          var distance = 0;
          for (var i = 0; i < this.points.length-1; i++)
            distance += this.points[i].distanceFrom(this.points[i+1]) / 1000;
          return distance;
        }
        else if (this.type == CONST_DRAWROUTE_MODE)
            return (this.gd) ? (this.gd.getDistance().meters / 1000) : 0;
      }
      return 0;
    }


  }


/**
 *
 * Class Route for one route. Route may be created
 *   
 */
 
  function Route() {
    this.ranges = [];
    this.trip;
    
    this.addRange = function(range) {
      this.ranges.push(range);
    }
    
    this.setTripType = function(trip) {
      this.trip = trip;
      this.remark();
    }
    
    this.addPoint = function(point) {
      if (this.getRangesCount() == 0 || (this.getRangesCount()>0 && this.ranges[this.getRangesCount() - 1].getType() != drawingMode)) {
        this.addRange(new RouteRange(drawingMode, this.getRangesCount(),this.trip));
        if (this.getRangesCount() > 1)
          this.ranges[this.getRangesCount() - 1].addPoint(this.ranges[this.getRangesCount() - 2].points[this.ranges[this.getRangesCount() - 2].points.length-1])
      }    
      var lastRange = this.getRangesCount() - 1;
      var lastPoint = this.ranges[lastRange].points[this.ranges[lastRange].points.length-1];
      if (lastPoint == null)   
        this.ranges[lastRange].addPoint(point);
      else if (lastPoint.lat() != point.lat() && lastPoint.lng() != point.lng())
        this.ranges[lastRange].addPoint(point);
    }
    
    this.getRangesCount = function() {
      return this.ranges.length
    }
    
    this.clear = function() {
      for (var i = 0; i < this.ranges.length; i++) {
        this.ranges[i].clear()
      }
      this.ranges.splice(0,this.ranges.length);
    }
    
    this.remark = function() {
      for (var i = 0; i < this.ranges.length; i++)
        this.ranges[i].remark()
    }
    
    this.draw = function() {
      var i = (this.ranges.length > 0) ? this.ranges.length-1 : 0;  
      this.ranges[i].draw()
    }
    
    this.drawAll = function() {
      for (var i = 0; i < this.ranges.length; i++)
        this.ranges[i].draw()
    }
    
    this.redrawOverlay = function(no) {
      for (var i = 0; i < this.ranges.length; i++)
        this.ranges[i].redrawOverlay()
    }
    
    this.getDistance = function() {
      var distance = 0;
      for (var i = 0; i < this.ranges.length; i++)
        distance += this.ranges[i].getDistance();
      return Math.round(distance);
    }
     
  }
  
  //]]>
  GSearch.setOnLoadCallback(load);
