# -*- coding: utf-8 -*-
"""
/***************************************************************************
 QGIS2APIIDEEDialog
                                 A QGIS plugin
 Complemento que crea un visualizador cartográfico con el contenido del lienzo de QGIS
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2023-12-16
        git sha              : $Format:%H$
        copyright            : (C) 2023 by IngenieroGeomatico
        email                : aurearagon@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

import os
from pathlib import Path
import shutil
import webbrowser
import urllib.parse

from qgis.PyQt import uic
from qgis.PyQt import QtWidgets

from qgis.core import (
    QgsProject, QgsMapLayer, QgsWkbTypes, QgsCoordinateTransform,
    QgsCoordinateReferenceSystem, QgsVectorFileWriter, QgsCoordinateTransformContext,
    QgsMessageLog
)
from qgis.gui import QgsMapCanvas
from qgis.utils import iface, Qgis

from qgis.PyQt import QtGui, QtWidgets, QtCore
from .utilidades import layer_templates

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'QGIS2APIIDEE_dialog_base.ui'))


class QGIS2APIIDEEDialog(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(QGIS2APIIDEEDialog, self).__init__(parent)
        self.setupUi(self)

    def selectFolder(self):
        dialog = QtWidgets.QFileDialog()
        if self.lineEdit_Folder.text().replace(" ", "").replace("—", "_") != "":
            folder_path = dialog.getExistingDirectory(self.lineEdit_Folder, "Selecciona carpeta de salida")
        elif self.lineEdit_Folder_2.text().replace(" ", "").replace("—", "_") != "":
            folder_path = dialog.getExistingDirectory(self.lineEdit_Folder_2, "Selecciona carpeta de salida")
        else:
            folder_path = dialog.getExistingDirectory(None, "Selecciona carpeta de salida")

        if folder_path is None or folder_path == "":
            folder_path = self.lineEdit_Folder.text() or self.lineEdit_Folder_2.text()

        self.lineEdit_Folder.setText(folder_path)
        self.lineEdit_Folder_2.setText(folder_path)
        return folder_path

    def exportMap(self):
        projectSource = "/QGIS2APIIDEE"
        sourceFolder = "/Sources"
        APIFolder = "/API_IDEE"
        APInucleo = "/nucleo"
        APIextension = "/ext"
        APIextension_layerSwitcher = "/layerSwitcher"
        JSFolder = "/JS"
        CSSFolder = "/CSS"
        pluginQGIS2APIIDEE = "/pluginQGIS2APIIDEE"

        exportFolder = self.lineEdit_Folder.text() + projectSource
        exportFolderSources = self.lineEdit_Folder.text() + projectSource + sourceFolder

        exportFolderAPI_nucleo = self.lineEdit_Folder.text() + projectSource + APIFolder + APInucleo
        exportFolderAPI_extension_layerSwitcher = self.lineEdit_Folder.text() + projectSource + APIFolder + APIextension + APIextension_layerSwitcher

        exportJSFolder = self.lineEdit_Folder.text() + projectSource + JSFolder
        exportCSSFolder = self.lineEdit_Folder.text() + projectSource + CSSFolder

        exportPluginQGIS2APIIDEE = self.lineEdit_Folder.text() + projectSource + pluginQGIS2APIIDEE

        if Path(exportFolder).exists():
            shutil.rmtree(exportFolder)

        Path(exportFolder).mkdir(parents=True, exist_ok=True)
        Path(exportFolderSources).mkdir(parents=True, exist_ok=True)

        Path(exportFolderAPI_nucleo).mkdir(parents=True, exist_ok=True)
        Path(exportFolderAPI_extension_layerSwitcher).mkdir(parents=True, exist_ok=True)

        Path(exportJSFolder).mkdir(parents=True, exist_ok=True)
        Path(exportCSSFolder).mkdir(parents=True, exist_ok=True)

        #Copia de API
        shutil.copyfile(
                        os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/nucleo/apiidee.ol.min.css',
                        exportFolderAPI_nucleo + '/apiidee.ol.min.css')
        shutil.copyfile(os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/nucleo/apiidee.ol.min.js',
                        exportFolderAPI_nucleo + '/apiidee.ol.min.js')
        shutil.copyfile(os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/nucleo/configuration.js',
                        exportFolderAPI_nucleo + '/configuration.js')

        #copia de extesiones API-IDEE
        shutil.copyfile(os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/ext/layerSwitcher/layerswitcher.ol.min.css',
                        exportFolderAPI_extension_layerSwitcher + '/layerswitcher.ol.min.css')
        shutil.copyfile(os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/ext/layerSwitcher/layerswitcher.ol.min.js',
                        exportFolderAPI_extension_layerSwitcher + '/layerswitcher.ol.min.js')

        # Obtención de extensiones personalizadas QGIS2APIIDEE
        checkBox_ComparacionMapas = self.checkBox_ComparacionMapas.isChecked()
        if checkBox_ComparacionMapas:
            Path(exportPluginQGIS2APIIDEE).mkdir(parents=True, exist_ok=True)
            shutil.copytree(os.path.dirname(__file__) + '/customPlugins/comparadorMapas',
                            exportPluginQGIS2APIIDEE + '/comparadorMapas', dirs_exist_ok=True)
            shutil.copytree(os.path.dirname(__file__) + '/customPlugins/viglino',
                            exportPluginQGIS2APIIDEE + '/viglino', dirs_exist_ok=True)

        fileMap = exportFolder + '/index.html'
        fileJS = exportJSFolder + '/QGIS2APIIDEE.js'
        fileCSS = exportCSSFolder + '/QGIS2APIIDEE.css'

        tableOfSources = self.tableWidget_capas

        layers = []
        controls = []
        plugins = []
        pluginImports = []

        initialZIndexLayer = 100
        for r in range(tableOfSources.rowCount()):
            layer = {
                'layerSourceType': '',
                'url_path': '',
                'format': '',
                'style': '',
                'nameLayer': '',
                'nameLegend': '',
                'visible': 0,
                'isLocal': 0,
                'dataSourceUri': '',
                'source': '',
                'QGISlayer': '',
                'sourceFolder': sourceFolder,
                'exportFolderSources': exportFolderSources,
                'zIndex': initialZIndexLayer - r
            }

            for c in range(tableOfSources.columnCount()):
                item = tableOfSources.item(r, c)
                if item is None:
                    cell_widget = tableOfSources.cellWidget(r, c)
                    if cell_widget is not None:
                        chk_box = cell_widget.findChild(QtWidgets.QCheckBox).isChecked()
                        if c == 0 and not chk_box:
                            break
                        elif c == 1:
                            layer['visible'] = chk_box
                            continue
                else:
                    text = str(item.text())
                    if c == 3:
                        layer['layerSourceType'] = text
                    elif c == 4:
                        QGISlayer = QgsProject.instance().mapLayersByName(text)[0]
                        layer['QGISlayer'] = QGISlayer
                        layer['nameLegend'] = QGISlayer.name()
                        layer['dataSourceUri'] = QGISlayer.dataProvider().dataSourceUri()
                        layer['source'] = QGISlayer.source()
                        if layer['dataSourceUri'] == '':
                            layer['dataSourceUri'] = layer['source']
                if c == tableOfSources.columnCount() - 1:
                    layers.append(self.JSONLayer2StringLayer(layer))

        layers = list(filter(lambda k: '' != k, layers))
        layers = list(reversed(layers))

        # Controles
      
        if self.checkBox_CapasBase.isChecked():
            controls.append('backgroundlayers')
        if self.checkBox_Rotacion.isChecked():
            controls.append('rotate')
        if self.checkBox_Localizacion.isChecked():
            controls.append('location')
        if self.checkBox_EscalaZoom.isChecked():
            controls.append('scale')
        if self.checkBox_ZoomBotones.isChecked():
            controls.append('panzoom')
        if self.checkBox_ZoomBarrita.isChecked():
            controls.append('panzoombar')
        if self.checkBox_EscalaGrafica.isChecked():
            controls.append('scaleline')

        # Plugins
        if self.checkBox_SelectorCapas.isChecked():
            headerImports = """
                <link href="./API_IDEE/ext/layerSwitcher/layerswitcher.ol.min.css" rel="stylesheet" />
                <script type="text/javascript" src="./API_IDEE/ext/layerSwitcher/layerswitcher.ol.min.js"></script>
            """
            stringplugin = """
                const mp_selectorCapa = new IDEE.plugin.Layerswitcher({
                        position: 'TR',
                        collapsed: false,
                        collapsible: true,
                        https: true,
                        http: true,
                        showCatalog: true,
                        displayLabel: false,
                        addLayers: true,
                        statusLayers: true,
                        modeSelectLayers: 'eyes',
                        isMoveLayers: true,
                        tools: ['transparency', 'legend', 'zoom', 'information', 'style', 'delete']
                    });
                mapajs.addPlugin(mp_selectorCapa);
            """
            pluginImports.append(headerImports)
            plugins.append(stringplugin)

        extentQGIS = iface.mapCanvas().extent()
        CRSQGIS = QgsProject.instance().crs()
        ct = QgsCoordinateTransform(CRSQGIS, QgsCoordinateReferenceSystem('EPSG:3857'), QgsProject.instance())
        bounds_crs = ct.transformBoundingBox(extentQGIS)
        bbox = [bounds_crs.xMinimum(), bounds_crs.yMinimum(), bounds_crs.xMaximum(), bounds_crs.yMaximum()]

        with open(fileJS, 'w') as filetowrite:
            filetowrite.write(self.CreateJS(bbox, layers, controls, plugins))

        with open(fileCSS, 'w') as filetowrite:
            filetowrite.write(self.CreateCSS())

        with open(fileMap, 'w') as filetowrite:
            filetowrite.write(
                self.CreateHTML( 
                    headerImports=pluginImports, 
                    checkBox_ComparacionMapas= checkBox_ComparacionMapas
                )
            )

        webbrowser.open(fileMap, new=2)
        self.close()
        return

    def exportMap_3D_2D(self):
        projectSource = "/QGIS2APIIDEE"
        sourceFolder = "/Sources"
        APIFolder = "/API_IDEE"
        APInucleo = "/nucleo"
        APIextension = "/ext"
        APIextension_layerSwitcher = "/layerSwitcher"
        JSFolder = "/JS"
        CSSFolder = "/CSS"
        pluginQGIS2APIIDEE = "/pluginQGIS2APIIDEE"

        exportFolder = self.lineEdit_Folder.text() + projectSource
        exportFolderSources = self.lineEdit_Folder.text() + projectSource + sourceFolder

        exportFolderAPI_nucleo = self.lineEdit_Folder.text() + projectSource + APIFolder + APInucleo
        exportFolderAPI_extension_layerSwitcher = self.lineEdit_Folder.text() + projectSource + APIFolder + APIextension + APIextension_layerSwitcher

        exportJSFolder = self.lineEdit_Folder.text() + projectSource + JSFolder
        exportCSSFolder = self.lineEdit_Folder.text() + projectSource + CSSFolder

        exportPluginQGIS2APIIDEE = self.lineEdit_Folder.text() + projectSource + pluginQGIS2APIIDEE

        if Path(exportFolder).exists():
            shutil.rmtree(exportFolder)

        Path(exportFolder).mkdir(parents=True, exist_ok=True)
        Path(exportFolderSources).mkdir(parents=True, exist_ok=True)

        Path(exportJSFolder).mkdir(parents=True, exist_ok=True)
        Path(exportCSSFolder).mkdir(parents=True, exist_ok=True)

        #Copia de API
        shutil.copytree(
                        os.path.dirname(__file__) + '/src_API-IDEE/v_1.0.0/nucleo',
                        exportFolderAPI_nucleo)

        fileMap = exportFolder + '/index.html'
        fileJS = exportJSFolder + '/QGIS2APIIDEE.js'
        fileCSS = exportCSSFolder + '/QGIS2APIIDEE.css'

        tableOfSources = self.tableWidget_capas

        layers = []
        controls = []
        plugins = []
        pluginImports = []

        initialZIndexLayer = 100
        for r in range(tableOfSources.rowCount()):
            layer = {
                'layerSourceType': '',
                'url_path': '',
                'format': '',
                'style': '',
                'nameLayer': '',
                'nameLegend': '',
                'visible': 0,
                'isLocal': 0,
                'dataSourceUri': '',
                'source': '',
                'QGISlayer': '',
                'sourceFolder': sourceFolder,
                'exportFolderSources': exportFolderSources,
                'zIndex': initialZIndexLayer - r
            }

            for c in range(tableOfSources.columnCount()):
                item = tableOfSources.item(r, c)
                if item is None:
                    cell_widget = tableOfSources.cellWidget(r, c)
                    if cell_widget is not None:
                        chk_box = cell_widget.findChild(QtWidgets.QCheckBox).isChecked()
                        if c == 0 and not chk_box:
                            break
                        elif c == 1:
                            layer['visible'] = chk_box
                            continue
                else:
                    text = str(item.text())
                    if c == 3:
                        layer['layerSourceType'] = text
                    elif c == 4:
                        QGISlayer = QgsProject.instance().mapLayersByName(text)[0]
                        layer['QGISlayer'] = QGISlayer
                        layer['nameLegend'] = QGISlayer.name()
                        layer['dataSourceUri'] = QGISlayer.dataProvider().dataSourceUri()
                        layer['source'] = QGISlayer.source()
                        if layer['dataSourceUri'] == '':
                            layer['dataSourceUri'] = layer['source']
                if c == tableOfSources.columnCount() - 1:
                    layers.append(self.JSONLayer2StringLayer(layer))

        layers = list(filter(lambda k: '' != k, layers))
        layers = list(reversed(layers))


        if self.checkBox_selectorCapa_2D3D.isChecked():
            headerImports = """

                <link href="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/selectorCapas3D/ext_layerSwitcher.css" rel="stylesheet" />
                <script type="text/javascript" src="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/selectorCapas3D/ext_layerSwitcher.js"></script>

            """
            pluginImports.append(headerImports)
            stringplugin = """
            mapajs.addPlugin(pluginCapasSuperpuestasFunc());
            """
            plugins.append(stringplugin)
        
        if self.checkBox_capaBase_2D3D.isChecked():
            headerImports = """

                <link href="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/selectorCapas3D/ext_backgorundLayers.css" rel="stylesheet" />
                <script type="text/javascript" src="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/selectorCapas3D/ext_backgorundLayers.js"></script>

            """
            pluginImports.append(headerImports)
            stringplugin = """
            mapajs.addPlugin(pluginCapasBaseFunc());
            """
            plugins.append(stringplugin)
        
        if self.checkBox_cambioImpl_2D3D.isChecked():
            headerImports = """

                <link href="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/cambioImpl/cambioImpl.css" rel="stylesheet" />
                <script type="text/javascript" src="https://ingenierogeomatico.github.io/Galeria_de_mapas/ext/cambioImpl/cambioImpl.js"></script>

            """
            pluginImports.append(headerImports)
            stringplugin = """
            mapajs.addPlugin(pluginCamioImplFunc());
            """
            plugins.append(stringplugin)


        extentQGIS = iface.mapCanvas().extent()
        CRSQGIS = QgsProject.instance().crs()
        ct = QgsCoordinateTransform(CRSQGIS, QgsCoordinateReferenceSystem('EPSG:3857'), QgsProject.instance())
        bounds_crs = ct.transformBoundingBox(extentQGIS)
        bbox = [bounds_crs.xMinimum(), bounds_crs.yMinimum(), bounds_crs.xMaximum(), bounds_crs.yMaximum()]

        with open(fileJS, 'w') as filetowrite:
            filetowrite.write(self.CreateJS_3D_2D(bbox, layers, controls, plugins))

        with open(fileCSS, 'w') as filetowrite:
            filetowrite.write(self.CreateCSS())
        
        with open(fileMap, 'w') as filetowrite:
            filetowrite.write(self.CreateHTML( 
                    headerImports=pluginImports
                )
            )


        webbrowser.open(fileMap, new=2)
        self.close()
        return
    
    def QGISStyle2apiideeStyle(self, qgisLayerLegend):
        return layer_templates.QGISStyle2apiideeStyle(qgisLayerLegend)

    def JSONLayer2StringLayer(self, layer):
        return layer_templates.JSONLayer2StringLayer(layer)

    def CreateHTML(self, headerImports=[], checkBox_ComparacionMapas=[]):

        headerImportsString = ''
        for l in headerImports:
            headerImportsString = headerImportsString + l

        body="""
        <!-- Contenedor principal del mapa -->
        <div id="mapaJS_div" class="m-container"></div>

        <!-- Importación de JS del visualizador-->
        <script type="text/javascript" src="./JS/QGIS2APIIDEE.js"></script>
        """
        CSS_MapasComparacion = ''
        JS_MapasComparacion = ''
        if checkBox_ComparacionMapas:
            CSS_MapasComparacion = """
            <!-- extensiones OL - viglino -->
            <link type="text/css" rel="stylesheet" href="./pluginQGIS2APIIDEE/viglino/CSS/ol-ext.css">
            <link type="text/css" rel="stylesheet" href="./pluginQGIS2APIIDEE/viglino/CSS/font-gis.css">
            <script type="text/javascript" src="./pluginQGIS2APIIDEE/viglino/JS/ol-ext.js"></script>

            <!-- extensiones propias de QGIS2APIIDEE (CSS) -->
            <link type="text/css" rel="stylesheet" href="./pluginQGIS2APIIDEE/comparadorMapas/CSS/comparadorMapas.css">
            """

            JS_MapasComparacion = """
            <!-- Importación de JS del visualizador-->
            <script type="text/javascript" src="./pluginQGIS2APIIDEE/comparadorMapas/JS/comparadorMapas.js"></script>
            """

            body="""
            <!-- The Modal -->
            <div id="myModal" class="modal">

                <!-- Modal content -->
                <div class="modal-content">
                    <span class="close">&times;</span>
                    <h3>Configuración de comparación</h3>

                    <table id="tablaModal">
                        <tr>
                            <th>Botón</th>
                            <th>Información</th>
                        </tr>
                        <tr>
                            <td><i class="fg-map-add"></i></td>
                            <td>Al hacer clic, abre una ventana modal para crear una nueva vista al visualizador</td>
                        </tr>
                        <tr>
                            <td><i class="fg-map-o"></i></td>
                            <td>
                                Al hacer clic, visualiza el mapa seleccionado
                            </td>
                        </tr>
                        <tr>
                            <td><i class="fg-screen-dub-o"></i></td>
                            <td>
                                Permite la comparación en espejo.
                                Se divide el visualizador en dos partes donde se puede comparar de forma síncrona dos mapas
                            </td>
                        </tr>
                        <tr>
                            <td><i class="fg-screen-split-h"></i></td>
                            <td>
                                Permite al comparación en cortina horizontal.
                                Se divide el visualizador superponiendo los dos mapas entre si, pudiendo ver la misma extensión
                                en los dos mapas
                            </td>
                        </tr>
                        <tr>
                            <td><i class="fg-screen-split-v"></i></td>
                            <td>
                                Permite al comparación en cortina vertical.
                                Se divide el visualizador superponiendo los dos mapas entre si, pudiendo ver la misma extensión
                                en los dos mapas
                            </td>
                        </tr>
                        <tr>
                            <td><i class="fg-screen-mag"></i></td>
                            <td>
                                Permite la comparación zonal.
                                Habilita un círculo que permite comparar los dos mapas según se mueve el ratón.
                            </td>
                        </tr>
                        <tr>
                            <td><i class="fg-map-options-alt"></i></td>
                            <td>
                                Permite configurar los mapas a visualizar en cada sección de comparación.
                            </td>
                        </tr>
                    </table>
                </div>

            </div>

            <!-- The Sidenav -->
            <div id="mySidenav" class="sidenav">

                <div class="grid-container">
                    <h3 style="padding-left: 10px;">Configuración comparación</h3>
                    <a href="javascript:void(0)" class="closebtn">&times;</a>
                </div>


                <table id="tablaConfig">
                    <tr>
                        <th>Botón</th>
                        <th>Configuración</th>
                    </tr>
                    <tr id="table_view1" class="activeTable">
                        <td><i class="fg-map-o"></i></td>
                        <td>
                            <div class="grid-container">
                                <p>Mapa:</p>
                                <select id="selectorMapasUnico" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                            </div>
                        </td>
                    </tr>
                    <tr id="table_compare">
                        <td><i class="fg-screen-dub-o"></i></td>
                        <td>
                            <div class="grid-container">
                                <p>Mapa derecho:</p>
                                <select id="selectorMapasEspejoDer" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                                <p>Mapa izquierdo:</p>
                                <select id="selectorMapasEspejoIzq" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                            </div>
                        </td>
                    </tr>
                    <tr id="table_swipev">
                        <td><i class="fg-screen-split-h"></i></td>
                        <td>
                            <div class="grid-container">
                                <p>Mapa derecho:</p>
                                <select id="selectorMapasHCortinillaDer" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                                <p>Mapa izquierdo:</p>
                                <select id="selectorMapasHCortinillaIzq" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                            </div>
                        </td>
                    </tr>
                    <tr id="table_swipeh">
                        <td><i class="fg-screen-split-v"></i></td>
                        <td>
                            <div class="grid-container">
                                <p>Mapa arriba:</p>
                                <select id="selectorMapasVCortinillaIzq" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                                <p>Mapa abajo:</p>
                                <select id="selectorMapasVCortninillaDer" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                            </div>
                        </td>
                    </tr>
                    <tr id="table_clip">
                        <td><i class="fg-screen-mag"></i></td>
                        <td>
                            <div class="grid-container">
                                <p>Mapa fondo:</p>
                                <select id="selectorMapasCirculoFondo" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                                <p>Mapa círculo:</p>
                                <select id="selectorMapasCirculoCir" class="selectorMapasClase" name="Selector de mapa">

                                </select>
                            </div>
                        </td>
                    </tr>
                </table>

                <div class="grid-container">
                    <p></p>
                    <button id="idAceptar" class="aceptar">aceptar</button>
                </div>
            </div>



            <!-- div comparación -->
            <div class="tools">
                <i id="addMap" class="fg-map-add" onclick="setMode('addMap')" title="Añadir mapa"></i>
                <i id="view1" class="fg-map-o activeSVG" onclick="setMode('view1')" title="Mapa único"></i>
                <i id="compare" class="fg-screen-dub-o" onclick="setMode('compare')" title="Compare"></i>
                <i id="swipev" class="fg-screen-split-h" onclick="setMode('swipev')" title="Swipe V"></i>
                <i id="swipeh" class="fg-screen-split-v" onclick="setMode('swipeh')" title="Swipe V"></i>
                <i id="clip" class="fg-screen-mag" onclick="setMode('clip')" title="Clip"></i>
                <i id="settings" class="fg-map-options-alt" onclick="setMode('settings')" title="configuración"></i>
                <i id="info" class="fg-poi-info-o" onclick="setMode('info')" title="info"></i>
            </div>

            <!-- Contenedor principal del mapa -->
            <div id="compareMaps">

                <div id="mapaJS_div" class="m-container m-mapea-container compareMaps" 
                    style="z-index: 1;"
                    >
                </div>
                <div id="mapaJS_div_2" class="m-container m-mapea-container compareMaps" 
                    style="z-index: 0;"
                    >
                </div>
                <div id="mapaJS_div_n" class="m-container m-mapea-container compareMaps" 
                    style="z-index: -1;"
                    >
                </div>

            </div>

            <!-- Importación de JS del visualizador-->
            <script type="text/javascript" src="./JS/QGIS2APIIDEE.js"></script>
            """


        html = """<!DOCTYPE html>
                    <html>
                        <head>
                            <meta charset="UTF-8">
                            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
                            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                            <meta name="cnig" content="yes">
                            <title>Visualizador API-IDEE</title>
                            
                            <!--          -->
                            <!-- API-IDEE -->
                            <!--          -->

                            <!-- CSS API-IDEE -->
                            <link type="text/css" rel="stylesheet" href="./API_IDEE/nucleo/apiidee.ol.min.css">
                            
                            <!-- JS API-IDEE  -->
                            <script type="text/javascript" src="./API_IDEE/nucleo/apiidee.ol.min.js"></script>
                            <script type="text/javascript" src="./API_IDEE/nucleo/configuration.js"></script>

                            <!-- extensiones API-IDEE -->
                            {headerImports}

                            {CSS_MapasComparacion}


                            <!-- Estilo personalizado del HTML-->
                            <link type="text/css" rel="stylesheet" href="./CSS/QGIS2APIIDEE.css">
                            
                        </head>
                        
                        <body>
                            {body}

                            {JS_MapasComparacion}

                        </body>
                    </html>""".format(
                                    headerImports=headerImportsString,
                                    CSS_MapasComparacion=CSS_MapasComparacion,
                                    JS_MapasComparacion=JS_MapasComparacion,
                                    body=body
                                )
        return html

    def CreateJS(self, bbox, layers, controls, plugins):

        layersString = ''
        for l in layers:
            layersString = layersString + l

        pluginString = ''
        for l in plugins:
            pluginString = pluginString + l
        
        JS = """
                                
            // Configuración del mapa
            let zoomInicial = 5
            let longLatInicial = [-3, 40]
            const zoom_p = IDEE.config.MAP_VIEWER_ZOOM || zoomInicial;
            const center_p = IDEE.config.MAP_VIEWER_CENTER || ol.proj.fromLonLat(longLatInicial);
            
            IDEE.proxy(false) // Necesario para ejecutar el visualizador en local.
            const mapajs = IDEE.map({{
                container: 'mapaJS_div',
                controls: {controls},
                bbox: {bbox}
            }});
            
            const layers_p = IDEE.config.MAP_VIEWER_LAYERS || [];
            mapajs.addLayers(layers_p)

            {layers}

            {plugins}
                                        
        """.format(
                    bbox = bbox,
                    controls=controls,
                    layers = layersString,
                    plugins = pluginString                
                    )
        return JS
    
    #TODO: cuando todo funcione, refactorizar para mejorar código duplicado
    def CreateJS_3D_2D(self, bbox, layers, controls, plugins):

        layersString = ''
        for l in layers:
            layersString = layersString + l

        pluginString = ''
        for l in plugins:
            pluginString = pluginString + l
        changeImplString = ''
        if self.checkBox_cambioImpl_2D3D.isChecked():
            changeImplString += """
                function pluginCamioImplFunc() {
                    return new miPlugin_cambioImpl({
                        buttonTitle: 'cambiar impl :)',
                        mapsFunction: mapa,
                        sameMap: true,
                        shareView: true,
                        shareLayers: true
                    });
                }
            """
        if self.checkBox_selectorCapa_2D3D.isChecked():
            changeImplString += """
                 function pluginCapasSuperpuestasFunc() {
                    return new miPlugin_layerSwitcher()
                }
            """
        
        if self.checkBox_capaBase_2D3D.isChecked():
            changeImplString += """
                function pluginCapasBaseFunc() {
                    return new miPlugin_baseLayer()
                }
            """
        
        JS = """
        function mapa() {{        
            // Configuración del mapa
            updateConfigBaseLayer()
            let zoomInicial = 5
            let longLatInicial = [-3, 40]
            const zoom_p = IDEE.config.MAP_VIEWER_ZOOM || zoomInicial;
            const center_p = IDEE.config.MAP_VIEWER_CENTER || ol.proj.fromLonLat(longLatInicial);
            
            IDEE.proxy(false) // Necesario para ejecutar el visualizador en local.
            mapajs = IDEE.map({{
                container: 'mapaJS_div',
                controls: {controls},
                bbox: {bbox}
            }});
            
            const layers_p = IDEE.config.MAP_VIEWER_LAYERS || [];
            mapajs.addLayers(layers_p)

            {layers}

            {plugins}

            return mapajs
        }}

        {changeImplString}

        mapajs_0 = mapa()

        function updateConfigBaseLayer() {{
            Base_IGNBaseTodo_TMS_2 = new IDEE.layer.TMS({{
                url: 'https://tms-ign-base.idee.es/1.0.0/IGNBaseTodo/{{z}}/{{x}}/{{-y}}.jpeg',
                legend: 'IGNBaseTodo_2',
                visible: true,
                isBase: true,
                tileGridMaxZoom: 17,
                name: 'IGNBaseTodo_2',
                attribution: '<p><b>Mapa base</b>: <a style="color: #0000FF" href="https://www.scne.es" target="_blank">SCNE</a></p>',
            }}, {{
                crossOrigin: 'anonymous',
                displayInLayerSwitcher: false,
            }})

            IDEE.addQuickLayers({{
                Base_IGNBaseTodo_TMS_2: Base_IGNBaseTodo_TMS_2
            }})

            tms_2 = {{
                "base": "QUICK*Base_IGNBaseTodo_TMS_2"
            }}

            IDEE.config("tms", tms_2)
            IDEE.config.backgroundlayers = [
                {{
                "id": "mapa",
                "title": "Callejero",
                "layers": [
                    "QUICK*Base_IGNBaseTodo_TMS_2"
                ]
                }},
                {{
                "id": "imagen",
                "title": "Imagen",
                "layers": [
                    "QUICK*BASE_PNOA_MA_TMS"
                ]
                }}
            ]

            IDEE.proxy(false);

            return
            }}

            function _onRenderComplete() {{
                const impl = mapajs_0.getMapImpl();
                const capa = mapajs.getLayers().filter(layer => layer.name == "capa_gjson")[0];
                if (!capa) return;
                mapajs_0.setBbox(capa.getFeaturesExtent());
                mapajs_0.setZoom(mapajs_0.getZoom() - 0.5);

                if (impl && typeof impl.un === 'function') {{
                    impl.un('rendercomplete', _onRenderComplete);
                    return;
                }}
                if (impl && typeof impl.off === 'function') {{
                    impl.off('rendercomplete', _onRenderComplete);
                    return;
                }}
                if (impl && typeof impl.removeListener === 'function') {{
                    impl.removeListener('rendercomplete', _onRenderComplete);
                    return;
                }}
            }}

            const _implForOn = mapajs_0.getMapImpl();
            if (_implForOn && typeof _implForOn.on === 'function') {{
            _implForOn.on('rendercomplete', _onRenderComplete);
            }} else if (_implForOn && typeof _implForOn.addEventListener === 'function') {{
            _implForOn.addEventListener('rendercomplete', _onRenderComplete);
            }} else {{
            console.warn('rendercomplete: no compatible add-listener method found on map impl');
            }}
              
        """.format(
                    bbox = bbox,
                    controls=controls,
                    layers = layersString,
                    plugins = pluginString,
                    changeImplString=changeImplString                
            )
        return JS
    
    def CreateCSS(self):

        CSS = """
                html,
                body {
                    margin: 0;
                    padding: 0;
                    height: 100%;
                    overflow: hidden;
                }

                .m-panel button, 
                .m-panel.m-plugin-layerswitcher.opened button.m-panel-btn, 
                .m-areas>div.m-area>div.m-panel.collapsed>button.m-panel-btn,
                .ol-zoomslider>button.ol-zoomslider-thumb,
                .m-areas>div.m-area>div.m-panel.no-collapsible>div.m-panel-controls>div.m-control.m-container.m-background>button,
                .m-scale-container,
                #m-rotate-slider-container,
                .m-areas > div.m-area > div.m-panel > div.m-panel-controls > div.m-control.m-rotate-container button[class^="g-cartografia-"]#m-rotate-button {
                    background-color: orange !important;
                }

                .m-areas>div.m-area>div.m-panel.no-collapsible>div.m-panel-controls>div.m-control.m-container.m-background>button.m-background-group-btn.activeBaseLayerButton{
                    background-color: #cd7d00 !important;
                }

                .ol-scale-line .ol-scale-line-inner {
                    border-color: orange;
                    color: orange;
                    font-weight: 700;
                }

                .ol-scale-line.ol-unselectable {
                    background: white !important;
                }
  
                .m-panel section button {
                    background-color: transparent !important;
                }
        """
        return CSS