﻿if (!Poseidon.Controls.Print) {
    Poseidon.Controls.Print = {};
}
if (!Poseidon.Controls.Print.Module) {
    Poseidon.Controls.Print.Module = {};
} 

Poseidon.Controls.Print.AlignTypesEnum = {
    TOP_LEFT: 'top-left',
    TOP: 'top',
    TOP_RIGHT: 'top-right',
    RIGHT: 'right',
    BOTTOM_RIGHT: 'bottom-right',
    BOTTOM: 'bottom',
    BOTTOM_LEFT: 'bottom-left',
    LEFT: 'left',
    CENTER: 'center',
    CUSTOM: 'custom'
}

Poseidon.Controls.Print.MapPrint = Ext.extend(Poseidon.Controls.Print, {

    title: 'Udskriftsopsætning',
    width: 610,
    height: 660,
    //autoHeight: true,
    layout: 'fit',
    resizable: false,
    closable: true,
    modal: true,
    closeAction: 'close',
    autoScroll: true,
    collapsible: false,
    printURL: '/Webservices/Print.asmx/PrintGIS34',

    initComponent: function () {
        var templateStore = new Ext.data.JsonStore({
            proxy: new Ext.data.HttpProxy({
                url: '/Webservices/Print.asmx/GetTemplateList',
                jsonData: {
                    'controlID': this.controlId
                }, //for FF
                method: 'post',
                headers:
                {
                    'Content-Type': 'application/json;charset=utf-8'
                }
            }),
            autoLoad: true,
            idIndex: 0,
            root: 'd.List',
            totalProperty: 'd.Count',
            idProperty: 'id',
            fields:
            [
                'id',
                'name'
            ],
            listeners:
            {
                load: function (store, records, options) {
                    if (records.length > 0) {
                        var record = records[0];
                        this.comboTemplates.setValue(record.get('name'));
                        //Ext.getCmp('poseidon-controls-print-combo-templates').setValue(record.get('name'));
                        this.fetchTemplate(record.get('id'));
                    } else {
                        Ext.MessageBox.show({
                            msg: 'Der er opstået en uventet fejl. Der blev ikke fundet nogen printskabeloner.',
                            buttons: Ext.MessageBox.OK,
                            icon: Ext.MessageBox.ERROR
                        });
                    }
                },
                scope: this
            }
        });

        var comboTemplates = new Ext.form.ComboBox({
            text: 'Skabelon',
            //id: 'poseidon-controls-print-combo-templates',
            hideLabel: true,
            width: 200,
            typeAhead: true,
            triggerAction: 'all',
            forceSelection: true,
            lazyRender: true,
            mode: 'local',
            store: templateStore,
            valueField: 'id',
            displayField: 'name',
            emptyText: 'Vælg en skabelon',
            listEmptyText: 'Ingen skabeloner',
            listeners: {
                select: function (combo, record, index) {
                    this.fetchTemplate(record.get('id'));
                },
                scope: this
            }
        });

        var comboPaperSizes = new Ext.form.ComboBox({
            //id: 'poseidon-controls-print-combo-size',
            hideLabel: true,
            width: 70,
            typeAhead: true,
            triggerAction: 'all',
            forceSelection: true,
            lazyRender: true,
            mode: 'local',
            store: new Ext.data.JsonStore({
                proxy: new Ext.data.HttpProxy({
                    url: '/Webservices/Print.asmx/GetPaperSizeList',
                    jsonData: {
                        'controlID': this.controlId
                    }, //for FF
                    method: 'post',
                    headers:
                    {
                        'Content-Type': 'application/json;charset=utf-8'
                    }
                }),
                autoLoad: true,
                idIndex: 0,
                root: 'd.List',
                totalProperty: 'd.Count',
                idProperty: 'id',
                fields:
                [
                    'id',
                    'name',
                    'width',
                    'height'
                ],
                listeners:
                {
                    load: function (store, records, options) {
                        if (records.length <= 0) {
                            Ext.MessageBox.show({
                                msg: 'Der er opstået en uventet fejl. Der blev ikke fundet nogen papirformater.',
                                buttons: Ext.MessageBox.OK,
                                icon: Ext.MessageBox.ERROR
                            });
                        }
                    },
                    scope: this
                }
            }),
            valueField: 'id',
            displayField: 'name',
            emptyText: 'Papirformat',
            listEmptyText: 'Ingen papirformater',
            listeners: {
                select: function (combo, record, index) {
                    // Get the scales.
                    var scales = this.comboMapScales.getScales();
                    //var scales = Ext.getCmp('poseidon-controls-print-combo-scales').getScales();

                    // Get the paper size.
                    var paperWidth = record.get('width');
                    var paperHeight = record.get('height');

                    if (scales.length > 0 && paperWidth && paperHeight && this.moduleManager) {
                        // Reset the scales on the map.
                        this.moduleManager.resetScales(record.get('width'), record.get('height'), scales);
                        // Rezoom the map.
                        this.updateMapEvents();
                        //this.doLayout();
                    }
                },
                scope: this
            }
        });

        var comboMapScales = new Ext.form.ComboBox({
            //id: 'poseidon-controls-print-combo-scales',
            hideLabel: true,
            width: 100,
            typeAhead: true,
            triggerAction: 'all',
            forceSelection: true,
            lazyRender: true,
            mode: 'local',
            store: new Ext.data.JsonStore({
                proxy: new Ext.data.HttpProxy({
                    url: '/Webservices/Print.asmx/GetMapScaleList',
                    jsonData: {
                        'controlID': this.controlId
                    }, //for FF
                    method: 'post',
                    headers:
                    {
                        'Content-Type': 'application/json;charset=utf-8'
                    }
                }),
                autoLoad: true,
                idIndex: 0,
                root: 'd.List',
                totalProperty: 'd.Count',
                idProperty: 'id',
                fields:
                [
                    'id',
                    'name',
                    'value'
                ],
                listeners:
                {
                    load: function (store, records, options) {
                        if (records.length <= 0) {
                            Ext.MessageBox.show({
                                msg: 'Der er opstået en uventet fejl. Der blev ikke fundet nogen målestoksforhold.',
                                buttons: Ext.MessageBox.OK,
                                icon: Ext.MessageBox.ERROR
                            });
                        }
                    },
                    scope: this
                }
            }),
            valueField: 'name',
            displayField: 'name',
            emptyText: 'Vælg et målestoksforhold',
            listEmptyText: 'Ingen målestoksforhold',
            listeners: {
                select: function (combo, record, index) {
                    if (this.moduleManager.map) {
                        var printMap = this.moduleManager.map;

                        var scale = this.moduleManager.getCorrectedScale(record.get('value'));

                        // Zoom the map to the chosen scale.
                        printMap.zoomToScale(scale, true);
                    }
                },
                scope: this
            },
            getScales: function () {
                // Extract all the scales.
                var scales = [];
                this.store.each(function (record) {
                    scales.push(record.get('value'));
                });

                return scales;
            }
        });

        var printPage = new Ext.Container({
            layout: 'absolute'
        });

        var config = {
            comboTemplates: comboTemplates,
            comboPaperSizes: comboPaperSizes,
            comboMapScales: comboMapScales,
            printPage: printPage,
            moduleManager: null,
            items: [printPage],
            tbar: new Ext.Toolbar({
                items:
                [
                    {
                        iconCls: 'icon-printer',
                        handler: this.print,
                        scope: this
                    }, '-', {
                        iconCls: 'icon-application-form-edit',
                        text: 'Vis på print',
                        id: 'poseidon-controls-print-menu-settings',
                        menu:
                        {
                            xtype: 'menu',
                            items:
                            [
                                {
                                    text: 'text'
                                }
                            ]
                        }
                    }, '-',
                    comboTemplates,
                    comboPaperSizes,
                    '->',
                    comboMapScales
                ]
            })
        }

        Ext.apply(this, Ext.apply(this.initialConfig, config));

        // Config object has already been applied to 'this' so properties can 
        // be overriden here or new properties (e.g. items, tools, buttons) 
        // can be added, eg:

        // Call parent (required)
        Poseidon.Controls.Print.MapPrint.superclass.initComponent.apply(this, arguments);
    },

    /**
    * Private
    */
    print: function () {
        this.executePrint({
            data: this.getObjects()
        });
    },

    loadTemplate: function () {
        // Get the scales.
        var scales = this.comboMapScales.getScales();
        //var scales = Ext.getCmp('poseidon-controls-print-combo-scales').getScales();

        // Get the paper size.
        var combo = this.comboPaperSizes; //Ext.getCmp('poseidon-controls-print-combo-size');
        var index = combo.getStore().findExact('name', combo.getValue());
        var paperWidth, paperHeight;
        if (index >= 0) {
            var record = combo.getStore().getAt(index);
            paperWidth = record.get('width');
            paperHeight = record.get('height');
        }

        if (scales.length > 0 && paperWidth && paperHeight && this.moduleManager) {
            this.moduleManager.loadTemplate(paperWidth, paperHeight, scales);

            var page = this.moduleManager.pageModule;

            //this.add(this.printPage);
            this.printPage.add(page);

            // Layout the page to get a size for it.
            this.doLayout();

            // Add the map module.
            page.add(this.moduleManager.mapModule);

            // Add the rest of the modules.
            for (var index = 0; index < this.moduleManager.items.length; index++) {
                page.add(this.moduleManager.items[index]);
            }

            // Layout the modules.
            this.doLayout();

            // Add all the modules to the combo.
            var control = Ext.getCmp('poseidon-controls-print-menu-settings');
            control.menu.removeAll(true);
            for (var index = 0; index < this.moduleManager.items.length; index++) {
                control.menu.add(
                {
                    text: this.moduleManager.items[index].module_title,
                    checked: true,
                    module: this.moduleManager.items[index],
                    checkHandler: function (item, checked) {
                        item.module.setVisible(checked);
                        item.module.visible = checked;
                    },
                    scope: this
                });
            }

            this.moduleManager.map.events.register("moveend", this, this.updateScaleCombo.bind(this));
            this.moduleManager.map.zoomToExtent(map.getExtent());

            // Hide the loading message.
            Ext.MessageBox.hide();
        }
    },

    updateMapEvents: function () {
        var combo = this.comboMapScales; // Ext.getCmp('poseidon-controls-print-combo-scales');
        var index = combo.getStore().findExact('name', combo.getValue());
        var value = null;
        if (index >= 0) {
            value = combo.getStore().getAt(index).get('value');
        }
        var scale = this.moduleManager.getCorrectedScale(value);
        this.moduleManager.map.zoomToScale(scale, true);
    },

    fetchTemplate: function (templateId) {
        if (this.moduleManager) {
            this.moduleManager.destroy();
            this.moduleManager = null;
        }

        // Remove all items in the window.
        this.printPage.removeAll(true);

        Ext.MessageBox.show({
            msg: 'Forbereder vis udskrift...',
            width: 300,
            wait: true,
            waitConfig: { interval: 200 }
        });

        Ext.Ajax.request({
            url: '/Webservices/Print.asmx/GetTemplate',
            jsonData:
            {
                'templateID': templateId
            },
            method: 'POST',
            scope: this,
            success: function (response, opts) {
                // Extract the response.
                response = Ext.decode(response.responseText).d;

                // Create a module manager object.
                this.moduleManager = new Poseidon.Controls.Print.ModuleManager(response);

                // Reset the print to match the new template.
                this.resetPrint();
            },
            failure: function (response, opts) {
                Ext.MessageBox.show({
                    msg: 'Forberedelse af vis udskrift mislykkedes',
                    buttons: Ext.MessageBox.OK,
                    icon: Ext.MessageBox.ERROR
                });
            }
        });
    },

    initializeMap: function () {
        var printMap = new OpenLayers.Map('', {
            projection: map.projection,
            units: map.units,
            maxExtent: map.maxExtent,
            //minResolution: map.minResolution,
            //maxResolution: map.maxResolution,
            //minScale: scales[scales.length - 1],
            //maxScale: scales[0],
            //resolution: map.resolution,
            //resolution: resolutions,
            scales: [500000, 250000, 100000, 75000, 50000, 25000, 10000, 5000, 2000, 1000, 500],
            //numZoomLevels: scales.length,
            restrictedExtent: map.restrictedExtent,
            //zoom: map.zoom,
            controls: [
                new OpenLayers.Control.Navigation()
            ]
        });

        // Add the visible layers to the new map.
        for (var layerIndex = 0; layerIndex < map.layers.length; layerIndex++) {
            if (map.layers[layerIndex].visibility) {
                printMap.addLayer(map.layers[layerIndex].clone());
            }
        }

        return printMap;
    },

    updateScaleCombo: function () {
        var printMap = this.moduleManager.map;
        var scale = Math.round(printMap.getScale());
        if (scale) {
            var control = this.comboMapScales; // Ext.getCmp('poseidon-controls-print-combo-scales');
            var store = control.getStore();
            var record = store.getAt(store.findExact('value', this.moduleManager.getRealScale(scale)));
            if (record) {
                control.setValue(record.get('name'));
            }
        }
    },

    getObjects: function () {
        var data = {};

        if (this.moduleManager) {
            // First get the page.
            data[this.moduleManager.pageModule.getModuleType()] = this.moduleManager.pageModule.getObject();
            //data.push(this.moduleManager.pageModule.getObject());

            // Then the map.
            data[this.moduleManager.mapModule.getModuleType()] = this.moduleManager.mapModule.getObject();
            //data.push(this.moduleManager.mapModule.getObject());

            for (var index = 0; index < this.moduleManager.items.length; index++) {
                // If the module is visible, include it too.
                if (this.moduleManager.items[index].visible === true) {
                    data[this.moduleManager.items[index].getModuleType()] = this.moduleManager.items[index].getObject();
                    //data.push(this.moduleManager.items[index].getObject());
                }
            }
        }

        return data;
    },

    onShow: function () {
        Poseidon.Controls.Print.MapPrint.superclass.onShow.call(this);
    },

    resetPrint: function () {
        var task = new Ext.util.DelayedTask(function () {
            var moduleManagerReady = false;
            var scalesReady = false;
            var sizesReady = false;

            // First criteria.
            if (this.moduleManager) {
                moduleManagerReady = true;
            }

            // Second criteria.
            if (this.comboMapScales.getStore().getCount() > 0) { //Ext.getCmp('poseidon-controls-print-combo-scales').getStore().getCount() > 0) {
                scalesReady = true;
            }

            // Third criteria.
            if (moduleManagerReady === true) {
                // Get the paper combo.                
                var combo = this.comboPaperSizes; // Ext.getCmp('poseidon-controls-print-combo-size');

                // If the store contains any records and the preferred paper size, then good.
                if (combo.getStore().getCount() > 0) {
                    sizesReady = true;
                    if (combo.getStore().findExact('name', this.moduleManager.pageModule.paper_size) >= 0) {
                        combo.setValue(this.moduleManager.pageModule.paper_size);
                    } else if (combo.getStore().findExact('name', 'A4') >= 0) {
                        combo.setValue('A4');
                    } else {
                        combo.setValue(combo.getStore().getAt(0).get('name'));
                    }
                }
            }
            // Check for success
            if (moduleManagerReady === true && scalesReady === true && sizesReady === true) {
                // Callback
                this.loadTemplate();
            } else {
                task.delay(500);
            }
        }, this);
        task.delay(500);
    },

    /**
    * Clean the module manager before destroying this window. 
    *
    * Important due to CompassRose.js which might not be destroyed correctly else?!?
    */
    beforeDestroy: function (component) {
        this.comboTemplates = null;
        this.comboMapScales = null;
        this.comboPaperSizes = null;
        this.printPage = null;

        // Destroy the module manager.
        if (this.moduleManager) {
            this.moduleManager.destroy();
        }
    }
});
