/*
Classes defined in this file,
    (1) GoogleMap
            - To define the namespace
            
    (2) GoogleMap.AddressLocator
            - Handles the geocoding and displaying map for a given address
*/

///////////////////////////////////////////////////////////////////////////////////////////////

GoogleMap = function() {}

///////////////////////////////////////////////////////////////////////////////////////////////

GoogleMap.AddressLocator = function() {}

GoogleMap.AddressLocator.AddressGeoCode         = undefined;
GoogleMap.AddressLocator.Accuracy               = undefined;

GoogleMap.AddressLocator.MapControl             = undefined;
GoogleMap.AddressLocator.MessageContainerControl= undefined;
GoogleMap.AddressLocator.MessageControl         = undefined;
GoogleMap.AddressLocator.HiddenXControl         = undefined;
GoogleMap.AddressLocator.HiddenYControl         = undefined;
GoogleMap.AddressLocator.HiddenAccuracyControl  = undefined;

GoogleMap.AddressLocator.Map                    = undefined;
GoogleMap.AddressLocator.ZoomLevel              = undefined;
GoogleMap.AddressLocator.Address                = undefined;
GoogleMap.AddressLocator.UseRecursive           = undefined;
GoogleMap.AddressLocator.AccuracyRequired       = undefined;

GoogleMap.AddressLocator.RequiredAccuracyLevel  = undefined;

GoogleMap.AddressLocator.AddressNotFound        = undefined;
GoogleMap.AddressLocator.AccuracyValidationMsg  = undefined;

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.LoadMap = function()
{
    try
    {
        GoogleMap.AddressLocator.InitializeMap();
        GoogleMap.AddressLocator.DetermineGeoCodeAndShowOnMap();
    }
    catch(ex) {}
}

GoogleMap.AddressLocator.LoadMapReadOnly = function()
{
    try
    {
        GoogleMap.AddressLocator.InitializeMap();
        GoogleMap.AddressLocator.ShowOnMapAsReadOnly();
    }
    catch(ex) {}
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.UnloadMap = function()
{
    try
    {
        GUnload;
    }
    catch(ex) {}
}
        
/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.InitializeMap = function()
{
    try
    {
        GoogleMap.AddressLocator.SetMapVisibility('hidden');
        if (google.maps.BrowserIsCompatible()) {
            if (GoogleMap.AddressLocator.MapControl)
            {
                GoogleMap.AddressLocator.Map = new google.maps.Map2(GoogleMap.AddressLocator.MapControl);
                GoogleMap.AddressLocator.Map.addControl(new google.maps.SmallMapControl());
            }
        }
    }
    catch (ex) { }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.DetermineGeoCodeAndShowOnMap = function()
{
    GoogleMap.AddressLocator.GetGeoCodeFromHiddens();
    
    if (!GoogleMap.AddressLocator.AddressGeoCode)
    {
        GoogleMap.AddressLocator.DetermineGeoCode();
    }
    else
    {
        GoogleMap.AddressLocator.ShowOnMap();
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.DetermineGeoCode = function()
{
    if(GoogleMap.AddressLocator.UseRecursive && GoogleMap.AddressLocator.AccuracyRequired)
    {
        GoogleGeoCoder.RecursiveGeoCoder.GeoCodeAddressRecursive(GoogleGeoCoder.ResponseType.JSON,
                                                                 GoogleMap.AddressLocator.Address,
                                                                 GoogleMap.AddressLocator.CallBackGeoCodeAndAccuracy);
    }
    else if(GoogleMap.AddressLocator.UseRecursive && !GoogleMap.AddressLocator.AccuracyRequired)
    {
        GoogleGeoCoder.RecursiveGeoCoder.GeoCodeAddressRecursive(GoogleGeoCoder.ResponseType.Point,
                                                                 GoogleMap.AddressLocator.Address,
                                                                 GoogleMap.AddressLocator.CallBackGeoCodeOnly);
    }
    else if(!GoogleMap.AddressLocator.UseRecursive && GoogleMap.AddressLocator.AccuracyRequired)
    {
        GoogleGeoCoder.GeoCoder.GeoCode(GoogleGeoCoder.ResponseType.JSON,
                                        GoogleMap.AddressLocator.Address,
                                        GoogleMap.AddressLocator.CallBackGeoCodeAndAccuracy);
    }
    else
    {
        GoogleGeoCoder.GeoCoder.GeoCode(GoogleGeoCoder.ResponseType.Point,
                                        GoogleMap.AddressLocator.Address,
                                        GoogleMap.AddressLocator.CallBackGeoCodeOnly);
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.ShowOnMap = function()
{
    if (!GoogleMap.AddressLocator.AccuracyRequired)
        GoogleMap.AddressLocator.ShowOnMapWithoutAccuracyValidation();
    else
        GoogleMap.AddressLocator.ShowOnMapWithAccuracyValidation();
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.ShowOnMapWithoutAccuracyValidation = function()
{
    if (GoogleMap.AddressLocator.AddressGeoCode)
    {
        GoogleMap.AddressLocator.MessageContainerControl.style.display = "none";
        GoogleMap.AddressLocator.SetMapVisibility('visible');     
        GoogleMap.AddressLocator.SetMapCenter();
        GoogleMap.AddressLocator.AddAddressMarkerToMap();
    }
    else
    {
        GoogleMap.AddressLocator.MessageContainerControl.style.display = "block";
        GoogleMap.AddressLocator.MessageControl.innerHTML = GoogleMap.AddressLocator.AddressNotFound;
    }
}
/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.ShowOnMapAsReadOnly = function()
{
    GoogleMap.AddressLocator.GetGeoCodeFromHiddens();
    
    if (GoogleMap.AddressLocator.AddressGeoCode)
    {
        GoogleMap.AddressLocator.SetMapVisibility('visible');
        GoogleMap.AddressLocator.SetMapCenter();
        GoogleMap.AddressLocator.AddAddressMarkerToMapReadOnly();
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.ShowOnMapWithAccuracyValidation = function()
{
    if (GoogleMap.AddressLocator.AddressGeoCode)
    {
        GoogleMap.AddressLocator.MessageContainerControl.style.display = "none";

        if (GoogleMap.AddressLocator.IsValidAccuracy())
        {
            GoogleMap.AddressLocator.SetMapVisibility('visible');
            GoogleMap.AddressLocator.SetMapCenter();
            GoogleMap.AddressLocator.AddAddressMarkerToMap();
            GoogleMap.AddressLocator.MessageContainerControl.style.display = "none";
        }
        else
        {
            GoogleMap.AddressLocator.MessageContainerControl.style.display = "block";
            GoogleMap.AddressLocator.MessageControl.innerHTML = GoogleMap.AddressLocator.AccuracyValidationMsg;
        }   
    }
    else
    {
        GoogleMap.AddressLocator.MessageContainerControl.style.display = "block";
        GoogleMap.AddressLocator.MessageControl.innerHTML = GoogleMap.AddressLocator.AddressNotFound;
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.SetMapVisibility = function(value)
{
    if(GoogleMap.AddressLocator.MapControl)
    {
        GoogleMap.AddressLocator.MapControl.style.visibility = value;
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.SetMapCenter = function()
{
    if(GoogleMap.AddressLocator.Map)
    {
        if(GoogleMap.AddressLocator.AddressGeoCode)
        {
            GoogleMap.AddressLocator.Map.setCenter(GoogleMap.AddressLocator.AddressGeoCode, GoogleMap.AddressLocator.ZoomLevel);
        }
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.AddAddressMarkerToMap = function()
{
    if (GoogleMap.AddressLocator.Map && 
            GoogleMap.AddressLocator.AddressGeoCode)
    {
        var marker = new google.maps.Marker(GoogleMap.AddressLocator.AddressGeoCode, {draggable: true});
        
        GoogleMap.AddressLocator.Map.addOverlay(marker);
       
        google.maps.Event.addListener(marker, 'dragstart', function(){
            GoogleMap.AddressLocator.Map.closeInfoWindow();
        });

        google.maps.Event.addListener(marker, 'dragend', function() {
            var newGeoCode = marker.getPoint();
            
            GoogleMap.AddressLocator.AddressGeoCode = newGeoCode;
            GoogleMap.AddressLocator.Accuracy = GoogleGeoCoder.AccuracyLevel.ADDRESS;
            
            GoogleMap.AddressLocator.SetAccuracyToHiddens(); 
            GoogleMap.AddressLocator.SetGeoCodeToHiddens();
        });
    }

}/*--------------------------------------------------------------------------------------------*/
GoogleMap.AddressLocator.AddAddressMarkerToMapReadOnly = function()
{
    if (GoogleMap.AddressLocator.Map && 
            GoogleMap.AddressLocator.AddressGeoCode)
    {
        var marker = new google.maps.Marker(GoogleMap.AddressLocator.AddressGeoCode, {draggable: false});
        
        GoogleMap.AddressLocator.Map.addOverlay(marker);     
    }

}/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.GetGeoCodeFromHiddens = function()
{
    var addressGeoCode = null;

    if (GoogleMap.AddressLocator.HiddenXControl && 
            GoogleMap.AddressLocator.HiddenYControl)
    {
        var x = parseFloat(GoogleMap.AddressLocator.HiddenXControl.value.replace(',','.'));
        var y = parseFloat(GoogleMap.AddressLocator.HiddenYControl.value.replace(',','.'));
        if( !isNaN(x) && x !=0 && !isNaN(y) && y !=0)
        {
            try{
                addressGeoCode = new google.maps.LatLng(y, x);     
            }catch (ex)
            {}
        }
    }
    GoogleMap.AddressLocator.AddressGeoCode = addressGeoCode;
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.GetAccuracyFromHiddens = function()
{
    var accuracy = null;

    if (GoogleMap.AddressLocator.HiddenAccuracyControl)
    {
        var val = parseInt(GoogleMap.AddressLocator.HiddenAccuracyControl.value);
        accuracy = (isNaN(val)?GoogleGeoCoder.AccuracyLevel.UNKNOWN:val);
    }
    GoogleMap.AddressLocator.Accuracy = accuracy;
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.SetGeoCodeToHiddens = function()
{
    if (GoogleMap.AddressLocator.AddressGeoCode)
    {
        if (GoogleMap.AddressLocator.HiddenXControl) 
            GoogleMap.AddressLocator.HiddenXControl.value = GoogleMap.AddressLocator.AddressGeoCode.lng();
        if (GoogleMap.AddressLocator.HiddenYControl) 
            GoogleMap.AddressLocator.HiddenYControl.value = GoogleMap.AddressLocator.AddressGeoCode.lat();
    }
    else
    {
        if (GoogleMap.AddressLocator.HiddenXControl) 
            GoogleMap.AddressLocator.HiddenXControl.value = '';
        if (GoogleMap.AddressLocator.HiddenYControl) 
            GoogleMap.AddressLocator.HiddenYControl.value = '';
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.SetAccuracyToHiddens = function()
{
    if (GoogleMap.AddressLocator.Accuracy)
    {
        if (GoogleMap.AddressLocator.HiddenAccuracyControl) 
            GoogleMap.AddressLocator.HiddenAccuracyControl.value = GoogleMap.AddressLocator.Accuracy;
    }
    else
    {
        if (GoogleMap.AddressLocator.HiddenAccuracyControl) 
            GoogleMap.AddressLocator.HiddenAccuracyControl.value = '';
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.IsValidAccuracy = function()
{
    if(GoogleMap.AddressLocator.HiddenAccuracyControl)
    {
        if(GoogleMap.AddressLocator.HiddenAccuracyControl.value < GoogleMap.AddressLocator.RequiredAccuracyLevel)
            return false;
        else
            return true;
    }
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.CallBackGeoCodeOnly = function(geocode)
{
    GoogleMap.AddressLocator.AddressGeoCode = geocode;
    GoogleMap.AddressLocator.SetGeoCodeToHiddens();

    GoogleMap.AddressLocator.ShowOnMap();
}

/*--------------------------------------------------------------------------------------------*/

GoogleMap.AddressLocator.CallBackGeoCodeAndAccuracy = function(geocode, accuracy)
{
    
    GoogleMap.AddressLocator.AddressGeoCode = geocode;
    GoogleMap.AddressLocator.Accuracy = accuracy;
    
    GoogleMap.AddressLocator.SetGeoCodeToHiddens();
    GoogleMap.AddressLocator.SetAccuracyToHiddens();
    
    GoogleMap.AddressLocator.ShowOnMap();
}

///////////////////////////////////////////////////////////////////////////////////////////////