(function($) {

    // gsdMaps plugin removes 'Static' from Google Static Maps!
    $.fn.gsdMaps = function(options) {
        
        return this.each(function() {
            
            var base = this;
            base.$el = $(this);
            base.el = this;
            base.$el.data('gsdMaps', base);
    
            // Main function - create dynamic map from static
            base.init = function() {
    
                base.options = $.extend(true, {}, $.fn.gsdMaps.defaultOptions, options);
    
                base.$el.each(function() {
    
                    var $this = $(this),
                        $src = $this.attr('src'),
                        $wrapper = $('<div />').attr(base.options.wrapperAttrs),
                        $mapHolder = $('<div />').attr(base.options.mapHolderAttrs).css(base.options.mapHolderCSS),
                        gMapPars = base.parseParams($src);

                    
                    $this.wrap($wrapper);
                    var $wrapEl = $this.parent();
                    $wrapEl.append($mapHolder);
                    var $mapEl = $this.next();
    
                    $wrapEl.css(base.options.wrapperCSS);
                    $wrapEl.css({'width' : gMapPars.width, 'height' : gMapPars.height});
                    $mapEl.css({'width' : gMapPars.width, 'height' : gMapPars.height});
                    
                    $wrapEl.one('click', function() {
                        // init map
                        
                        var coordinates = new google.maps.LatLng(gMapPars.latitude, gMapPars.longitude),
                            map = new google.maps.Map($mapEl.get(0), { 
                                zoom: gMapPars.zoom, 
                                center: coordinates, 
                                mapTypeId: google.maps.MapTypeId.ROADMAP 
                            });
                    
                        // init markers
                        if (gMapPars.markers) {
                            for (var i=0; i<gMapPars.markers.length; i++) {
                                if(gMapPars.markers[i].icon){
                                    var image = gMapPars.markers[i].icon;
                                }
                                marker = new google.maps.Marker({
                                    position: new google.maps.LatLng(gMapPars.markers[i].latitude, gMapPars.markers[i].longitude),
                                    map: map,
                                    icon: image
                                });
                            }        
                        }

    
                    });
    
                    // load in colorbox
                    if (base.options.colorbox.init === true && typeof($.fn.colorbox) === 'function') {
    
                        $wrapEl.colorbox({inline:true, href:$mapEl.css({'position' : 'static', 'width' : base.options.colorbox.width, 'height' : base.options.colorbox.height})});
                    }
    
                });
    
            };
    
            // private function for debugging
            base.debug = function($obj) {
                if (window.console && window.console.log) {
                    window.console.log($obj);
                }
            };
    
            // basic parameter extraction;
            // however, all of them are strings
            base.extractParams = function(src) {
                var paramStr = src.split('?')[1];
                var params = paramStr.split('&');
                var paramHash = [];
                $.each(params, function(i, val) {
                    var keyVal = val.split('=');
                    paramHash[keyVal[0]] = keyVal[1];
                });
                // basic parameters needed to call Google Maps API;
                // without them the script should fail completely
                var requiredParams = ['center', 'zoom', 'size'];
                for (par in requiredParams) {
                    if (typeof paramHash[requiredParams[par]] !== 'string') {
                        return false;
                    }
                }
                return paramHash;
            };
    
            // parse the extracted parameters 
            // because some of them should be integers, floats or booleans
            base.parseParams = function(src) {
    
                var gMapParams = base.extractParams(src);
    
                for (param in gMapParams) {
                    switch (param) {
                        case 'center':
                            var latLng = gMapParams[param].split(',');
                            gMapParams.latitude = parseFloat(latLng[0]);
                            gMapParams.longitude = parseFloat(latLng[1]);
                            delete gMapParams[param];
                            break;
                        case 'markers':
                            var markers = gMapParams[param].split('|');
                            var markersArr = [];
                            var cnt = 0;
                            $.each(markers, function(i, val) {
                                var markerParams = val.split(',');
                                var markerArr = [];
                                $.each(markerParams, function(j, val) {
                                    switch (j) {
                                        case 0:
                                            var icon = val.split('icon:');
                                            
                                            if(icon[1]){
                                                markerArr.icon = icon[1];
                                            } else {
                                                markerArr.latitude = parseFloat(val);
                                            }
                                            
                                        break;
                                        case 1:
                                            // longitude
                                            markerArr.longitude = parseFloat(val);
                                        break;
                                        case 2:
                                            // color
                                            markerArr.color = val;
                                        break;
                                    }
                                });
                                markersArr[cnt] = markerArr;
                                cnt++;
                            });
                            gMapParams[param] = markersArr;
                            break;
                        case 'zoom':
                            gMapParams[param] = parseInt(gMapParams[param], 10);
                            break;
                        case 'size':
                            var size = gMapParams[param].split('x');
                            gMapParams.width = parseInt(size[0], 10);
                            gMapParams.height = parseInt(size[1], 10);
                            delete gMapParams[param];
                            break;
                        case 'sensor':
                            if (gMapParams[param] === 'true') {
                                gMapParams[param] = true;
                            } else {
                                gMapParams[param] = false;
                            }
                            break;
                    }
                }
                return gMapParams;
            };
            
            // Init gsdMaps if there is anything to run it on (google static image)
            if (base.$el) {

                base.init();

            }


        });
    };


    // default options
    $.fn.gsdMaps.defaultOptions = {
        wrapperAttrs : {
            'class' : 'gsdmap'
        },
        wrapperCSS : {
            'position' : 'relative',
            'overflow' : 'hidden',
            'display'  : 'inline-block',
            '*display' : 'inline',
            '*zoom'    : '1',
            'cursor'   : 'pointer'
        },
        mapHolderAttrs : {
            'class' : 'map_holder'
        },
        mapHolderCSS : {
            'position' : 'absolute',
            'left'     : 0,
            'top'      : 0
        },
        colorbox : {
            'init'     : false,
            'width'    : 800,
            'height'   : 600
        }
    };

})(jQuery);
