// (c) Lightbox Multimedia    http://www.lightbox.ie
// created by Tomek Kaczmarek
// this jquery plugin is following this plugin development pattern:
// http://www.learningjquery.com/2007/10/a-plugin-development-pattern
// version: 1.0.20091102
(function(jQuery){
    // plugin definition
    jQuery.fn.gmap = function(options){
        // build main options before element iteration
        var opts = jQuery.extend({}, jQuery.fn.gmap.defaults, options);
        // iterate and proceed with each matched element
        return this.each(function(){
            var $this = jQuery(this);
            // build element specific options
            var o = jQuery.meta ? jQuery.extend({}, opts, $this.data()) : opts;
            opts['mapnode'] = $this;
            var map = drawMap($this, o);
            $this.data("map", map);
            $this.bind("gmaprepaint", function(){
                refreshMap($this.data("map"));
            });
            if(isFacebox(opts)){
                jQuery(document).bind('reveal.facebox', function(){
                    refreshMap(map);
                });
            }
        });
    };
    // public function as a callback 
    jQuery.fn.gmap.dragendCallback = function(marker){
        //log(marker);
    };
    // private function for refreshing map - for use with tabs and facebox for instance
    function refreshMap(gmapObj){
        gmapObj.checkResize();
    }
    // private function for drawing map
    function drawMap(node, opts){
        var mapnode = node[0];
        var gMap;
        if(GBrowserIsCompatible()){
            if(mapnode){
                // initializing map types
                var mapTypes = opts['mapTypes'];
                if(mapTypes.length == 0){
                    mapTypes = [G_NORMAL_MAP];
                }
                //creating map
                gMap = new GMap2(mapnode,{
                        size: new GSize(opts['width'],opts['height']),
                        mapTypes: mapTypes
                });
                // getting center and setting map
                var center = getCenterLatLng(opts);
                gMap.setCenter(center, opts['zoom']);
                gMap.addControl(new GSmallMapControl());
                if(mapTypes.length > 0){
                    gMap.addControl(new GMapTypeControl());
                }
                //drawing markers
                drawMarkers(gMap, opts);
            }
        }
        return gMap;
    };
    function getCenterLatLng(opts){
        var center = opts['center'];
        var markers = opts['markers'];
        var defaultCenter = new GLatLng(center[0], center[1]);
        if(markers.length > 0){
            var latSum = 0;
            var latCount = 0;
            var lngSum = 0;
            var lngCount = 0;
            for(var i=0; i<markers.length; i++){
                var markersItem = markers[i];
                var latlng   = markersItem['latlng'];
                latSum += latlng[0];
                latCount++;
                lngSum += latlng[1];
                lngCount++;
            }
        return new GLatLng((latSum/latCount), (lngSum/lngCount));
        }
        return defaultCenter;
    }
    function drawMarkers(gMap, opts){
        var markers = opts['markers'];
        var infoWindowContentContainer = [];
        for(var i=0; i<markers.length; i++){
            var markersItem = markers[i];
            var latlng   = markersItem['latlng'];
            var caption = markersItem['caption'];
            var show = markersItem['show'];
            var draggable = markersItem['draggable'];
            var title = markersItem['title'];
            //storing info window content
            infoWindowContentContainer[i] = caption;
            //adding marker, storing index of info window content and creating onclick event
            var marker = new GMarker(new GLatLng(latlng[0], latlng[1]), {title: title, draggable: draggable});
            marker.value = i;
            GEvent.addListener(marker,"click", function() {
                openInfoWindow(gMap, this.getLatLng(), infoWindowContentContainer[this.value], opts);
                //log("addListener(click): marker.value: " + this.value);
            });
            GEvent.addListener(marker, "dragend", function() {
                var fn = opts['dragendCallback'];
                fn(this);
            });
            //adding to map
            gMap.addOverlay(marker);
            if(show){
                openInfoWindow(gMap, marker.getLatLng(), infoWindowContentContainer[marker.value], opts);
            }
            //resizing bounds and zoom
            var bounds = gMap.getBounds();
            bounds.extend(marker.getLatLng());
            gMap.setCenter(bounds.getCenter(), gMap.getBoundsZoomLevel(bounds));
        }
    }
    function openInfoWindow(gMap, latlng, caption, opts){
        gMap.openInfoWindowHtml(latlng, caption);
        if(isFacebox(opts) && jQuery.browser.msie){
            // nasty workaround for IE 
            opts['mapnode'].fadeOut(1);
            opts['mapnode'].fadeIn(1);
        }
    }
    function isFacebox(opts){
        if(opts['facebox']){
            return true;
        }
        return false;
    }
    // private function for logging
    function log($obj){
        if (window.console && window.console.log){
            window.console.log($obj);
        }
    };
    // plugin defaults
    jQuery.fn.gmap.defaults = {
        center:   [53.342225,-6.280468],
        zoom:     16,
        width:    500,
        height:   360,
        mapTypes: [],
        markers:  [],
        facebox:  false,
        dragendCallback: jQuery.fn.gmap.dragendCallback
    };
    // end of closure
})(jQuery);