var gwGoogleMap =
{
    map: false,
    mapLat: 59.358396,
    mapLng: 10.338135,

    zoomValue: 8,
    zoomToFitValue: 0.1,
    zoomDivider: 6,

    infoWindow: new Array(),
    infoWindowList: new Array(),
    useInfoWindow: true,

    mapPoints: new Array(),
    markers: new Array(),
    showMarkerPrefix: 'showmarker-',
    markerIDListName: 'gwGoogleMapIDList[]',
    inputMarkerLatPrefix: 'gwGoogleMapLat-',
    inputMarkerLngPrefix: 'gwGoogleMapLng-',
    inputMarkerNamePrefix: 'gwGoogleMapName-',
    inputMarkerURLPrefix: 'gwGoogleMapURL-',
    inputMarkerToggleName: 'gwGoogleMapToggle',

    readMore: 'Read more',

    /*!
      Public functions
    */
    initialize: function( id )
    {
        gwGoogleMap.clearAll();
        gwGoogleMap.createMap( id );
    },

    setMarker: function( id, value )
    {
        var key = 'marker' + id;
        marker = gwGoogleMap.markers[key];
        marker.setVisible( value );
        if ( value == false )
        {
            gwGoogleMap.closeInfoWindow( id );
        }
        gwGoogleMap.updateShowMarker( value );
        gwGoogleMap.zoomToFit();
    },

    toggleMarkers: function( value )
    {
        var markerElements = document.getElementsByName( gwGoogleMap.markerIDListName );

        for ( var index = 0; index < markerElements.length; index++ )
        {
            if ( markerElements[index] )
            {
                var id = gwGoogleMap.showMarkerPrefix + markerElements[index].value;
                var markerCheckbox = document.getElementById( id );
                markerCheckbox.checked = value;
                gwGoogleMap.setMarker( markerElements[index].value, value );
            }
        }
    },

    addAllMarkers: function()
    {
        var markerElements = document.getElementsByName( gwGoogleMap.markerIDListName );

        for ( var index = 0; index < markerElements.length; index++ )
        {
            if ( markerElements[index] )
            {
                value = markerElements[index].value;
                gwGoogleMap.addMarkerDataFromID( value );
            }
        }
    },

    zoomToFit: function()
    {
        if ( gwGoogleMap.mapPoints.length > 0 )
        {
            var bounds = new google.maps.LatLngBounds();
            for (var i = 0, LtLgLen = gwGoogleMap.mapPoints.length; i < LtLgLen; i++) {
                // And increase the bounds to take this point
                bounds.extend( gwGoogleMap.mapPoints[i].position );
            }

            bounds = gwGoogleMap.setMinSize( bounds, gwGoogleMap.zoomToFitValue );
            gwGoogleMap.map.fitBounds( bounds );
        }
    },

    clearAll: function()
    {
        gwGoogleMap.map = false;
        gwGoogleMap.infoWindow = new Array();
        gwGoogleMap.infoWindowList = new Array();
        gwGoogleMap.mapPoints = new Array();
        gwGoogleMap.markers = new Array();
    },

    /*!
      Private functions
    */
    createMap: function( id )
    {
        var latlng = new google.maps.LatLng( gwGoogleMap.mapLat, gwGoogleMap.mapLng );
        var myOptions =
        {
            zoom: gwGoogleMap.zoomValue,
            center: latlng,
            scrollwheel: true,
            scaleControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        var mapCanvas = document.getElementById( id );
        gwGoogleMap.map = new google.maps.Map( mapCanvas, myOptions );
    },

    setMinSize: function( bounds, value )
    {
        var northEast = bounds.getNorthEast();
        var southWest = bounds.getSouthWest();

        var latDiff = northEast.lat() - southWest.lat();
        var lngDiff = northEast.lng() - southWest.lng();

        var level = value / gwGoogleMap.zoomDivider;

        if ( latDiff < value ||
             lngDiff < value )
        {
            var newLat = northEast.lat() + level;
            var newLng = northEast.lng() + level;

            var gwLatlng = new google.maps.LatLng( newLat, newLng );
    		bounds.extend( gwLatlng );

            newLat = southWest.lat() - level;
            newLng = southWest.lng() - level;

            gwLatlng = new google.maps.LatLng( newLat, newLng );
    		bounds.extend( gwLatlng );
        }
        return bounds;
    },

    addMarkerDataFromID: function( id )
    {
        var latitude = document.getElementById( gwGoogleMap.inputMarkerLatPrefix + id );
        var longitude = document.getElementById( gwGoogleMap.inputMarkerLngPrefix + id );
        var title = document.getElementById( gwGoogleMap.inputMarkerNamePrefix + id );
        var url = document.getElementById( gwGoogleMap.inputMarkerURLPrefix + id );

        gwGoogleMap.addMarker( id, latitude.value, longitude.value, title.value, url.value );
    },

    updateShowMarker: function( value )
    {
        var showMarkerCheckbox = document.getElementById( gwGoogleMap.inputMarkerToggleName );
        if ( showMarkerCheckbox != undefined )
        {
            if ( value == false )
            {
                showMarkerCheckbox.checked = false;
            }
            else if ( value == true )
            {
                var markerElements = document.getElementsByName( gwGoogleMap.markerIDListName );
                var markerTest = true;
                for ( var index = 0; index < markerElements.length; index++ )
                {
                    if ( markerElements[index] )
                    {
                        var id = gwGoogleMap.showMarkerPrefix + markerElements[index].value;
                        var markerCheckbox = document.getElementById( id );
                        if ( markerCheckbox.checked != true )
                        {
                            showMarkerCheckbox.checked = false;
                            markerTest = false;
                            break;
                        }
                    }
                }
                if ( markerTest == true )
                {
                    showMarkerCheckbox.checked = true;
                }
            }
        }
    },

    addMarker: function( id, latitude, longitude, title, url )
    {
        longitude = parseFloat( longitude );
        latitude = parseFloat( latitude );

        var myLatlng = new google.maps.LatLng( latitude, longitude );

        var marker = new google.maps.Marker({
              position: myLatlng,
              map: gwGoogleMap.map,
              title: title
                            });

        gwGoogleMap.mapPoints.push( {position: myLatlng} );
        gwGoogleMap.markers['marker' + id] = marker;

        if ( gwGoogleMap.useInfoWindow == true )
        {
            gwGoogleMap.addInfoWindow( id, marker, title, url );
        }
    },

    fetchInfoWindow: function( id )
    {
        var infoWindow = false;
        var key = 'w' + id;
        if ( gwGoogleMap.infoWindow[key] )
        {
            var infoWindow = gwGoogleMap.infoWindow[key];
        }
        return infoWindow;
    },

    closeInfoWindow: function( id )
    {
        var value = false;
        var infoWindow = gwGoogleMap.fetchInfoWindow( id );
        if ( infoWindow )
        {
            infoWindow.close();
            value = true;
        }
        return value;
    },

    createLink: function( url )
    {
        value = '<a href="' + url + '">' + gwGoogleMap.readMore + '</a>';
        return value;
    },

    addInfoWindow: function ( id, marker, value, url )
    {
        value += '<br />' + gwGoogleMap.createLink( url );
        var infoWindowKey = 'w' + id;

        gwGoogleMap.infoWindow[infoWindowKey] = new google.maps.InfoWindow({
           content: value
        });

        google.maps.event.addListener( marker, 'click', function() {
            for ( var i=0; i<gwGoogleMap.infoWindowList.length; i++ )
            {
                gwGoogleMap.closeInfoWindow( gwGoogleMap.infoWindowList[i]);
            }
            gwGoogleMap.infoWindow[infoWindowKey].open( gwGoogleMap.map, marker );
        });
        gwGoogleMap.infoWindowList.push( id );
    }
}
