/* global Descartes */

var $ = require('jquery');
var _ = require('lodash');

var Utils = Descartes.Utils;
var AbstractInPlace = Descartes.UI.AbstractInPlace;

var AbstractInkMapSetup = require('./AbstractInkMapSetup');

/**
 * Class: Descartes.UI.InkMapSetupInPlace
 * Classe proposant, dans une zone fixe de la page HTML, la saisie des paramètres de mise en page pour l'exportation PDF.
 *
 * Hérite de:
 *  - <Descartes.UI.AbstractInPlace>
 *
 * Evénements déclenchés:
 * choosed - Les paramètres sont saisis et valides.
 */
var Class = Utils.Class(AbstractInPlace, AbstractInkMapSetup, {

    defaultDisplayClasses: {
        globalClassName: 'DescartesPrinterSetupLabelAndValue',
        labelClassName: 'DescartesPrinterSetupLabel',
        inputClassName: 'DescartesPrinterSetupInput',
        textClassName: 'DescartesUIText',
        selectClassName: 'DescartesPrinterSetupSelect',
        fieldSetClassName: 'DescartesPrinterSetupFieldSet',
        legendClassName: 'DescartesPrinterSetupLegend',
        buttonClassName: 'DescartesUIButton',
        errorClassName: 'DescartesJQueryError'
    },
    /**
     * Propriete: errors
     * {Array(String)} Liste des erreurs rencontrés lors des contrôles de surface.
     */
    errors: null,

    /**
     * Propriete: papers
     * {Array(Object)} Objets JSON stockant les propriétés des "papiers" disponibles en cohérence avec la taille de la carte.
     */
    papers: [],

    /**
     * Propriete: size
     * {Integer} Taille des zones de saisie (10 par défaut).
     */
    size: 10,

    /**
     * Constructeur: Descartes.UI.PrinterSetupInPlace
     * Constructeur d'instances
     *
     * Paramètres:
     * div - {DOMElement|String} Elément DOM de la page accueillant le formulaire de saisie.
     * paramsModel - {Object} Modèle de la vue passé par référence par le contrôleur <Descartes.Action.PrinterParamsManager>.
     * options - {Object} Objet optionnel contenant les propriétés à renseigner dans l'instance
     *
     * Options de construction propres à la classe:
     * label - {Boolean} Indicateur pour l'affichage ou non d'un titre pour la zone des paramètres d'impression.
     * optionsPanel - {Objet} Options du panel (voir <Descartes.UI.AbstractInPlaceJQueryUI>).
     */
    initialize: function (div, paramsModel, options) {
        _.extend(this, options);
        AbstractInPlace.prototype.initialize.apply(this, [div, paramsModel, this.EVENT_TYPES, options]);
        AbstractInkMapSetup.prototype.initialize.apply(this, [div, paramsModel, this.EVENT_TYPES, options]);
    },
    /**
     * Methode: draw
     * Construit la zone de la page HTML pour la saisie des paramètres de mise en page.
     */
    draw: function () {
        this.setPapers();
        this.setResolutions();
        this.setProjections();

        var content = '<form id="' + this.id + '" class="form-horizontal">';
        content += this.populateForm();
        content += '<div class="row d-flex justify-content-center">';
        content += '<div style="width: 200px;">';
        content += '<custom-button>' + this.getMessage('BUTTON_MESSAGE') + '</custom-button>';
        content += '<custom-progress></custom-progress>';
        content += '</div>';
        content += '</div>';
        content += '</form>';

        this.renderPanel(content);
        this.registerEvents();

    },
    /**
     * Methode: redraw
     * Reconstruit la zone de la page HTML pour la saisie des paramètres de mise en page en cas de changement de taille de la carte.
     *
     * Paramètres:
     * paramsModel - {Object} Modèle de la vue passé par référence par le contrôleur <Descartes.Action.PrinterParamsManager>.
     */
    redraw: function (paramsModel) {
        this.model = paramsModel;
        this.draw();
    },

    registerEvents: function () {
        var container = document.getElementById(this.id);
        container.addEventListener('submit', event => {
            event.preventDefault();
            this.result = Utils.serializeFormArrayToJson($(event.target).serializeArray());
            this.done();
        });

        if (this.model.previewToggleable) {
        container.querySelector("custom-button").enabled = false;
        container.querySelector("input[name='showPreview']")
            .addEventListener("change", (event) => {
                var visible = event.target.checked;
                this.events.triggerEvent('togglePreview', visible);
                container.querySelector("custom-button").enabled = visible;
            });
        }

        container.querySelectorAll(".toggle-block").forEach(element => {
            element.addEventListener("change", (event) => {
                var blockId = event.target.name;
                var visible = event.target.checked;
                this.events.triggerEvent('toggleBlock', [blockId, visible]);
                this.model[blockId + 'Enabled'] = visible;
            });
        });

        if (this.model.dpiEditable) {
            container.querySelector("select[name='dpi']")
            .addEventListener("change", (event) => {
                this.model.dpi = event.target.value;
            });
        }

        if (this.model.projectionEditable && this.model.displayProjections && this.model.displayProjections.length > 1) {
            container.querySelector("select[name='projectionSelect']")
            .addEventListener("change", (event) => {
                this.model.projection = event.target.value;
            });
        }

        if (this.model.titleToggleable && this.model.titleEditable) {
            container.querySelector("input[name='title']")
            .addEventListener("change", (event) => {
                document.querySelector("#title-input").style.display = event.target.checked ? "block" : "none";
            });
        }

        if (this.model.titleToggleable && this.model.titleEditable) {
            container.querySelector("input[name='title-text']")
            .addEventListener("change", (event) => {
                this.model.title = event.target.value;
            });
        }

        if (this.model.descriptionToggleable && this.model.descriptionEditable) {
            container.querySelector("input[name='description']")
                .addEventListener("change", (event) => {
                    document.querySelector("#description-input").style.display = event.target.checked ? "block" : "none";
                });
        }

        if (this.model.descriptionToggleable && this.model.descriptionEditable) {
            container.querySelector("textarea[name='description-text']")
                .addEventListener("change", (event) => {
                    this.model.description = event.target.value;
                });
        }

        if (this.model.formatEditable) {
            container.querySelector("select[name='paper']")
                .addEventListener("change", (event) => {
                    var code = event.target.value;
                    this.model.format = this.model.enabledFormats.filter(format => format.code === code)[0];
                    this.events.triggerEvent('changePaperSize');
            });
        }

        if (this.model.marginEditable) {
            container.querySelector("input[name='marginTopInput']")
                .addEventListener("change", (event) => {
                    this.model.marginTop = event.target.value;
                    this.events.triggerEvent('changePaperSize');
                });
            container.querySelector("input[name='marginBottomInput']")
                .addEventListener("change", (event) => {
                    this.model.marginBottom = event.target.value;
                    this.events.triggerEvent('changePaperSize');
                });
            container.querySelector("input[name='marginLeftInput']")
                .addEventListener("change", (event) => {
                    this.model.marginLeft = event.target.value;
                    this.events.triggerEvent('changePaperSize');
                });
            container.querySelector("input[name='marginRightInput']")
                .addEventListener("change", (event) => {
                    this.model.marginRight = event.target.value;
                    this.events.triggerEvent('changePaperSize');
                });
        }
    },

    CLASS_NAME: 'Descartes.UI.InkMapSetupInPlace'
});

module.exports = Class;
