//------------------------------------------
//------------------------------------------
//        OurActivities Map Class 
//------------------------------------------
var OACMap = function(container)
{
    var mapView = {type:null,zoom:null,lat:null,lng:null,coords:null};
    var mapContainer = container;
    var map = null;
    
    var geoMapImg = null;
    var currentMapCenter = null;
    var currentMapZoom = null;
    
    var markerArray = [];
    var currentMarker = null;
    var translate = 0.0;
    var initialOverlayBounds = null;
    var options = {
        initLat:    -34.9294304855664525, // sets the initial lattertude for the center of the map.
		initLng:    138.60162734985351, // sets the initial longitude for the center of the map.
		initZoom:   2, // sets the initial zoom level for the map.
		hasOverviewMap:   true,
		hasNavCtrl: true,
		hasMapTypeCtrl: true,
		 
		markerInfoEvent: 'click',
		centerOnMarker: false,
		iconBaseHref:"",
		mapImagesBaseHref: "",
		iconDefaultShadow: "shadow.png",
		iconHoverSuffix: "_over",
		iconActiveSuffix: "_active",
		iconActiveIndex: -1,
		
		geoMapFile: null,
		geoMapLat: null,
		geoMapLng: null,
		geoMapZoom: null,
		geoSearchStr: null
    };
    
    //------------------------------------------
    //            Public Functions 
    //------------------------------------------
    this.getOptions = function (){return options;};
    this.setOptions = function (newOptions)
    {
        if(newOptions) {
            $.extend(options, newOptions);
        }
    };
    
   /* 
    this.translateOverlayUp = function(amount)
    {
      if(options.geoMapFile != null && options.geoMapFile.length != 0)
       {
          translate += amount;
          map.removeOverlay(geoMapImg);
         //geoMapImg = new GGroundOverlay(options.geoMapFile, map.getBounds());
          var bounds = getOverlayBounds(map.getCenter());
          var swPoint = bounds.getSouthWest();
          var nePoint = bounds.getNorthEast();
          swPoint = new GLatLng(swPoint.lat() + translate,swPoint.lng());
          nePoint = new GLatLng(nePoint.lat() + translate,nePoint.lng());
          var newBounds = new GLatLngBounds(bounds.getSouthWest(),bounds.getNorthEast());
          geoMapImg = new GGroundOverlay(options.geoMapFile, getOverlayBounds(map.getCenter()));
          //geoMapImg.hide();
          map.addOverlay(geoMapImg);
       }
    }
    */
    
    this.translateOverlayLeftRight = function(amount)
    {
          var totalBounds = map.getBounds();
          var upAmount = (totalBounds.getNorthEast().lng() - totalBounds.getSouthWest().lng()) / 50;
          upAmount = upAmount * amount;
          var swPoint = initialOverlayBounds.getSouthWest();
          var nePoint = initialOverlayBounds.getNorthEast();
          swPoint = new GLatLng(swPoint.lat(),swPoint.lng() + upAmount);
          nePoint = new GLatLng(nePoint.lat(),nePoint.lng()+ upAmount);
          var newBounds = new GLatLngBounds(swPoint,nePoint);
          this.moveOverlay(newBounds);
    }
    
    this.translateOverlayUpDown = function(amount)
    {
          var totalBounds = map.getBounds();
          var upAmount = (totalBounds.getNorthEast().lat() - totalBounds.getSouthWest().lat()) / 50;
          upAmount = upAmount * amount;
          var swPoint = initialOverlayBounds.getSouthWest();
          var nePoint = initialOverlayBounds.getNorthEast();
          swPoint = new GLatLng(swPoint.lat() + upAmount,swPoint.lng());
          nePoint = new GLatLng(nePoint.lat() + upAmount,nePoint.lng());
          var newBounds = new GLatLngBounds(swPoint,nePoint);
          this.moveOverlay(newBounds);
    }
   
    this.centerOverlay = function()
    {
        this.moveOverlay(getOverlayBounds(map.getCenter()));
    }
    
    this.moveOverlay = function(newBounds)
    {
      if(options.geoMapFile != null && options.geoMapFile.length != 0)
       {
          initialOverlayBounds = newBounds;
          map.removeOverlay(geoMapImg);
          geoMapImg = new GGroundOverlay(options.geoMapFile, newBounds);
          map.addOverlay(geoMapImg);
       }
    }
    
    //Load the map from XML - uses current settings
    this.loadMap = function(boundsXML){
        if(mapContainer != null)
        {
            if(map == null)
            {
                map = new GMap2(mapContainer);
            }
            
            
            //use bounds from xml
            if(boundsXML != null && boundsXML.length != 0)
              bounds = GetBoundsFromXML(boundsXML);            
            else if(options.geoMapLat != null && options.geoMapLng != null)  //use old style bounds
            {
                map.setCenter(new GLatLng(options.geoMapLat, options.geoMapLng), options.geoMapZoom);
                map.setZoom(options.initZoom);
                bounds = getOverlayBounds(map.getCenter());
            }
            else    //default
            {
                map.setCenter(new GLatLng(options.initLat, options.initLng), options.initZoom);
                bounds = getOverlayBounds(map.getCenter());
            }
            
            if(options.geoMapFile != null && options.geoMapFile.length != 0) //load overlay if we have one
            {
                geoMapImg = new GGroundOverlay(options.geoMapFile, bounds);
                geoMapImg.hide();
                map.addOverlay(geoMapImg);
                map.addControl(new GeoMapControl());
            }
            
            //set the map view to center on whatever bounds we picked.    
            map.setCenter(bounds.getCenter(),map.getBoundsZoomLevel(bounds)); 
            initialOverlayBounds = bounds;
                        
            map.savePosition();
            map.removeMapType(G_HYBRID_MAP);
            if(options.hasMapTypeCtrl)
            {
                map.addControl(new GMapTypeControl());
                map.addMapType(G_PHYSICAL_MAP);

            }
            
            if(options.hasOverviewMap)
            {
                map.addControl(new GOverviewMapControl());
                
            }
            
            if(options.hasNavCtrl)
            {
                map.addControl(new GSmallMapControl());
                //map.addControl(new GScaleControl());
                map.enableScrollWheelZoom();
                map.enableContinuousZoom();
                map.enableDoubleClickZoom();
            }
            else
            {
                map.disableDragging();
                
            }
        }
    };
    
    function getOverlayBounds(center)
    {
        var polyW = 455;
        var polyH = 350;
        
        polyOffsetX = Math.floor(polyW / 2);
        polyOffsetY = Math.floor(polyH / 2);
    
        
        var pxlCenter = map.fromLatLngToContainerPixel(center);
       
        var newBounds = new GLatLngBounds(
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x - polyOffsetX, pxlCenter.y + polyOffsetY)),
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x + polyOffsetX, pxlCenter.y - polyOffsetY))
        );
        
        /*polygon = new GPolygon([
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x - polyOffsetX, pxlCenter.y - polyOffsetY)),
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x + polyOffsetX, pxlCenter.y - polyOffsetY)),
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x + polyOffsetX, pxlCenter.y + polyOffsetY)),
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x - polyOffsetX, pxlCenter.y + polyOffsetY)),
            map.fromContainerPixelToLatLng(new GPoint(pxlCenter.x - polyOffsetX, pxlCenter.y - polyOffsetY))
            ], "#000000", 1, 1);*/
        
        return newBounds;
    } 
            
    // Loads placemarks from XML Doc - uses current settings
    this.loadPlacemarks = function(xmlDoc)
    {
        if(xmlDoc)
        {
            var mapBounds = map.getBounds();
            var hasVisibleMarker = false;
            var markerNodes = xmlDoc.getElementsByTagName("Placemark");
         
            var newMarker;
            for(var i=0; i<markerNodes.length; i++)
            {
                newMarker = GetMarkerData(markerNodes[i]);
                if(newMarker)
                {
                    map.addOverlay(newMarker);
                    
                    if(mapBounds.containsLatLng(newMarker.getLatLng()))
                    {
                        hasVisibleMarker = true;
                    }
                }
            }
            
            //If no markers are in viewing range then center map on first marker
            if(markerArray.length != 0 && (options.centerOnMarker || !hasVisibleMarker))
            {
                map.panTo(markerArray[0].getLatLng());
            }
        }
    };
    
    this.clearMap = function()
    {
        map.clearOverlays();
        markerArray = [];
    }
    
    this.geoSearch = function(srchStr)
    {
        var geocoder = new GClientGeocoder();
        geocoder.getLatLng(
          srchStr,
          function(point) {
            if (point) {
              map.setCenter(point, 4);
            }
          }
        );
    }
    
    //------------------------------------------
    //            Private Functions 
    //------------------------------------------
    //  Creates a marker from XML
    //------------------------------------------
    function GetMarkerData(xmlNode)
    {
        //get placemarkers
        var lng = 0;
        var lat = 0;
        var title = "";
        var name = "";
        var descNode = null;
        var description = "";
        var iconURL = "";
        var link = "";
        
        title = getChildNodeValue(xmlNode, "title", "");
        name = getChildNodeValue(xmlNode, "name", "");
        link = getChildNodeValue(xmlNode, "link", "");
        description = "";
        descNode = xmlNode.getElementsByTagName("description");
        lng = $.trim(getChildNodeValue(xmlNode, "Longitude", "0"));
        lat = $.trim(getChildNodeValue(xmlNode, "Latitude", "0"));
        iconURL = getSingleNodeValue(xmlNode, "Icon/href", "");
        
        if(descNode && descNode.length != 0)
        {
		    description = serializeNode(descNode[0]);
		    description = description.replace("<description>", "");
			description = description.replace("</description>", "");
			description = description.replace("<description/>", "");
        }

        if(name.length != 0 && name.toLowerCase() != title.toLowerCase())
        {
            description = "<p>"+name+"</p>" + description
        }
        
        if(lat != 0 && lng != 0)
        {
            var index = markerArray.length;
            
            if(options.iconActiveIndex == index && options.iconActiveSuffix != null && options.iconActiveSuffix.length != 0)
            {
                iconURL = iconURL.replace(".", options.iconActiveSuffix+".");
            }
            
            var newMarker = CreateMarker(new GLatLng(lat, lng), index, title, description, link, CreateIcon(iconURL));
            markerArray.push(newMarker);
            
            return newMarker;
        }
        
        return null;
        
    };
    
    //------------------------------------------
    //  Creates a GMarker object
    //------------------------------------------
    function CreateMarker(latlng, idx, title, info, link, newIcon)
    {
        var marker = new GMarker(latlng, {icon: newIcon});
        marker.Index = idx;
        marker.Title = title;
       
        GEvent.addListener(marker, "mouseover", function() {
       
          if (typeof SlimHtmlInfoWindow !== 'undefined') {
            if (!this.overlay) {
              // just recording this for use in the closeOverlay function
              this.overlay = new SlimHtmlInfoWindow(this, info);
            }
            currentMarker = this;
            map.addOverlay(this.overlay);
          } else {
            marker.openInfoWindowHtml(title);
          }
          
          if(options.iconHoverSuffix && options.iconHoverSuffix.length != 0)
          {
            var hoverImg = newIcon.image.replace(".", options.iconHoverSuffix+".");
            marker.setImage(hoverImg);
          }
          
        });
        
        GEvent.addListener(marker, "mouseout", function() {
            if (typeof SlimHtmlInfoWindow !== 'undefined' && marker.overlay) {
                map.removeOverlay(marker.overlay);
            }
            
            if(options.iconHoverSuffix && options.iconHoverSuffix.length != 0)
            {
                marker.setImage(marker.getIcon().image);
            }
        });
        
        if(link && link.length != 0)
        {
            GEvent.addListener(marker, "click", function() {
                location.href = link;
            });
        }
        
        return marker;
    };
    
    //-------------------------------------------------------
    //    Closes the info overlay for the current marker
    //-------------------------------------------------------
    function closeOverlay() {
      if (currentMarker) {
        map.removeOverlay(currentMarker.overlay);
        currentMarker.show();
      }
    }
    
    //-------------------------------------------------------
    //    Creates a GIcon with the specified image
    //-------------------------------------------------------
    function CreateIcon(iconURL)
    {
        var icon = new GIcon();
        icon.image = options.iconBaseHref+iconURL;
        icon.shadow = options.iconBaseHref+options.iconDefaultShadow;
        icon.iconSize = new GSize(20.0, 34.0);
        icon.shadowSize = new GSize(38.0, 34.0);
        icon.iconAnchor = new GPoint(10, 34.0);
        icon.infoWindowAnchor = new GPoint(10.0, 0);

        return icon;
    };
    
    //---------------------------------------------------------------
	//    Helper functions
	//---------------------------------------------------------------
    // Returns the value of the first node match for the given xPath.
    // If no value is found the default value is returned.
    //---------------------------------------------------------------
    function getSingleNodeValue(parentNode, xPath, defaultValue)
    {
        var nodes;
        var xPathArray = xPath.split('/');
        var val = defaultValue;
        
        if(xPathArray.length > 1)
        {
            nodes = parentNode.getElementsByTagName(xPathArray[0]);
            
            if(nodes.length != 0)
            {
                val = getSingleNodeValue(nodes[0], xPathArray.slice(1).join('/'), defaultValue);   
            }
        }
        else
        {   
            val = getChildNodeValue(parentNode, xPath, defaultValue);
        }
     
        return val;
    };
    
    //-------------------------------------------------------
    //    Returns the value of the child node.
    //    If no value is found the default value is returned.
    //-------------------------------------------------------
    function getChildNodeValue(parentNode, nodeName, defaultValue)
    {
        var nodes = parentNode.getElementsByTagName(nodeName);
        if(nodes.length != 0)
        {
            return GXml.value(nodes[0]);
        }
        
        return defaultValue;
    };

    //-------------------------------------------------------
    //    Escapes xml special chars.
    //-------------------------------------------------------
    function XmlFormat(str)
    {
		var result = str;
		
		result = result.replace(/&/g, "&amp;");
		result = result.replace(/</g, "&lt;");
		result = result.replace(/>/g, "&gt;");
		result = result.replace(/'/g, "&apos;");
		result = result.replace(/"/g, "&quot;");
		
		return result;
    };
    
    //-------------------------------------------------------
    //    Returns the node XML as a string
    //-------------------------------------------------------
    function serializeNode (node) {
		if (typeof XMLSerializer != 'undefined') {
			return new XMLSerializer().serializeToString(node);
		}
		else if (typeof node.xml != 'undefined') {
			return node.xml;
		}
		else if (typeof printNode != 'undefined') {
			return printNode(node);
		}
		else {
			// might want to handle problem here
			return 'undefined';
		}
	};
	
	/*------------------------------------------
        Google Map Extensions
    ------------------------------------------*/
    //Slim HTML Info Window
    function SlimHtmlInfoWindow(marker, html)
    {
        this.marker = marker;
        this.html = html;

    }

    SlimHtmlInfoWindow.prototype = new GOverlay();
    SlimHtmlInfoWindow.prototype.initialize = function(map)
    {        
        var div = $("<div class='mapInfoWindow'><div class='body'>"+this.html+"</div></div>");
        div.hide();
        $(map.getPane(G_MAP_FLOAT_PANE)).append(div);
        
        // offsets based on popup div dimensions
        var w = div.width();
        var h = div.height()
        var offsetX = 0;
        var offsetY = 75;
        var winPosX = map.fromLatLngToDivPixel(this.marker.getPoint()).x + offsetX;
        var winPosY = map.fromLatLngToDivPixel(this.marker.getPoint()).y - offsetY;
        
        //set positioning
        var winW = map.fromLatLngToContainerPixel(map.getBounds().getNorthEast()).x;
        var winH = map.fromLatLngToContainerPixel(map.getBounds().getSouthWest()).y;
        var winRX = map.fromLatLngToContainerPixel(this.marker.getLatLng()).x + offsetX + w;
        var winRY = map.fromLatLngToContainerPixel(this.marker.getLatLng()).y - (offsetY + h);
        
        var winBGX = "left";
        var winBGY = "bottom";
        
        if(winRX > winW)
        {
            winPosX = map.fromLatLngToDivPixel(this.marker.getPoint()).x - (offsetX + w);
            winBGX = "right";
        }
        
        if(winRY < 0)
        {
            winPosY = map.fromLatLngToDivPixel(this.marker.getPoint()).y;
            winBGY = "top";
        }
        
        div.addClass("mapInfoWindow-"+winBGX+winBGY);
        
        div.attr("style", "position:absolute;top:" + winPosY + "px;left: " + winPosX + "px;");
        this._map = map;
        this._div = div;
     
        div.show();
    }

    SlimHtmlInfoWindow.prototype.remove = function(){
     
        this._div.remove();
    }

    SlimHtmlInfoWindow.prototype.copy = function()
    {
        return new SlimHtmlInfoWindow(this.marker, this.html);

    }

    SlimHtmlInfoWindow.prototype.redraw = function(force) {
        if (!force) return;

    }

    function GetBoundsFromXML(xml)
    {
       var doc = GXml.parse(xml);
       var points = doc.getElementsByTagName("Point");
       
       var lat = getChildNodeValue(points[0],"lat","");
       var lng = getChildNodeValue(points[0],"long","");
       var nePoint = new GLatLng(lat,lng);
       
       lat = getChildNodeValue(points[1],"lat","");
       lng = getChildNodeValue(points[1],"long","");
       swPoint = new GLatLng(lat,lng);
       
       var bounds = new GLatLngBounds(swPoint,nePoint);
       return bounds;
    }
    
    //Geo Map Control
    function GeoMapControl(){}

    GeoMapControl.prototype = new GControl();
    GeoMapControl.prototype.initialize = function(map)
    {        
        var elem = $("<div class='geo-map'><label><input type='checkbox' name='showgeomap' value='1'/>Santos Acreage</label></div>");
        
        GEvent.addDomListener(elem.find("input").get(0), "click", function() {
            if(geoMapImg != null)
            {
                if(this.checked && geoMapImg.isHidden())
                {
                    currentMapCenter = map.getCenter();
                    currentMapZoom = map.getZoom();
                 
                    map.setCenter(bounds.getCenter(),map.getBoundsZoomLevel(bounds)); 
                   
                    geoMapImg.show();
                    
                }
                else if(!this.checked && !geoMapImg.isHidden())
                {
                    geoMapImg.hide();
                    if(currentMapCenter != null)
                    {
                        map.setCenter(currentMapCenter, currentMapZoom);
                    }
                }
            }
        });
        
        map.getContainer().appendChild(elem.get(0));

        return elem.get(0);
    }

    GeoMapControl.prototype.getDefaultPosition = function() {
      return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(220, 7));
    }
    
};

var globalMap = null;
//-------------------------------------------------------
//    ourActivityMap utils
//-------------------------------------------------------
(function($) {
    
    $.fn.ourActivityMap = function(options, mapXML,boundsXML){
        return this.each(function(){
            
            if (GBrowserIsCompatible()) {
                //set unload function
                $("body").unload = GUnload;
                
                var oacMap = new OACMap(this);
                oacMap.setOptions(options);
                oacMap.loadMap(boundsXML);
                globalMap = oacMap;
                if(mapXML && mapXML.length != 0)
                {
                    var doc = GXml.parse(mapXML);
                    oacMap.loadPlacemarks(doc);
                }
                else if(options.geoSearchStr && options.geoSearchStr.length != 0)
                {
                    oacMap.geoSearch(options.geoSearchStr);
                }
                
                $(this).data("oacMap", oacMap);
            }
        });
    }  
    
    $.ourActivityGetMap = function(id, options){
        var elemId = id;
        var obj = null;
        
        if(elemId.indexOf('#') == -1)
        {
            elemId = "#" + elemId;
        }
        
        obj = $(elemId).data("oacMap");
        
        if(options) {
            $.extend(obj.options, options);
            $(elemId).data("oacMap", obj);    
        }
            
        return obj;
    }
})(jQuery);