var map			= null,
    baseUrl2	= null,
    infoWindow  = null;

//Initial Starting Values
var centerLatitude  = 0,
    centerLongitude = 0,
    startZoom       = 1,
    loadedBounds    = null,
    geocoder        = null,
    mCluster        = null,
    markers         = {
                fundraisers : [],
                galaparty   : [],
                moparty     : [],
                morunning   : [],
                promotions  : [],
                searched    : []
    };

function initializeMapping( mapdiv, base )
{
	baseUrl2 = base;

    var myOptions = {
          zoom: startZoom,
          center: new google.maps.LatLng( centerLatitude, centerLongitude ),
          mapTypeControl: true,
          mapTypeControlOptions: {
            style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
          },
          zoomControl: true,
          zoomControlOptions: {
            style: google.maps.ZoomControlStyle.DEFAULT
          },
          mapTypeId: google.maps.MapTypeId.ROADMAP
        }

		map = new google.maps.Map( document.getElementById( mapdiv ), myOptions );

		// Update the map markers when we move/zoom the map
        google.maps.event.addListener(map, 'tilesloaded', function() { updateMarkers() });

        infoWindow = new google.maps.InfoWindow();
        infoWindow.setOptions({ maxWidth: '500' });

		geocoder = new google.maps.Geocoder();
		//geocoder.setBaseCountryCode(country);
}

function plotListOfPoints()
{
	var markersArray=[];

	$.getJSON( '/momoney/get-members/', function( json ) {
		for( var i in json.points )
		{
			var point = new GLatLng( json.points[i].lat, json.points[i].lon );
			var html = "Number of Members here: " + json.points[i].members.length;
			var marker = createMarker( point, html );
			markersArray.push( marker );
		}
		cluster=new ClusterMarker( map, {
			markers:markersArray
		} );
		cluster.fitMapToMarkers();

		map.savePosition();
	});
}

function updateMarkers()
{
	var bounds = map.getBounds();
	if( loadedBounds != null )
	{
		if( loadedBounds.containsBounds( bounds ) )
		{
			// No need to reload...
			return;
		}
	}
	$('#map-loading-graphic').css( 'display', 'inline' );
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var getVars = 'nelat/' + northEast.lat()
                            + '/nelon/' + northEast.lng()
                            + '/swlat/' + southWest.lat()
                            + '/swlon/' + southWest.lng()
                            + '/zoom/' + map.getZoom();

    // get markers from server, that stores markers in markers global variable
    getMarkers( this.baseUrl2, getVars, 'fundraisers' );

    $('#map-loading-graphic').css( 'display', 'none' );
}


/**
 * get markers from server and store them in markers global object
 *
 */
function getMarkers( baseUrl, options, type ) {

    $.getJSON( baseUrl + 'get-marker-points/type/' + type + '/' + options, function( json ) {

		var fundRaisers = json['fundraisers'];
        funraisersMarkers('remove'); // remove previous fundraiser markes from map
        markers.fundraisers = []; // Actually remove the reference to marker. Empty fundraisers, otherwiser when you zoom out it will still have old markers
		for( var i in fundRaisers )
		{
            var point = new google.maps.LatLng( fundRaisers[i].lat, fundRaisers[i].lon ),
                html = buildBubbleHtml( fundRaisers[i], json.type, i ),
                boundaries = fundRaisers[i].boundaries || null,
                marker = createMarker( point, html, i, boundaries );

			markers.fundraisers.push( marker );
		}

        var galaParties = json['galaparties'];
        for( var i in galaParties )
		{
            var point = new google.maps.LatLng( galaParties[i].lat, galaParties[i].lon ),
                html = buildEventBubbleHtml( galaParties[i], i, 'galaparty' ),
                marker = createMarker( point, html, i, null, '/images/icons/galaparty.png' );

            markers.galaparty.push( marker );
        }

        var promotions = json['promotions'];
        for( var i in promotions )
		{
            var point = new google.maps.LatLng( promotions[i].lat, promotions[i].lon ),
                html = buildPromotionsBubbleHtml( promotions[i], i, 'promotion' ),
                marker = createMarker( point, html, i, null, '/images/icons/promotion.png' );

            markers.promotions.push( marker );
        }

        var moParties = json['moparties'];
        for( var i in moParties )
		{
            var point = new google.maps.LatLng( moParties[i].lat, moParties[i].lon ),
                html = buildEventBubbleHtml( moParties[i], i, 'moparty' ),
                marker = createMarker( point, html, i, null, '/images/icons/moparty.png' );

            markers.moparty.push( marker );
        }

        var moRunnings = json['morunnings'];
        for( var i in moRunnings )
		{
            var point = new google.maps.LatLng( moRunnings[i].lat, moRunnings[i].lon ),
                html = buildEventBubbleHtml( moRunnings[i], i, 'morunning' ),
                marker = createMarker( point, html, i, null, '/images/icons/gIcon.png' );

            markers.morunning.push( marker );
        }

        updateMarkerOverlays();
        /*
		if( mapDebug === true )
		{
			//console.log( 'DEBUG:' );
			//console.log( json['debug'] );
			var gridPoints = json['debug']['grids'];

			for( var x in gridPoints )
			{
				var bounds = gridPoints[ x ];
				var rectBounds = new GLatLngBounds(
					new GLatLng( bounds['swLat'],
						bounds['swLon'] ),
					new GLatLng( bounds['neLat'],
						bounds['neLon'] )
					);
			//map.addOverlay( new Rectangle( rectBounds, 1, '#999999' ) );
			}

		}

		if( json['debug']['bounds'] )
		{
			bounds = json['debug']['bounds'];
			rectBounds = new GLatLngBounds(
				new GLatLng( bounds['swLat'],
					bounds['swLon'] ),
				new GLatLng( bounds['neLat'],
					bounds['neLon'] )
				);
			loadedBounds = rectBounds;
		//map.addOverlay( new Rectangle( rectBounds, 1, '#CCCCCC' ) );
		} else {
			loadedBounds = null;
		}*/
	});

}

/**
 * create marker using google geopoint and bubble html
 *
 */
function createMarker( point, html, j, boundaries, icon )
{
    var movIcon = {};
	movIcon.image = icon || "/images/icons/gmark.png";
	movIcon.shadow = "/images/icons/shadow-gmark.png";

	var marker = new google.maps.Marker({
                            position: point,
                            icon    : movIcon.image,
                            shadow  : movIcon.shadow
                 });

    google.maps.event.addListener( marker, "click", function() {
        if( boundaries ){
            $.get( nsBaseUrl + 'momoney/load-top-fundraisers/neLat/'+boundaries.neLat+'/neLon/'+boundaries.neLon+'/swLat/'+boundaries.swLat+'/swLon/'+boundaries.swLon, function(data) {
                if( data ) {
                    $("#marker_"+j).html(data);
                }
            });
        }
    infoWindow.setContent( html );
    infoWindow.open( map, marker );
	});

	return marker;
}

function updateMarkerOverlays()
{

    $('.js_toggle-mapoverlays').each(function(){
        var action = null;
        if (!this.checked) action = 'remove';

        // if show all is checked, set action to add regardless of if the checkbox is checked or not
        if ( $('#mapToggles-showall:checked').val() )
            action = 'add';

        switch (this.value.toLowerCase()){
            case 'top_fundraisers':
                funraisersMarkers( action );
                break;
            case 'events':
                galapartyMarkers( action );
                mopartyMarkers( action );
                morunningMarkers( action );
                break;
            case 'promotions':
                promotionsMarkers( action );
                break;
            default:
                break;
        }

    });
}


function funraisersMarkers( action )
{
    action = action || 'add'; // if no action is passed set default to add
    var targetMap = null;

    // if action is add overlays, set targetmap to real map initialised on page.
    // else targetmap will be null and overlays will be removed from map, but we'll still have reference to markers in makers global array
    if ( 'add' == action )
        targetMap = map;


    if (markers.fundraisers.length == 0)
        return;

    for( var i in markers.fundraisers )
    {
        markers.fundraisers[i].setMap( targetMap );
    }

}

function galapartyMarkers( action )
{
    action = action || 'add';
    var targetMap = null;

    if ( 'add' == action )
        targetMap = map;

    if (markers.galaparty.length == 0)
        return;

    for( var i in markers.galaparty )
    {
        markers.galaparty[i].setMap( targetMap );
    }
}

function mopartyMarkers( action )
{
    action = action || 'add';
    var targetMap = null;

    if ( 'add' == action )
        targetMap = map;

    if (markers.moparty.length == 0)
        return;

    for( var i in markers.moparty )
    {
        markers.moparty[i].setMap( targetMap );
    }
}

function morunningMarkers( action )
{
    action = action || 'add';
    var targetMap = null;

    if ( 'add' == action )
        targetMap = map;

    if (markers.morunning.length == 0)
        return;

    for( var i in markers.morunning )
    {
        markers.morunning[i].setMap( targetMap );
    }
}

function  promotionsMarkers( action )
{
    action = action || 'add';
    var targetMap = null;

    if ( 'add' == action )
        targetMap = map;

    if (markers.promotions.length == 0)
        return;

    for( var i in markers.promotions )
    {
        markers.promotions[i].setMap( targetMap );
    }
}

/**
 * Given an object containing the marker details, a marker type (will be
 * "country" for zoom levels 1-3, and a marker-number, creates the base
 * marker content to go into the popup bubble.
 *
 * Top fundraisers for non-country markers will be loaded via ajax when
 * opened.
 */
function buildBubbleHtml( object, type, j )
{
	var html = '<div class="map-bubble-content map-bubble-content_wide">';
    var height = '';
	if( type == "country" )
	{
		//country view....
		html += "<b>" + object.name + "</b><br />";
	}
	else
	{
		html += "<b>" + object.suburb + "</b> ";
        if( object.postcode )
            html += "(" + object.postcode + ")";
        html += "<br />";

        height = "height:70px";
	}

	html += object.num_members;
	if( object.num_members == 1 )
		html += " person<br />";
	else
		html += " people<br />";

	html += object.amount_raised+'<br/><br />';


    html += '<div id="marker_'+j+'" style="padding:0px;margin:0px;'+height+'">';

    // We should only have TopMo info for "country" markers
	if( object.topmo )
	{
        html += "<b>Top fundraisers</b><br />";
        for (var i in object.topmo)
        {
            if( object.topmo[i] )
            {
                html += '<div class="map-topmo"><div class="map-topmo-name">' +
                            '<a href="/mospace/'+object.topmo[i].id+'">'+object.topmo[i].firstname + ' ' + object.topmo[i].lastname + '</a>' +
                            '</div><div class="map-topmo-amount">'+object.topmo[i].amount_raised+'</div>'+
                        '</div>';
            }
        }
	}

    html += '</div></div>';

	return html;
}

/**
 * get galaparty html code to place into marker info bubble
 */
function buildEventBubbleHtml( event, j, eventType )
{
    var html = '<div class="map-bubble-content">';
    var height = '';

    switch (eventType)
    {
        case 'galaparty':
            html += '<b>'+ event.location +'</b><br />';
        break;
        case 'moparty':
            html += '<b>'+event.name+'</b><br />'
        break;
        case 'morunning':
            html += '<b>Mo Running</b><br />'
        break;
    }
    
    html += event.date + '<br />' + event.start_time + ' ' + event.end_time + '<br /><br />';
    html += event.location;

    html += '<p class="address">' + (event.address1 != '' ? event.address1 : '') + (event.address2 != '' ? event.address2 : '')
                + '<br />' + event.suburb + ', ' + event.state + ', ' + event.postcode + '</p>';

    switch (eventType)
    {
        case 'galaparty':
            html += event.venue_info + '<div style="margin: 10px 0 0">' + event.buy_link + '</div>' + '<div style="margin: 10px 0 0"><a href="' + event.facebook_link + '" target="_blank">View on Facebook</a></div>';
        break;
        case 'moparty':
            html += '<div style="margin: 10px 0 0">'+ event.email_link +'</div>';
        break;
        case 'morunning':
            html += '<div style="margin: 10px 0 0">Buy tickets</div>';
        break;
    }

    html += '<div>';
    return html;
}

function buildPromotionsBubbleHtml( promotion, j )
{
    var html = '<div class="map-bubble-content">';
    var height = '';

    html += '<b>'+ promotion.name +'</b><br />';
    html += promotion.description + '<br /><br />';
    html += promotion.location;

    html += '<p class="address">' + (promotion.address1 != '' ? promotion.address1 : '') + (promotion.address2 != '' ? promotion.address2 : '')
                + '<br />' + promotion.suburb + ', ' + promotion.state + ', ' + promotion.postcode + '</p>';

    html += '<div style="margin: 10px 0 0">' + promotion.url + '</div>';

    html += '<div>';
    return html;
}

function mapping_locationSearch()
{
	var location = $('#place').val();

    geocoder.geocode({
        address : location,
        bounds : map.getBounds()
    },
    function ( results, status ){
        if ( status == google.maps.GeocoderStatus.OK ){
            mapping_locationFound( results );
        } else {
            alert( 'Address not found...' );
        }
    });

	return false;
}

function mapping_checkAllBoxes( cbx, form )
{
    for (var i=0; i<form.length; i++)
    {
        var e = form.elements[i];
        if ((e.type == 'checkbox') && (e.name != cbx.name))
        {
            e.checked = cbx.checked;
        }
    }
}


function mapping_locationFound( result )
{

    // clear previously searched location
    if ( markers.searched.length > 0 )
    {
       markers.searched[0].setMap( null );
       markers.searched.splice(0,1);
    }

    map.setCenter( result[0].geometry.location );
    map.fitBounds( result[0].geometry.viewport );
    
    var marker = new google.maps.Marker({
        map     : map,
        position: result[0].geometry.location,
        zIndex  : 1000000
    });

    markers.searched.push(marker);
}

$(document).ready(function(){
    $('#mapToggles-showall').click( function (){
        if ( this.checked )
            $('.js_toggle-mapoverlays:not("#mapToggles-showall")').attr('disabled', 'disabled');
        else
            $('.js_toggle-mapoverlays:not(this)').removeAttr('disabled');
    });
});


