/*
 * LINGUIST.LLMAP.Service
 * Written by Joshua M. Thompson <joshua@linguistlist.org>
 *
 * This class encapsulates the functionality of a 'service',
 * which is a group of related layers that together make up
 * a map.
 */

LINGUIST.LLMAP.Service = Ext.extend(Ext.util.Observable, {
    url: null,
    service: null,
    layers: null,

    projection: 4326,
    units: 'degrees',

    isPermanent: false,

    visible: true,

    constructor: function(config) {
        LINGUIST.LLMAP.Service.superclass.constructor.call(this, config);

        Ext.apply(this, config);

        this.addEvents('setvisible', 'update');
    },

    getFilterList: function() {
        var list = [];

        for (var i = 0 ; i < this.layers.length ; i++) {
            var layer = this.layers[i];

            if (layer.visible) {
                var filter = layer.filter;

                if (filter == null) {
                    filter = 'INCLUDE';
                }

                list.push(filter);
            }
        }

        return list.join(';');
    },

    getLayerList: function() {
        var list = [];

        for (var i = 0 ; i < this.layers.length ; i++) {
            var layer = this.layers[i];

            if (layer.visible) {
                list.push(layer.id);
            }
        }

        return list.join(',');
    },

    getStyleList: function() {
        var list = [];

        for (var i = 0 ; i < this.layers.length ; i++) {
            var layer = this.layers[i];

            if (layer.visible) {
                list.push(layer.style);
            }
        }

        return list.join(',');
    },

    getLegendGraphic: function(layer, scale) {
        return '';
    },

    setVisible: function(visible) {
        this.fireEvent('setvisible', this, this.visible, visible)
        
        this.visible = visible;
        
        this.updateLayers();
    },

    updateLayers: function() {
        var layers = this.getLayerList();

        if (layers == '') {
            this.map_layer.setVisibility(false);
        }
        else {
            this.map_layer.mergeNewParams({
                layers: layers,
                styles: this.getStyleList(),
                cql_filter: this.getFilterList()
	        });

            this.map_layer.setVisibility(this.visible);
        }

        this.fireEvent('update', this);
    }
});

LINGUIST.LLMAP.IMSService = Ext.extend(LINGUIST.LLMAP.Service, {
    constructor: function(config) {
        LINGUIST.LLMAP.IMSService.superclass.constructor.call(this, config);

        this.map_layer = new OpenLayers.Layer.WMS(
            this.canonical_name,
            '/services/' + this.id + '/wms?',
            {
                layers: this.getLayerList(),
                styles: this.getStyleList(),
                cql_filter: this.getFilterList(),
                format: 'image/png8',
                transparent: true
            },
            {
                opacity: this.opacity / 100,
                ratio: 1,
                singleTile: true
            }
        );
    },

    getLegendGraphic: function(layer, scale) {
        if (layer.legend_url) {
            return layer.legend_url;
        }
        else {
            return '/services/' + this.id + '/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetLegendGraphic&FORMAT=image/png&LAYER=' + layer.id;
        }
    }
});

LINGUIST.LLMAP.ProjectService = Ext.extend(LINGUIST.LLMAP.Service, {
});

LINGUIST.LLMAP.WMSService = Ext.extend(LINGUIST.LLMAP.Service, {
    constructor: function(config) {
        LINGUIST.LLMAP.WMSService.superclass.constructor.call(this, config);

        if (this.url.match(/maggie.linguistlist.org\/geoserver\/wms/)) {
            this.legend_options = [ 'forceLabels:on', 'fontName:Arial Unicode MS', 'fontSize:12', 'fontStyle:normal', 'fontAntiAliasing:true' ];
        }

        this.map_layer = new OpenLayers.Layer.WMS(
            this.canonical_name,
            this.url,
            {
                layers: this.getLayerList(),
                styles: this.getStyleList(),
                cql_filter: this.getFilterList(),
                format: 'image/png',
                tiled: true,
                transparent: true
            },
            {
                ratio: 1,
                singleTile: true
            }
        );
    },

    getLegendGraphic: function(layer, scale) {
        var style = layer.style;

        if (style == null) {
            style = '';
        }

        var url = this.url + 'SERVICE=WMS&VERSION=1.1.1&REQUEST=GetLegendGraphic&FORMAT=image/png&LAYER=' + layer.id + '&STYLE=' + style;

/*
        if (scale != null) {
            url = url + '&SCALE=' + scale;
        }
*/

        if (this.legend_options != null) {
            url = url + '&LEGEND_OPTIONS=' + this.legend_options.join(';');
        }

        return url;
    }
});

LINGUIST.LLMAP.SatelliteBaseMap = Ext.extend(LINGUIST.LLMAP.Service, {
    layers: [],

    constructor: function(config) {
        LINGUIST.LLMAP.SatelliteBaseMap.superclass.constructor.call(this, config);

        this.map_layer = new OpenLayers.Layer.WMS(
            'Satellite',
            'http://maggie.linguistlist.org/geoserver/gwc/service/wms',
            {
                layers: 'bluemarble-500m',
                format: 'image/jpeg',
                tiled: true
            },
            {
                isBaseLayer: true,
                projection: new OpenLayers.Projection('EPSG:4326'),
                units: 'degrees',
                numZoomLevels: 14,
                maxResolution: 0.703125,
                maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
                transitionEffect: 'resize',
                wrapDateLine: true
            }
        );
    }
});

LINGUIST.LLMAP.SatelliteBaseMapMercator = Ext.extend(LINGUIST.LLMAP.Service, {
    layers: [],

    constructor: function(config) {
        LINGUIST.LLMAP.SatelliteBaseMapMercator.superclass.constructor.call(this, config);

        this.map_layer = new OpenLayers.Layer.WMS(
            'Satellite Mercator',
            'http://maggie.linguistlist.org/geoserver/gwc/service/wms',
            {
                layers: 'bluemarble-500m',
                format: 'image/jpeg',
                tiled: true
            },
            {
                isBaseLayer: true,
                projection: new OpenLayers.Projection('EPSG:900913'),
                units: 'm',
                numZoomLevels: 14,
                maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
                maxResolution: 156543.0339,
                sphericalMercator: true,
                transitionEffect: 'resize',
                wrapDateLine: true
            }
        );
    }
});

LINGUIST.LLMAP.VectorBaseMap = Ext.extend(LINGUIST.LLMAP.Service, {
    constructor: function(config) {
        LINGUIST.LLMAP.VectorBaseMap.superclass.constructor.call(this, config);

        this.map_layer = new OpenLayers.Layer.WMS(
            'Map',
            'http://maggie.linguistlist.org/geoserver/gwc/service/wms',
            {
                layers: 'vector-basemap',
                format: 'image/png8',
                tiled: true
            },
            {
                isBaseLayer: true,
                projection: new OpenLayers.Projection('EPSG:4326'),
                units: 'degrees',
                numZoomLevels: 14,
                maxResolution: 0.703125,
                maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
                transitionEffect: 'resize',
                wrapDateLine: true
            }
        );
    }
});

LINGUIST.LLMAP.BaseMapOverlay = Ext.extend(LINGUIST.LLMAP.WMSService, {
    canonical_name: 'Base Map',
    url: 'http://maggie.linguistlist.org/geoserver/wms?',

    legend_options: [ 'forceLabels:on', 'fontName:Arial Unicode MS', 'fontSize:12', 'fontStyle:normal', 'fontAntiAliasing:true' ],

    alwaysOnTop: true,
    isPermanent: true,

    layers: [
        {
            id: 'llmap:DCW_BUILTUP',
            name: 'Urbanized Areas',
            style: 'built-up-area',
            show_legend: true,
            visible: false 
        },
        {
            id: 'llmap:DCW_PROVINCES',
            name: 'Province Borders',
            style: 'province-borders',
            show_legend: true,
            visible: false 
        },
        {
            id: 'llmap:DCW_COUNTRIES',
            name: 'Country Borders',
            style: 'country-borders',
            show_legend: true,
            visible: false 
        },
/*
        {
            id: 'llmap:CITIES',
            name: 'Cities',
            style: 'city',
            show_legend: true,
            visible: false
        },
*/
        {
            id: 'llmap:CONTINENTS',
            name: 'Continent Labels',
            style: 'continent-labels',
            visible: false
        },
        {
            id: 'llmap:COUNTRIES',
            name: 'Country Labels',
            style: 'country-labels',
            visible: false
        },
        {
            id: 'llmap:DCW_PROVINCES',
            name: 'Province Labels',
            style: 'province-labels',
            visible: false 
        },
        {
            id: 'llmap:DCW_INLAND_WATER',
            name: 'Inland Water Labels',
            style: 'inland-water-labels',
            visible: false
        },
        {
            id: 'llmap:DCW_OCEANS',
            name: 'Ocean Labels',
            style: 'ocean-labels',
            visible: false
        }
    ]
});
