/* Create GbgMap namespace */
if(typeof GbgMap == "undefined"){ var GbgMap = {}; }

GbgMap.UI = {
    mapUI: null,
    // Zoom to specified zoom level
    zoom: function (dir) {
        if (dir >= 0 && dir <= 9) {
            GbgMap.API.Actions.zoomTo(dir);
            $('#gs-map-zoom li').removeClass('sel');
            $('#gs-map-zoom li:eq(' + dir + ')').addClass('sel');
        }
    },
    // Display list of search results
	printFeatures: function(features) {
		var hits = ' träffar';
		if(features.length == 1) hits = ' träff';
		$('#gs-map-search .search-results').css('height',$('#gs-map-view').height()).html('<h2>Visar '+features.length+hits+'</h2><ul></ul>');
		for(var i = 0; i < features.length; i++) {
			var header = '<h3 class="type"><a href="#">Namnlöst objekt</a></h3>';
			var ingress = '';
			var body = '';
			if(typeof features[i].header != "undefined") header = '<h3 class="type"><a href="#">'+features[i].header+'</a></h3>';
			if(typeof features[i].ingress != "undefined") ingress = '<p class="meta">'+features[i].ingress+'</p>';
			if(typeof features[i].body != "undefined") body = '<p class="meta">'+features[i].body+'</p>';
			$('#gs-map-search ul').append('<li id="gsfeat-'+features[i].featureId+'">'+
										      header + ingress + body +
										  '</li>');
		}
		$('#gs-map-search h3 a').click(function() {
			var id = $(this).parent().parent().attr('id').split('-')[1];
			GbgMap.API.selectFeatureCallback(id);
			return false;
		});
	},
    // Initialize control for switching background layers
    initBgSwitch: function (active, layers, startLayer) {
        var gsBgSwitch = '';
        if (active && layers.length > 1) {
            gsBgSwitch = $('<div />').attr('id', 'gs-map-layers').html(
				'<h2 class="structural">Välj kartunderlag</h2>' +
				'<ul>' +
				'</ul>'
			);
            var btn = '';
            for (var i = 0; i < layers.length; i++) {
                btn = $('<li />').append(
					$('<a />').attr('href', '#').attr('id', 'gs-bgs-' + layers[i]).html(layers[i]).click(function () {
					    $('#gs-map-layers a').removeClass('sel');
					    GbgMap.API.Actions.changeBackgroundTo($(this).attr('id').split('-')[2]);
					    $(this).addClass('sel');
					    return false;
					})
				);
                if (layers[i] == startLayer) btn.find('a').addClass('sel');
                gsBgSwitch.find('ul').append(btn);
            }
        }
        return gsBgSwitch;
    },
    // Initialize panning controls
    initPan: function (active) {
        var gsMapPan = '';
        if (active) {
            // Create structure
            gsMapPan = $('<div />').attr('id', 'gs-map-pan').html(
				'<h2 class="structural">Panorera</h2>' +
				'<ul>' +
					'<li class="mp-n"><a href="#"><span>N</span>orrut</a></li>' +
					'<li class="mp-s"><a href="#"><span>S</span>öderut</a></li>' +
					'<li class="mp-w"><a href="#"><span>V</span>ästerut</a></li>' +
					'<li class="mp-e"><a href="#"><span>Ö</span>sterut</a></li>' +
				'</ul>'
			);
            // Add click events
            gsMapPan.find('.mp-n a').click(function () {
                GbgMap.API.Actions.panUp();
                return false;
            });
            gsMapPan.find('.mp-s a').click(function () {
                GbgMap.API.Actions.panDown();
                return false;
            });
            gsMapPan.find('.mp-w a').click(function () {
                GbgMap.API.Actions.panLeft();
                return false;
            });
            gsMapPan.find('.mp-e a').click(function () {
                GbgMap.API.Actions.panRight();
                return false;
            });
        }
        return gsMapPan;
    },
    // Initialize zooming controls
    initZoom: function (active) {
        var gsMapZoom = '';
        if (active) {
            // Create structure
            gsMapZoom = $('<div />').attr('id', 'gs-map-zoom').html(
				'<h2 class="structural">Välj zoomnivå</h2>' +
				'<span class="mz-in"><a href="#">Zooma in</a></span>' +
				'<span class="mz-out"><a href="#">Zooma ut</a></span>' +
				'<ol>' +
				    '<li class="mz-1 mz-t">Nivå 1</li>' +
				    '<li class="mz-2">Nivå 2</li>' +
				    '<li class="mz-3">Nivå 3</li>' +
				    '<li class="mz-4 mz-t">Nivå 4</li>' +
				    '<li class="mz-5">Nivå 5</li>' +
				    '<li class="mz-6">Nivå 6</li>' +
				    '<li class="mz-7 mz-t">Nivå 7</li>' +
				    '<li class="mz-8">Nivå 8</li>' +
				    '<li class="mz-9">Nivå 9</li>' +
				    '<li class="mz-10 mz-t">Nivå 10</li>' +
				'</ol>'
			);
            // Add click events
            gsMapZoom.find('.mz-in a').click(function () {
                var curZoom = GbgMap.API.getCurrentZoomLevel();
                if (curZoom < 9) {
                    GbgMap.API.Actions.zoomIn();
                }
                return false;
            });
            gsMapZoom.find('.mz-out a').click(function () {
                var curZoom = GbgMap.API.getCurrentZoomLevel();
                if (curZoom > 0) {
                    GbgMap.API.Actions.zoomOut();
                }
                return false;
            });
            // Handle the slider control
            gsMapZoom.find('li').each(function (i) {
                $(this).mousedown(function (e) {
                    $('body').mousemove(function (e) {
                        var sel = $('#gs-map-zoom li.sel');
                        var index = $('#gs-map-zoom li').index(sel);
                        var xchord = e.pageX;
                        var xpos = sel.offset().left;

                        if ((xchord > (xpos + 19)) && index < 9) {
                            sel.removeClass('sel').next().addClass('sel');
                        } else if ((xchord < xpos) && index > 0) {
                            sel.removeClass('sel').prev().addClass('sel');
                        }
                        return false;
                    }).mouseup(function () {
                        var sel = $('#gs-map-zoom li.sel');
                        GbgMap.UI.zoom($('#gs-map-zoom li').index(sel));
                        $('body').unbind('mousemove').unbind('mouseup');
                    });
                    return false;
                }).click(function () {
                    var sel = $(this);
                    GbgMap.UI.zoom($('#gs-map-zoom li').index(sel));
                    $('body').unbind('mousemove').unbind('mouseup');
                    return false;
                });
            });
        }
        return gsMapZoom;
    },
    // Initialize search listing
    initSearch: function (active) {
        var gsMapSearch = '';
        if (active) {
            gsMapSearch = $('<div />').attr('id', 'gs-map-search').append('<div class="search-results"></div>');
        }
        return gsMapSearch;
    },
    /***********************************************
	
    Generate and render map GUI
	
    ***********************************************/
    init: function (portalConf) {

        // Check portlet configuration and add defaults if key not present
        for (var key in GbgMap.UI.Defaults) {
            if (!portalConf.hasOwnProperty(key)) {
                portalConf[key] = GbgMap.UI.Defaults[key];
            }
        }

        // Create general layout structure
        var gsMap = $('<div />').attr('id', 'gs-map').addClass('cf').attr('tabindex','0').keydown(function(event) {
        	switch(event.keyCode) {
        		case 37: // Left arrow key
        			$('#gs-map-pan .mp-w a').click();
        			event.preventDefault();
        			break;
        		case 38: // Up arrow key
        			$('#gs-map-pan .mp-n a').click();
        			event.preventDefault();
        			break;
        		case 39: // Right arrow key
        			$('#gs-map-pan .mp-e a').click();
        			event.preventDefault();
        			break;
        		case 40: // Down arrow key
        			$('#gs-map-pan .mp-s a').click();
        			event.preventDefault();
        			break;
        		case 107: // Plus key
        			$('#gs-map-zoom .mz-in a').click();
        			event.preventDefault();
        			break;
        		case 109: // Minus key
        			$('#gs-map-zoom .mz-out a').click();
        			event.preventDefault();
        			break;
        	}
		});
        var gsMapView = $('<div />').attr('id', 'gs-map-view');
        var gsMapNav = $('<div />').attr('id', 'gs-map-nav');
        var gsMapFooter = '';
        var gsMapCanvas = $('<div />').attr('id', 'gs-map-canvas').html('<div id="gs-main-map"></div>');

        // Set configuration
        if (GbgMap.UI.Layouts.hasOwnProperty(portalConf.layoutType)) {
            var layout = portalConf.layoutType;
        } else {
            var layout = GbgMap.UI.Defaults.layoutType;
        }
        var container = $('#' + portalConf.mapDiv);
        if (portalConf.width > 0) container.css('width', portalConf.width);
        if (portalConf.height > 0) gsMapCanvas.css('height', portalConf.height);

        // Make place for search bar if active
        if (GbgMap.UI.Layouts[layout].search) {
            gsMapNav.css('margin-left', 260);
            gsMapCanvas.css('margin-left', 260);
        }
        if (GbgMap.UI.Layouts[layout].footer) {
            gsMapFooter = $('<div />').attr('id', 'gs-map-footer').html(
				'<a class="print-link" href="#printnow" onclick="window.print(); return false;">Skriv ut...</a>'
			);
        }

        // Put it all together
        gsMapNav.append(this.initBgSwitch(GbgMap.UI.Layouts[layout].bgswitch, portalConf.bgLayers, portalConf.startBgLayer));
        gsMapNav.append(this.initPan(GbgMap.UI.Layouts[layout].pan));
        gsMapNav.append(this.initZoom(GbgMap.UI.Layouts[layout].zoom));
        if (gsMapNav.is(':empty')) gsMapNav = '';
        gsMapView.append(gsMapNav).append(gsMapCanvas);
        gsMap.append(this.initSearch(GbgMap.UI.Layouts[layout].search)).append(gsMapView).append(gsMapFooter);

        // Inject into DOM
        this.mapUI = gsMap;
        container.html(this.mapUI);

        // Init OpenLayers
        portalConf.mapDiv = 'gs-main-map';

        GbgMap.createConfiguration(portalConf, GbgMap.Resources, function (config) {

            GbgMap.API.initializeMap(config, function () {

                // Add callback for updating of zoom bar when zooming with click or scroll
                GbgMap.API.Actions.onZoomEnd(function () {
                    var lvl = GbgMap.API.getCurrentZoomLevel();
                    $('#gs-map-zoom li').removeClass('sel');
                    $('#gs-map-zoom li:eq(' + lvl + ')').addClass('sel');
                });

                // Zoom to first zoom level
                GbgMap.API.Actions.zoomTo(portalConf.startZoomLevel);

                var dataset = GbgMap.getDatasetById(portalConf.featureIdsCollection.datasetId);

                var startLayer = new GbgMap.API.ActiveLayerWFS({
                    id: dataset.layerName,
                    featureNS: dataset.featureNS,
                    url: dataset.url,
                    name: dataset.name,
                    iconUrl: dataset.iconUrl,
                    filter: dataset.filter,
                    fields: dataset.fields,
                    idField: dataset.fields["featureId"],
                    ingressField: dataset.fields["ingress"],
                    headerField: dataset.fields["header"],
                    bodyField: dataset.fields["body"],
                    linkField: dataset.fields["link"]
                });

                GbgMap.API.addActiveLayer(startLayer);

                GbgMap.API.Search.searchByIDs(dataset.name, portalConf.featureIdsCollection.ids, function (searchResult) {

                    startLayer.addFeatures(searchResult);

                    GbgMap.UI.printFeatures(searchResult);
                });

                GbgMap.API.selectFeatureCallback = function (featureId) {

                    var feature = startLayer.getFeatureById(featureId);

                    var header = '<p class="heading"><strong>Namnlöst objekt</strong></p>';
					var ingress = '';
					var body = '';
					var link = '';
					if(typeof feature.header != "undefined") header = '<p class="heading"><strong>'+feature.header+'</strong></p>';
					if(typeof feature.ingress != "undefined") ingress = '<p class="meta">'+feature.ingress+'</p>';
					if(typeof feature.body != "undefined") body = '<p class="body">'+feature.body+'</p>';
					if(typeof feature.link != "undefined") link = '<a href="'+feature.link+'">Mer om '+feature.header+'</a>';

                    //Build html with feature attributes
                    var html = '<div class="gs-map-bubble"> \
	                    <div class="b-h"></div> \
	                    <div class="b-b">'+ingress+header+body+link+
		                    '<a class="btn-close" href="#">Stäng</a> \
	                    </div> \
	                    <div class="b-f"></div> \
                    </div>';

                    GbgMap.API.showPopup(html, feature, function () {
                        $(".btn-close").click(function () {
                            GbgMap.API.hidePopup();
                            $('#gs-map-search li.sel').removeClass('sel');
                            return false;
                        });
                    });
					
					// Select feature in search result list
					$('#gs-map-search li.sel').removeClass('sel');
					$('#gsfeat-'+featureId).addClass('sel');
                }
            });
        });
    }
};

// Supported UI layouts
GbgMap.UI.Layouts = {
	'Full': {
		'bgswitch': true,
		'zoom': true,
		'pan': true,
		'search': true,
		'footer': true
	},
	'Stripped': {
		'bgswitch': false,
		'zoom': false,
		'pan': false,
		'search': false,
		'footer': false
	},
	'NoSearch': {
		'bgswitch': true,
		'zoom': true,
		'pan': true,
		'search': false,
		'footer': true
	}
};

// UI configuration defaults
GbgMap.UI.Defaults = {
    
    //Id for the div where map will be rendered
    mapDiv : "gs-map-container",

    //Width of the map, if zero, no width will be set
    width: 0,

    //Height of the map, if zero, no height will be set
    height: 0,

    layoutType : "Full", /* "Stripped" */
    
    //Specifies whether controls like zoom in/out with mouse scroll should be enabled
    mouseMapControls : true,

    //Background layers available in the map
    bgLayers: ["Karta"],

    //Background layer that is active from start
    startBgLayer: "Karta",

    //Center coordinate for start view of the map
    startXY: "156000,6400000",

    //Zoomlevel for startview of the map
    startZoomLevel: 0,

    
    featureIdsCollection: [],
    
    //List of features with complete attribute values that are ready to be shown on the map
    featureCollection: [],
    
    //List of datasets that search function will search in
    searchLayers: [],

    //List of layers that will 
    publicLayers: [],

    //External url that a complete list of features(featureCollection) can be loaded from
    featureUrl : ""    
};
