/**
 * Copyright (c) 2008-2011 The Open Planning Project
 * 
 * Published under the BSD license.
 * See https://github.com/opengeo/gxp/raw/master/license.txt for the full text
 * of the license.
 */

/**
 * @requires plugins/Tool.js
 */

/** api: (define)
 *  module = gxp.plugins
 *  class = Print
 */

/** api: (extends)
 *  plugins/Tool.js
 */
Ext.namespace("gxp.plugins");

/** api: constructor
 *  .. class:: Print(config)
 *
 *    Provides an action to print the map.
 */
gxp.plugins.Print = Ext.extend(gxp.plugins.Tool, {
    
    /** api: ptype = gxp_print */
    ptype: "gxp_print",

    /** api: config[printService]
     *  ``String``
     *  URL of the print service.
     */
    printService: null,

    /** api: config[customParams]
     *  ``Object`` Key-value pairs of custom data to be sent to the print
     *  service. Optional. This is e.g. useful for complex layout definitions
     *  on the server side that require additional parameters.
     */
    customParams: null,   

    /** private: method[constructor]
     */
    constructor: function(config) {
        gxp.plugins.Print.superclass.constructor.apply(this, arguments);
    },

    /** api: method[addActions]
     */
    addActions: function() {

        // don't add any action if there is no print service configured
        if (this.printService !== null) {

            var printProvider = new GeoExt.data.PrintProvider({
                url: this.printService,
                customParams: this.customParams,
                autoLoad: false,
                listeners: {
                    beforeprint: function() {
                        // The print module does not like array params.
                        // TODO Remove when http://trac.geoext.org/ticket/216 is fixed.
                        printWindow.items.get(0).printMapPanel.layers.each(function(l) {
                            var params = l.get("layer").params;
                            for(var p in params) {
                                if (params[p] instanceof Array) {
                                    params[p] = params[p].join(",");
                                }
                            }
                        });
                    },
                    loadcapabilities: function() {
                        printButton.initialConfig.disabled = false;
                        printButton.enable();
                    },
                    print: function() {
                        try {
                            printWindow.close();							
                        } catch (err) {
                            // TODO: improve destroy
                        }
                    }
                }
            });

            var actions = gxp.plugins.Print.superclass.addActions.call(this, [{
				hidden: true,
                menuText: locale.labels.print.menuText,
                tooltip: locale.tips.printTooltip,
				text: this.target=="panel6" ? "" : locale.labels.print.menuText,
				//id: "printMapButton",
                iconCls: "gxp-icon-print",
                //disabled: true,
                handler: function() {
                    var supported = getSupportedLayers();
                    if (supported.length > 0) {
                        createPrintWindow.call(this);
                        showPrintWindow.call(this);
                    } else {
                        // no layers supported
                        Ext.Msg.alert(
							locale.messages.printNotAllNotPrintableText,
                            locale.messages.printNonePrintableText
                        );
                    }
                },
                scope: this,
                listeners: {
                    render: function() {
                        // wait to load until render so we can enable on success
                        printProvider.loadCapabilities();
                    }
                }
            }]);

            var printButton = this.actions[0].items[0];
			var menuPrint = this.actions[0].items[this.actions[0].items.length-1];
			menuPrint.setText("");

            var printWindow;

            function destroyPrintComponents() {
                if (printWindow) {
                    // TODO: fix this in GeoExt
                    try {
                        var panel = printWindow.items.first();
                        panel.printMapPanel.printPage.destroy();
                        //panel.printMapPanel.destroy();
                    } catch (err) {
                        // TODO: improve destroy
                    }
                    printWindow = null;
                }
            }

            var mapPanel = this.target.mapPanel;
            function getSupportedLayers() {
                var supported = [];
                mapPanel.layers.each(function(record) {
                    var layer = record.getLayer();
                    if (isSupported(layer)) {
                        supported.push(layer);
                    }
                });
                return supported;
            }

            function isSupported(layer) {
                return (
                    layer instanceof GPOpenLayers.Layer.WMS ||
                    layer instanceof GPOpenLayers.Layer.OSM
                );
            }

            var printlegend = new GeoExt.LegendPanel();
            function createPrintWindow() {
                printWindow = new Ext.Window({
                    title: locale.labels.printPreview.printTitle,
                    modal: true,
                    border: false,
                    resizable: false,
                    width: 600,
                    items: [
                        new GeoExt.ux.PrintPreview({
                            autoHeight: true,
                            mapTitle: locale.labels.printPreview.mapTitle,
                            comment: locale.labels.printPreview.comment,
                            printMapPanel: {
                                map: Ext.applyIf({
                                    controls: [
                                        new GPOpenLayers.Control.Navigation(),
                                        new GPOpenLayers.Control.PanPanel(),
                                        new GPOpenLayers.Control.ZoomPanel(),
                                        new GPOpenLayers.Control.Attribution()
                                    ],
                                    eventListeners: {
                                        preaddlayer: function(evt) {
                                            return isSupported(evt.layer);
                                        }
                                    }
                                }, mapPanel.initialConfig.map),
                                items: [{
                                    xtype: "gx_zoomslider",
                                    vertical: true,
                                    height: 100,
                                    aggressive: true
                                }]
                            },
                            printProvider: printProvider,
                            includeLegend: false,
                            sourceMap: mapPanel,
                            legend: printlegend
                        })
                    ],
                    listeners: {
                        beforedestroy: destroyPrintComponents
                    }
                });
            }

            function showPrintWindow() {
                printWindow.show();

                // measure the window content width by it's toolbar
                printWindow.setWidth(0);
                var tb = printWindow.items.get(0).items.get(0);
                var w = 0;
                tb.items.each(function(item) {
                    if(item.getEl()) {
                        w += item.getWidth();
                    }
                });
                printWindow.setWidth(
                    Math.max(printWindow.items.get(0).printMapPanel.getWidth(),
                    w + 20)
                );
                printWindow.center();
            }

            return actions;
        }
    }

});

Ext.preg(gxp.plugins.Print.prototype.ptype, gxp.plugins.Print);
