var markermanager=function(){
    var haversine=function(lat1, lon1, lat2, lon2){
        if (typeof(Number.prototype.toRad) === "undefined") {
          Number.prototype.toRad = function() {
            return this * Math.PI / 180;
          }
        }
    
        var R = 6371; // km
        var dLat = (lat2-lat1).toRad();
        var dLon = (lon2-lon1).toRad();
        var lat1 = lat1.toRad();
        var lat2 = lat2.toRad();
        
        var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
        var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
        var d = R * c;
        
        return d;
    }
    return {
        markers: [],
        find_nearest_location: function(lat, lon){
            var min_distance=Infinity;
            var current_marker=null;
            $.each(this.markers, function(i, m){
                d=haversine(lat, lon, m.position.lat(), m.position.lng());
                if(d<min_distance){
                    min_distance=d;
                    current_marker=m;
                }
            });
            return current_marker;
        },
        find_nearest_user: function(map, zoom, click, no_geo_zoom){
          var mm=this;
          if(!zoom){
            zoom=10;
          }
          
          if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
              marker=mm.find_nearest_location(position.coords.latitude, position.coords.longitude);
              map.setCenter(marker.getPosition());
              if(click){
                google.maps.event.trigger(marker, 'click');
              }
              map.setZoom(zoom);
            });
          } else if (google.gears) {
            var geo = google.gears.factory.create('beta.geolocation');
            geo.getCurrentPosition(function(position) {
              marker=mm.find_nearest_location(position.latitude, position.longitude);
              map.setCenter(marker.getPosition());
              if(click){
                google.maps.event.trigger(marker, 'click');
              }
              map.setZoom(zoom);
            });
          } else{
            map.setCenter(new google.maps.LatLng(0.0,10.0));
            if(no_geo_zoom){
                map.setZoom(no_geo_zoom);
            }else{
                map.setZoom(zoom);
            }

          }
        },
        delete_markers: function(){
            $.each(this.markers, function(i, m){
                m.setMap(null);
            });
            this.markers=[];
        },
        close_windows: function(){
            $.each(this.markers, function(i, m){
                m.infoWindow.close();
            });
        },
        add_marker: function(m){this.markers.push(m);}
    };
};

var map_handler=function(opt){
    var map=new google.maps.Map(document.getElementById(opt.target),{
      mapTypeId: google.maps.MapTypeId.HYBRID});
      
    var mm=markermanager();  
    var placemark_handler=function(p){
        m=geoxml3.createMarker(p);
        mm.add_marker(m);
    };
      
    geoxml3=new geoXML3.parser({map: map,
        createMarker: placemark_handler,
        afterParse: opt.afterParse});
    
    var obj={
        map: map,
        mm: mm,
        geoxml3: this.geoxml3,
        getMarkerManager: function(){
            return this.mm;
        },
        getMap: function(){
            return map;
        },
        load_markers: function(url, callback){
            this.mm.delete_markers();
            this.geoxml3.options.afterParse=callback;
            geoxml3.parse(url);
        },
        find_nearest_user: function(zoom, click, no_geo_zoom){
            this.mm.close_windows();
            this.mm.find_nearest_user(this.map, zoom, click, no_geo_zoom);
        },
        load_and_zoom: function(url, zoom){
            this.load_markers(url, function(){
                this.zoom(zoom);
            });
        },
        zoom: function(zoom){
            this.map.setZoom(zoom);
        },
        load_and_go_nearest: function(url, zoom, click){
            var mh=this;
            this.load_markers(url, function(){
                this.go_nearest(zoom, click);
            });
        },
        go_nearest: function(zoom, click, no_geo_zoom){
            this.mm.close_windows();
            this.find_nearest_user(zoom, click, no_geo_zoom);
        },
        load_and_go_location: function(url, lat, lng){
            var mh=this;
            this.load_markers(url, function(){
                mh.go_location(lat,lng);
            });
        },
        go_location: function(lat, lng){
            var mh=this;
            this.mm.close_windows();
            map.setZoom(18);
            $.each(this.mm.markers, function(i, m){
                if(m.position.lat().toFixed(10)==lat.toFixed(10) && m.position.lng().toFixed(10)==lng.toFixed(10)){
                    google.maps.event.trigger(m, 'click');
                } 
            });
        }
    };
    
    if(opt.kml_url){
        obj.load_markers(opt.kml_url);    
    }
    
    return obj;
};

var contact_map_initialize=function(){
    if($('#map_canvas').length>0){
        var map=map_handler({target: 'map_canvas', kml_url: $('#map_canvas').attr('rel')});
    
        var opener=$('#map_opener').fancybox({hideContentOnClick: true})
        $('.show_map').click(function(e){
            opener.click();
            //map.load_and_go_nearest($(e.target).attr('href'));
            //map.load_and_zoom($(e.target).attr('href'), 1);
            //map.load_and_go_nearest($(e.target).attr('href'), 2, false);
            google.maps.event.trigger(map.map, 'resize');
            map.go_nearest(2,false);

            return false;
        });
        
        $('.find_nearest').click(function(e){
            opener.click();
            google.maps.event.trigger(map.map, 'resize');
            map.go_nearest(8, false, 2);

            return false;
        });
        
        $('.find_marker').click(function(e){
            opener.click();
            var data=$.parseJSON($(e.target).attr('href'));
            //map.load_and_go_location(data[0], data[2], data[1]);
            google.maps.event.trigger(map.map, 'resize');
            map.go_location(data[2], data[1]);
            return false;
        })
    }
}


