/**
* An jQuery plugin for Google Maps
* @version  0.1.8
*
* @history: 0.1.0  - The initial version
*           0.1.1  - Select element via jQuery call, ex: $("#myDivID").gmap('init');
*           0.1.6  - Added function for creating a MarkerManager.
*                  - Added option 'title' to add an hover title text over a marker
*                  - Added function to add multiple markers
*                  - Added option for enable/disable zoom by mouse scoll wheel
*                  - Added method for parsing Hitta.se map XML and add markers on the map
*           0.1.7  - Added dynamical zoom level and center point Hitta.se XML, calculated from marker latlng
*           0.1.8  - Added function for searching and geocoding an address and add a marker overlay on the map
*/
(function($) {
    /** 
    * Global namespace
    */
    $.gmap = $.gmap || {};

    // TODO: Put options in a separate js-file -------------------------------------------------------------------------------------
    // Default option values
    $.gmap.MapDefaultOptions =
    {
        language: "en",                         // Map language (not in use YET)
        mapCenter: [0, 0],                      // Map center - longitude-X & latitude-Y
        mapZoom: 12,                            // Map zoom level
        mapControlSize: "small",                // Map control: large, small or none
        scrollWheelZoom: false                  // Map zoom using mouse scroll wheel
    }

    // Default marker options
    $.gmap.MarkerDefaultOptions =
	{
	    LatLng: [],                            // Latitude and longitude (x & y) values
	    HTML: null,                            // HTML for marker info
	    markerEvent: "click",                  // The marker event
	    triggEvent: false,                     // Trigg marker event
	    title: "",                             // Alt title when hovering the marker
	    clickEvent: false,                     // Capture clicks on the marker?

	    // Used if a MarkerManager is created
	    minZoom: 1,                            // Min zoom for marker
	    maxZoom: 17                            // Max zoom for marker
	}

    // Default marker manager options
    $.gmap.MarkerManagerDefaultOptions =
	{
	// Default options for Marker Manager
}

    // Default hittaDotSeXml options
    $.gmap.hittaDotSeXmlDefaultOptions =
	{
	    zoomLevel: 8                          // Map Zoom level
	}

    // Default search address options
    $.gmap.SearchAddressDefaultOptions =
	{
	    address: null,                        // Address to search
	    autoZoomCenter: true,                 // Auto set zoom and map center
	    mapZoom: null,                        // Map zoom
	    HTML: null                            // HTML for marker info

	}
    //--------------------------------------------------------------------------------------------------------------------------------

    /**
    * The init method: Create the map
    * @param HTML-element _element
    * @param array _options
    * @return void
    */
    $.gmap.init = function(_element, _options) {
        // Set options
        var options = $.extend({}, $.gmap.MapDefaultOptions, _options);

        // Check for errors on start up
        $.gmap.checkForErrors(_element);

        // Create a new GMap2 object
        _element.gmap = $.gmap.GMap2 = new GMap2(_element);

        // Set map center and zoom
        _element.gmap.setCenter(new GLatLng(options.mapCenter[0], options.mapCenter[1]), options.mapZoom);

        // Add GMap controls
        switch (options.mapControlSize) {
            case "small":
                _element.gmap.addControl(new GSmallMapControl());
                break;

            case "large":
                _element.gmap.addControl(new GLargeMapControl());
                break;
        }

        if (options.scrollWheelZoom)
            _element.gmap.enableScrollWheelZoom();
    }

    /**
    * GMap error check
    * @return void
    */
    $.gmap.checkForErrors = function() {
        // If undefined the GMap API could not be loaded
        if (typeof GBrowserIsCompatible == 'undefined') {
            alert('Kunde inte ladda Google Maps API');
        }

        // If browser not compatible
        if (!GBrowserIsCompatible()) {
            alert('Din webbläsare är inte kompatiblel med Google Maps');
        }
    }

    /**
    * Creates a marker on map
    * @param array _options
    * @param function _callback
    * @return void
    */
    $.gmap.addMarker = function(_options, _callback) {
        // Marker options
        var options = $.extend({}, $.gmap.MarkerDefaultOptions, _options);

        /** *****************************************************************************************************************
        * EXPERIMENTAL 
        *   - Lägg 'custom icon' i options
        */
        var xIcon = new GIcon(G_DEFAULT_ICON);
        xIcon.image = "/Templates/Styles/Images/GoogleMarker.png";
        var marker = new GMarker( new GLatLng(options.LatLng[0], options.LatLng[1]), { title: options.title, icon: xIcon } );
        //*******************************************************************************************************************

        // Create a new marker
        //var marker = new GMarker(new GLatLng(options.LatLng[0], options.LatLng[1]), { title: options.title });

        // If it has HTML to pass in, add an event listner for a click
        if (options.HTML) {
            GEvent.addListener(marker, options.markerEvent, function() {
                marker.openInfoWindowHtml(options.HTML);
            });
        }

        // If the marker manager exists, add it
        if ($.gmap.GMarkerManager)
            $.gmap.GMarkerManager.addMarker(marker, options.minZoom, options.maxZoom);
        else
            $.gmap.GMap2.addOverlay(marker); // Overlay marker directly on the map

        // Trigg event when creating marker
        if (options.triggEvent == true)
            GEvent.trigger(marker, options.markerEvent);

        if (options.clickEvent == true) {
            GEvent.addListener(marker, "click", function() {

            });
        }

        // If _callback parameter is a function, return it as a function
        if (typeof _callback == "function") return _callback();
    }

    /**
    * Add multiple markers on the map
    * @param object array _pointObjArr
    * @return void
    */
    $.gmap.addMultipleMarkers = function(_objArr, _options) {
        for (var i = 0; i < _objArr.length; i++) {
            $.gmap.addMarker(_objArr[i]);
        }
    }

    /**
    * Creates an marker manger
    * @param array _options
    * @param function _callback
    * @return void
    */
    $.gmap.createMarkerManager = function(_options, _callback) {
        // Marker options
        var options = $.extend({}, $.gmap.MarkerManagerDefaultOptions, _options);

        // Create a marker manager and attach it to the global GMarkerManager object
        $.gmap.GMarkerManager = new GMarkerManager($.gmap.GMap2, options);

        // If _callback parameter is a function, return it as a function
        if (typeof _callback == 'function') return _callback();
    }

    /**
    * Parses a hitta.se formatted XML and creates marker on the map
    * @param string _xmlStr A string containing XML data
    * @return void
    */
    $.gmap.hittaDotSeXml = function(_options, _callback) {
        // hittaDotSeXml options
        var options = $.extend({}, $.gmap.hittaDotSeXmlDefaultOptions, _options);

        // Parse XML
        var xml = GXml.parse(options.XML);
        var nPoints = xml.documentElement.getElementsByTagName("Point");

        // If we don´t have a MarkerManager we create one
        //if (!$.gmap.GMarkerManager) 
        //$.gmap.createMarkerManager();

        // Set map center (the init value)
        $.gmap.GMap2.setCenter(new GLatLng(0, 0), 0);

        // Create a new bound object
        var bounds = new GLatLngBounds();

        // Add markers and it´s values to the bounds object
        for (var i = 0; i < nPoints.length; i++) {
            $.gmap.addMarker({ LatLng: [nPoints[i].getAttribute("X"), nPoints[i].getAttribute("Y")], HTML: nPoints[i].childNodes[2].firstChild.nodeValue });
            bounds.extend(new GLatLng(nPoints[i].getAttribute("X"), nPoints[i].getAttribute("Y")));
        }

        // Set zoom level depending on bounds
        $.gmap.GMap2.setZoom($.gmap.GMap2.getBoundsZoomLevel(bounds));

        // Set the real map center depending on calculated bounds
        $.gmap.GMap2.setCenter(bounds.getCenter());

        // If _callback parameter is a function, return it as a function
        if (typeof _callback == 'function') return _callback();
    }

    /**
    * Searches for an address and geocode the result
    * @param string address The address to search for
    * @return void
    */
    $.gmap.searchAddress = function(_options, _callback) {
        // Add default options
        var options = $.extend({}, $.gmap.SearchAddressDefaultOptions, _options);

        // Creates a new Geocoder object
        // TODO: Create a Geocoder method and check if that exists before creating a new one
        var geocoder = new GClientGeocoder();

        // Geocode the address
        geocoder.getLatLng(options.address, function(point) {
            if (!point)
                alert('Destinationen kunde inte hittas');
            else {
                if (options.autoZoomCenter && options.mapZoom == null) {
                    // Create a new bound object and add the coordinates
                    var bounds = new GLatLngBounds();
                    bounds.extend(point);

                    // Set zoom level depending on bounds
                    $.gmap.GMap2.setZoom($.gmap.GMap2.getBoundsZoomLevel(bounds));

                    // Set the real map center depending on calculated bounds
                    $.gmap.GMap2.setCenter(bounds.getCenter());
                } else {
                    $.gmap.GMap2.setCenter(point);
                }

                if (options.mapZoom != null)
                    $.gmap.GMap2.setZoom(options.mapZoom);

                $.gmap.addMarker({ LatLng: [point.y, point.x], HTML: options.HTML, triggEvent: true });
            }

            // If _callback parameter is a function, return it as a function
            if (typeof _callback == 'function') return _callback(options, point);
        });
    }

    /**
    * The gmap-function.
    * @param string _method
    * @param array _options
    * @return void
    */
    $.fn.gmap = function(_method, _options, _callback) {
        return this.each(function() {
            // The init method
            if (_method == "init") {
                new $.gmap.init(this, _options, _callback);
            }
            // If init not found so try find other method
            else {
                try {
                    new $.gmap[_method](_options, _callback);
                }
                catch (err) {
                    alert('Kunde inte hitta funktionen "' + _method + '"');
                }
            } // End if
        }); // End this.each
    } // End $.fn.gmap

})(jQuery);
