var mapResized = false;
var markerDraggedMsg = "Marker Dragged...";
var usingGpsLocationMsg = "Using Latitude/Longitude Positioning";
var escapeStringArray = ["commonwealth of", "republic of", "kingdom of"];

function isGoogleMapsAvailable()
{
    return (typeof google === 'object' && typeof google.maps === 'object');
}

function parseAddress(address) {
    try {
        if ( typeof address == "string") {
            var re = new RegExp(escapeStringArray.join("|"), "gi");
            return address.replace(re, "");
        } else {
            return address;
        }
    } catch(e) {
        return address;
    }
}

function toggleMapDisplay(divid, showMapButtonId)
{
    var mapCanvasDiv = $('#' + divid);
    var showMapButtonDiv = $('#' + showMapButtonId);

    if ('none' === mapCanvasDiv.css('display'))
    {
        mapCanvasDiv.css('display', "");
        var mres = $('#' + MA_ASSET_MAP_SINK);
        mres.trigger(MA_ASSET_MAP_FIRST_RENDER);
        mres.unbind();
        showMapButtonDiv.children().first().css("display", "none");
        showMapButtonDiv.children().last().css("display", "");
    }
    else
    {
        mapCanvasDiv.css('display', "none");
        showMapButtonDiv.children().first().css("display", "");
        showMapButtonDiv.children().last().css("display", "none");
    }
}

function showAddressV3LatLong(lat, longi, address, divid, zoomLevel, allowDraggableMarker, initialCall) {
    if (!isGoogleMapsAvailable())
    {
        return;
    }

    //define variables we'll be using
    var mapCanvasDiv = $('#' + divid);

    if (mapCanvasDiv.css('display') === 'none')
    {
        return;
    }

    if ( typeof zoomLevel === "undefined") {
        zoomLevel = 13;
    }

    if ( typeof allowDraggableMarker === "undefined") {
        allowDraggableMarker = false;
    }

    try {

    	var myLatLng;
    	
        var myOptions = {
            zoom : zoomLevel,
            mapTypeId : google.maps.MapTypeId.ROADMAP
        };

        //if lat lng exist, use them instead, try to preserve the address
        if ((lat != null) && (longi != null) && (lat != "") && (longi != "")) {
        	myLatLng = new google.maps.LatLng(lat, longi)
            myOptions = {
                center : myLatLng,
                zoom : zoomLevel
            };
        }

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

        //going with latlng here
        //logToConsole("using latlng   " + myLatLng + "   " + address + "   " + map + "   " + mapCanvasDiv + "   " + allowDraggableMarker + "   " + initialCall);
        showMapLatLng(myLatLng, address, map, mapCanvasDiv, allowDraggableMarker, initialCall);
    } catch(err) {
        //logToConsole(err);
    }
}

function showMapLatLng(latLngObj, address, map, mapCanvasDiv, allowDraggableMarker, initialCall) {
    if (!isGoogleMapsAvailable())
    {
        return;
    }

    //if the map is not visible, show it and trigger the resize to react to the showing
    mapCanvasDiv.show();
    google.maps.event.trigger(map, 'resize');

    map.setCenter(latLngObj);

    //dont create multiple markers, remove the old one
    if (mapCanvasDiv.data('markerObject') != null) {
        mapCanvasDiv.data('markerObject').setMap(null);
        mapCanvasDiv.data('markerObject', null);
    }

    var marker = new google.maps.Marker({
        map : map,
        draggable : allowDraggableMarker,
        position : latLngObj,
        title : "Physical Location\r\n\r\nLatitude:" + latLngObj.lat() + ", Longitude:" + latLngObj.lng()
    });

    //fire
    if ( typeof initialCall !== "undefined") {
        mapCanvasDiv.trigger('mapInitialLoad', [latLngObj, address]);
        //clear out the fallback flag
        mapCanvasDiv.data('fallback', null);
    } else {
        mapCanvasDiv.trigger('mapLoaded', [latLngObj, address]);
    }

    if (allowDraggableMarker == true) {
        google.maps.event.addListener(marker, 'dragend', function() {
            mapCanvasDiv.trigger('mapDragEnd', marker.getPosition());
            marker.setTitle("Physical Location\r\n\r\nLatitude:" + marker.getPosition().lat() + ", Longitude:" + marker.getPosition().lng());
        });
    }

    //store the map+marker in the data when we're done
    mapCanvasDiv.data('mapObject', map);
    mapCanvasDiv.data('markerObject', marker);

}

function initAssetMapControl(mapDivId, latitudeFieldId, longitudeFieldId, addressToggleId, latLongToggleId,
                             useSiteLocationToggleId, addressFieldId, gpsLatLngSinkId) {
    if (!isGoogleMapsAvailable())
    {
        return;
    }

    var jqMapDivObj = $('#' + mapDivId);
    var addressField = parseAddress($('#' + addressFieldId))

    //bind these to the jqMapDivObj
    jqMapDivObj.data('latitudeFieldId', latitudeFieldId);
    jqMapDivObj.data('longitudeFieldId', longitudeFieldId);

    var dragCallback = function(event, endPos) {
        updatePositionInputs(endPos, $('#' + latitudeFieldId), $('#' + longitudeFieldId));
        $('#' + latLongToggleId).prop('checked', true).change();
        addressField.val(markerDraggedMsg);
    };

    //bind to the canvas, an initial load event
    jqMapDivObj.on('mapInitialLoad', function(event, latLngPosition, address) {
        $(this).data('siteLatLng', latLngPosition);
        $(this).data('siteAddress', address);
        updatePositionInputs(latLngPosition, $('#' + latitudeFieldId), $('#' + longitudeFieldId));
    });

    jqMapDivObj.on('mapInitialLoad', function(event, latLngPosition, address) {
    });

    //bind the mapLoaded event
    jqMapDivObj.on('mapLoaded', function(event, latLngPosition, address) {
        updatePositionInputs(latLngPosition, $('#' + latitudeFieldId), $('#' + longitudeFieldId));
    });

    jqMapDivObj.on('mapLoaded', function(event, latLngPosition, address) {
    });

    //bind the checkbox

    {
        $('#' + useSiteLocationToggleId).on('change', function(a,b,c) {
            if ($(this).is(':checked')) {

                $('#' + gpsLatLngSinkId).hide();
                var latLngPosition = jqMapDivObj.data('siteLatLng');
                var siteAddress = jqMapDivObj.data('siteAddress');

                //if siteAddress has been populated. otherwise it is initial
                if (siteAddress != null) {
                    addressField.val(siteAddress);
                    toggleTextInput(addressField, false);
                    showAddressV3LatLong(null, null, siteAddress, mapDivId, 13, false);
                } else if (jqMapDivObj.data('fallback')) {
                    //no site address, empty the canvas
                    displayErrorCanvas(jqMapDivObj, map);
                }

            } else {
                $('#' + gpsLatLngSinkId).show();
                //if map is available, set dragging
                if (jqMapDivObj.data('markerObject')) {
                    jqMapDivObj.data('markerObject').setDraggable(true);
                    //update
                    showAddressV3LatLong($('#' + latitudeFieldId).val(), $('#' + longitudeFieldId).val(), null, mapDivId, 13, true);
                }

                if (jqMapDivObj.data('fallback')) {
                    addressField.val("Defaulting to address of business" + siteAddress);
                    jqMapDivObj.find('.updateMapButton').trigger('click');
                }
            }
        });
    }

    //bind entry methods
    var locationEntryMethodCallback = function(event) {
        if ($(this).prop('checked', true) && ($(this).val() == 'address')) {
            //enable and disable the address box
            toggleTextInput($('#' + latitudeFieldId), false);
            toggleTextInput($('#' + longitudeFieldId), false);
            toggleTextInput(addressField, true);

            //clear out dragging message
            if (addressField.val() == markerDraggedMsg || addressField.val() == usingGpsLocationMsg) {
                addressField.val("");
            }

            addressField.select().focus();
        } else if ($(this).prop('checked', true) && ($(this).val() == 'latLng')) {
            //enable and disable the lat lng boxes
            toggleTextInput($('#' + latitudeFieldId), true);
            toggleTextInput($('#' + longitudeFieldId), true);
            toggleTextInput($('#' + addressFieldId), false);
        }
    };

    $('#' + addressToggleId).on('change', locationEntryMethodCallback);
    $('#' + latLongToggleId).on('change', locationEntryMethodCallback);

    //bind drag event
    jqMapDivObj.on('mapDragEnd', dragCallback);

    //bind address field enter key
    $('#' + addressFieldId).keydown(function(event) {
        if (event.which == 13) {
            event.preventDefault();
            jqMapDivObj.find('.updateMapButton').first().click();
        }
    });
}

function updatePositionInputs(latLngPosition, latField, longField) {
    latField.val(latLngPosition.lat() + '');
    longField.val(latLngPosition.lng() + '');
}

function toggleTextInput(elem, enable) {
    elem.prop('disabled', !enable);
    var color = (enable == true) ? '#FFFFFF' : '#E8EDF0';
    elem.css('background-color', color);
}

function resizeMap(mapCanvasId, width, shrink) {
    var mapCanvasDiv = $('#' + mapCanvasId);

    //resize using jquery
    var size = "200px";
    if (shrink == true) {
        size = "100px";
    }

    mapCanvasDiv.stop(true, true).animate({
        height : size
    }, 40, function() {

        if (mapCanvasDiv.data('mapObject')) {
            var map = mapCanvasDiv.data('mapObject');
            var marker = mapCanvasDiv.data('markerObject');
            google.maps.event.trigger(map, 'resize');
            map.setCenter(marker.getPosition());
        }
    });
}

function displayErrorCanvas(mapCanvasDiv, map) {
    mapCanvasDiv.show();
    document.getElementById(mapCanvasDiv.attr('id')).innerHTML = '&nbsp;&nbsp;Cannot Display Map, ensure the inherited address is valid, or set the location manually using the "Override" checkbox below';
}
