﻿google.load('maps', '2.x');

var GoogleMap = new function() {

    /* 
    Contents 
				
    1. Map General
    1.1 Properties
    1.2 Setup
			
    2. Icons
    2.1 Add Icon
    2.2 Clear Icons
			
    3. Markers
    3.1 Add Marker
    3.2 Get Marker By MarkerID
			
    4. Builder
    4.1 Build
	
	
    5. Support
    5.1 CentreAndZoom
    5.2 PostZoomProcessing
    5.3 CloseAllPopups
			
    */




    /* 1 Map General */

    //1.1 Properties
    var me = this;
    this.Map;
    this.Markers = new Array();
    this.Icons = new Array();

    this.ManualZoom = false;


    //1.2 Setup
    this.Setup = function(oMap, nLat, nLong, oZoomEndDelegate, oDragEndDelegate) {

        oMap = f.SafeObject(oMap);
        me.Map = new google.maps.Map2(oMap);

        if (nLat != undefined) {
            me.Map.setCenter(new google.maps.LatLng(nLat, nLong), 13);
        } else {
            me.Map.setCenter(new google.maps.LatLng(0, 0), 1);
        }
        me.Map.setUIToDefault();

        // if there is a zoom end delegate then tie up the event to a listener
        if (oZoomEndDelegate != undefined) {
            GEvent.addListener(me.Map, "zoomend", oZoomEndDelegate);
        }

        // if there is a drag end delegate then tie up the event to a listener
        if (oDragEndDelegate != undefined) {
            GEvent.addListener(me.Map, "dragend", oDragEndDelegate);
        }

    }


    //1.3 Bounds
    this.Bounds = function() {
        var oBounds = me.Map.getBounds();
        var oSouthWest = oBounds.getSouthWest();
        var oNorthEast = oBounds.getNorthEast();
        return { StartLat: oSouthWest.lat(), StartLong: oSouthWest.lng(), EndLat: oNorthEast.lat(), EndLong: oNorthEast.lng() };
    }



    /* 2 Icons */

    //2.1 Add Icon
    this.AddIcon = function(sIconKey, sURL, iHeight, iWidth, iAnchorX, iAnchorY) {
        me.Icons[sIconKey] = { URL: sURL, Height: iHeight, Width: iWidth, AnchorX: iAnchorX, AnchorY: iAnchorY };
    }

    //2.2 Clear Icons
    this.ClearIcons = function() {
        me.Icons = new Array();
    }



    /* 3 Markers */


    //3.1 AddMarker
    this.AddMarker = function(nLat, nLong, sMarkerID, sIconKey, oOnClick, oMouseOver, oMouseOut,
							iMinLat, iMaxLat, iMinLong, iMaxLong) {

        //icon
        var oIcon;
        if (sIconKey != undefined) {
            var oCustomIcon = me.Icons[sIconKey];
            oIcon = new GIcon();
            oIcon.image = oCustomIcon.URL;
            oIcon.iconAnchor = new GPoint(oCustomIcon.AnchorX, oCustomIcon.AnchorY);
            oIcon.iconSize = new GSize(oCustomIcon.Width, oCustomIcon.Height);
        } else {
            oIcon = new GIcon(G_DEFAULT_ICON);
        }


        //get add marker
        var oLatLong = new GLatLng(nLat, nLong);
        var oMarker = new GMarker(oLatLong, { icon: oIcon })
        var oOverlay = me.Map.addOverlay(oMarker);


        //store marker details
        var oBounds = { MinLat: iMinLat, MaxLat: iMaxLat, MinLong: iMinLong, MaxLong: iMaxLong };
        me.Markers[sMarkerID] = { Lat: nLat, Long: nLong, Marker: oMarker, Bounds: oBounds };


        //add events
        if (oOnClick != undefined) {
            GEvent.addListener(oMarker, 'click', function() { eval(oOnClick + '(\'' + s.Replace(sMarkerID.toString(), '\'', '\\\'') + '\')'); });
        }
        if (oMouseOver != undefined) {
            GEvent.addListener(oMarker, 'mouseover', function() { eval(oMouseOver + '(\'' + s.Replace(sMarkerID.toString(), '\'', '\\\'') + '\')'); });
        }
        if (oMouseOut != undefined) {
            GEvent.addListener(oMarker, 'mouseout', function() { eval(oMouseOut + '(\'' + s.Replace(sMarkerID.toString(), '\'', '\\\'') + '\')'); });
        }




    }

    //3.2 GetMarkerByMarkerID
    this.GetMarkerByMarkerID = function(sMarkerID) {

        //get the relevant marker;
        var oMarker = me.Markers[sMarkerID];
        var oLatLong = new GLatLng(oMarker.Lat, oMarker.Long);
        var oCoords = me.Map.fromLatLngToContainerPixel(oLatLong);

        //set the x and y from lat and long now the map is zoomed
        oMarker.Coords = { x: oCoords.x, y: oCoords.y };
        return oMarker
    }


    //3.3 Clear Markers
    this.ClearMarkers = function() {
        me.Markers = new Array();
    }



    /* 4 Builder */

    //4.1 Build
    this.Build = function(bCentreAndZoom, sIcons, sEventDefs, sPoints) {

        me.Map.clearOverlays();

        //icons
        me.ClearIcons();
        var aIcons = sIcons.split('#');
        for (var i = 0; i < aIcons.length; i++) {
            var aIcon = aIcons[i].split(',');
            me.AddIcon(aIcon[0], aIcon[1], aIcon[2], aIcon[3], aIcon[4], aIcon[5]);
        }

        //event defs
        var aEventDefs = new Array();
        var aEvents = sEventDefs.split('#');
        for (var i = 0; i < aEvents.length; i++) {
            var aEvent = aEvents[i].split(',');
            aEventDefs[aEvent[0]] = { Click: aEvent[1], MouseOver: aEvent[2], MouseOut: aEvent[3] };
        }


        //points
        me.ClearMarkers();
        if (sPoints != '') {
            var aPoints = sPoints.split('#');
            var aPoint;
            for (var i = 0; i < aPoints.length; i++) {
                aPoint = aPoints[i].split(',');
                me.AddMarker(aPoint[1], aPoint[2], aPoint[0], aPoint[4],
						aEventDefs[aPoint[3]].Click, aEventDefs[aPoint[3]].MouseOver, aEventDefs[aPoint[3]].MouseOut,
							aPoint[5], aPoint[6], aPoint[7], aPoint[8]);
            }
        }

        //only zoom and centre if this is the first stab at properties
        if (bCentreAndZoom) {
            me.CentreAndZoom();
        }
        me.ManualZoom = false;
    }


    /* 5 Support Functions */

    //5.1 centre and zoom
    this.CentreAndZoom = function(MaxZoomLevel) {

        var aBounds = new GLatLngBounds();

        for (var marker in me.Markers) {
            var point = new GLatLng(me.Markers[marker].Lat, me.Markers[marker].Long);
            aBounds.extend(point);
        }

        me.Map.checkResize();
        me.Map.setZoom(me.Map.getBoundsZoomLevel(aBounds));
        me.Map.setCenter(aBounds.getCenter());

        if (MaxZoomLevel != undefined && MaxZoomLevel < me.Map.getZoom()) {
            me.Map.setZoom(MaxZoomLevel);
        }
    }



}
