# -*- coding: utf-8 -*-
"""
/***************************************************************************
 ISO19157Dialog
                                 A QGIS plugin
 Aplicación de la norma ISO 19157 sobre la BTN25 del CNIG
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                             -------------------
        begin                : 2021-02-18
        git sha              : $Format:%H$
        copyright            : (C) 2021 by Harold Mercado LLanos
        email                : hmercado78@hotmail.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.                                   *
 *                                                                         *
 ***************************************************************************/
"""

# Se importan los modulos requeridos

import os
import sys
sys.path.append("pyqt path")
import pandas as pd
import random
import PyQt5
import threading
import webbrowser
from datetime import datetime
from qgis import processing
from qgis.PyQt import uic
from qgis.gui import QgsMessageBar
from qgis.core import *
from qgis.core import (QgsProject, QgsVectorLayer, QgsLayerTreeGroup, 
    QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsWkbTypes, 
    QgsField, QgsDistanceArea, QgsCoordinateReferenceSystem, QgsPoint, 
    QgsApplication, QgsGeometry, QgsPointXY, QgsFeature, QgsMarkerSymbol, 
    QgsSimpleFillSymbolLayer, QgsSymbolLayer, QgsProperty, QgsFillSymbol, 
    QgsSingleSymbolRenderer)
from qgis.utils import iface, showPluginHelp
from PyQt5.QtWidgets import (QFileDialog, QTabWidget, QListWidget, 
    QPushButton, QComboBox, QTextEdit, QGridLayout, QCheckBox, 
    QDialog, QTableWidget, QTableWidgetItem, QAbstractScrollArea, 
    QMessageBox, QInputDialog, QProgressBar, QTextBrowser)
from PyQt5 import QtGui, QtCore
from PyQt5.QtGui import *
from PyQt5.QtGui import QColor
from PyQt5.QtCore import Qt
from iso_19157.scripts.iso_19157_conlogica import conLogica
from iso_19157.scripts.iso_19157_caltemporal import caltemporal
from iso_19157.scripts.iso_19157_complecion import complecion
from iso_19157.scripts.iso_19157_calposicional import posicional

# Se instancia el proyecto
project = QgsProject.instance()


# Carga el archivo .ui Para que PyQt pueda completar el plugin con los elementos de Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'iso_19157_dialog_base.ui'))


class ISO19157Dialog(QDialog, FORM_CLASS):
    def __init__(self, parent=None):
        """Constructor."""
        super(ISO19157Dialog, self).__init__(parent)
        # Set up the user interface from Designer through FORM_CLASS.
        # After self.setupUi() you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)

# Se asigan el comportamiento de los botones y demas Widgets
        QtCore.QMetaObject.connectSlotsByName(self)
        self.proyn_bt.clicked.connect(self.open_new)
        self.proyv_bt.clicked.connect(self.open_old)
        self.Add_obj.clicked.connect(self.add_objeto)    
        self.tb_conj_datos.cellClicked.connect(self.elimina_cd)
        self.bp_cdr.clicked.connect(self.asociar_cdr) 
        self.bt_validar.clicked.connect(self.validar_cd)
        self.tabWidget.setTabEnabled(1,False)
        self.tabWidget.setTabEnabled(2,False)  
        self.tabWidget.setTabEnabled(3,False) 
        self.tabWidget.setTabEnabled(4,False)
        self.tabWidget.setTabEnabled(5,False)
        self.bt_temp_2.pressed.connect(self.ver_result_temp)
        self.bt_comp_2.pressed.connect(self.ver_result_comp)
        self.bt_cons_2.pressed.connect(self.ver_result_cons)
        self.bt_posi_2.pressed.connect(self.ver_result_posi)
        self.help_in.pressed.connect(self.ayudas_in)
        self.help_cd.setEnabled(True)
        self.help_cd.clicked.connect(self.ayudas_cd)
        self.help_vl.clicked.connect(self.ayudas_vl)
        self.help_el.clicked.connect(self.ayudas_elem)
        self.help_cl.clicked.connect(self.ayudas_log)
        self.help_com.clicked.connect(self.ayudas_com)        
        self.help_ep.clicked.connect(self.ayudas_posi)
        self.help_et.clicked.connect(self.ayudas_temp)
        self.help_tem.clicked.connect(self.ayudas_tema)
        self.help_usa.clicked.connect(self.ayudas_usab)
        self.bt_comp.clicked.connect(self.fun_comp) 
        self.bt_cons.clicked.connect(self.fun_topo)
        self.bt_posi.clicked.connect(self.fun_posi) 
        self.bt_temp.clicked.connect(self.fun_temp) 
        self.bt_iniciar.clicked.connect(self.iniciar_val)
        self.bt_reproy.clicked.connect(self.reproyecta)
        self.bt_element.clicked.connect(self.sel_elementos)

# Funcion que permite Crear un nuevo proyecto de Evaluacion.
# Se requiere asignar una carpeta vacia donde el algoritmo carga los archivos iniciales
    def open_new(self):
        #print(self.sender().objectName())
        self.tabWidget.setTabEnabled(1,False)
        self.tabWidget.setTabEnabled(2,False)  
        self.tabWidget.setTabEnabled(3,False) 
        self.tabWidget.setTabEnabled(4,False)
        self.bt_validar.setEnabled(False)
        self.bp_cdr.setEnabled(False)
        self.tb_conj_datos.clear()
        self.cb_cde.clear()
        self.rel_val.clear()

        dialogo = QFileDialog(self)
        fic_nuevo = dialogo.getExistingDirectory(self, 'Seleccione Directorio')

        if not fic_nuevo:
            return

        else: 
            if os.path.isdir(str(fic_nuevo)):
                self.proyn.setText(fic_nuevo)
                self.proyv.setText("")
                if os.listdir(fic_nuevo):
                    self.label_6.setText("<font style='color:#FF0000'><b>Este Directorio no es valido, seleccione un directorio vacio</b></font>")
                    self.tabWidget.setTabEnabled(1,False)
                else:
                    self.label_6.setText("<font style='color:#00B000'><b>Es Directorio valido, continue a la pestaña Conjunto de datos</b></font>")
                    fic = open(fic_nuevo+'/Iso19157.txt','a')
                    fic.close()
                    now = datetime.now()
                    hoy = now.strftime('%Y/%m/%d %H:%M')
                    fic = open(fic_nuevo+'/Registro.txt','a')
                    fic.write('Plugin ISO 19157'+'\n'+'Creación de proyecto de evaluación: '+str(hoy)+'\n')
                    fic.write('Ubicación de proyecto: '+str(fic_nuevo)+'/Iso19157.txt'+'\n')
                    fic.close()
                    cde = open(fic_nuevo+'/cde.txt',"a+")
                    cde.close()
                    global ruta
                    ruta=fic_nuevo
                    project.write(fic_nuevo+'/iso19157.qgs')
                    os.mkdir(fic_nuevo+'/Resultados')
                    os.mkdir(fic_nuevo+'/CD')
                    self.act_tabla_cd()
                    self.tabWidget.setTabEnabled(1,True)
     
# Para buscar y continuar con un proyecto Existen, recarga la informacion al algoritmo.
    def open_old(self):
        #print(self.sender().objectName())
        self.tabWidget.setTabEnabled(1,False)
        self.tabWidget.setTabEnabled(2,False)  
        self.tabWidget.setTabEnabled(3,False) 
        self.tabWidget.setTabEnabled(4,False)
        self.bt_validar.setEnabled(False)
        self.bp_cdr.setEnabled(False)
        dialogo = QFileDialog(self)


        #def progress_changed(progress):
            #self.pbar_fic.setValue(progress)

        fic_viejo = dialogo.getExistingDirectory(self, 'Seleccione Directorio')

        #feed = QgsProcessingFeedback()
        #feed.progressChanged.connect(self, SIGNAL(currentChanged(int)))

        if not fic_viejo:
            return

        else:    
            if os.path.isdir(str(fic_viejo)):
                self.proyv.setText(fic_viejo)
                self.proyn.setText("")
                arc = fic_viejo+"/Iso19157.txt"
                if os.path.isfile(arc):
                    self.label_6.setText("<font style='color:#00B000'><b>Puede continuar o revisar el resultado de la evaluación</b></font>")
                    global ruta
                    ruta=fic_viejo
                    now = datetime.now()
                    hoy = now.strftime('%Y/%m/%d %H:%M')
                    fic = open(fic_viejo+'/Registro.txt','a')
                    fic.write('Ingreso al proyecto de evaluación: '+str(hoy)+'\n')
                    fic.close()
                    project.read(fic_viejo+'/iso19157.qgs')
                    self.tabWidget.setTabEnabled(1,True)
                    self.act_tabla_cd()
                else:
                    self.label_6.setText("<font style='color:#FF0000'><b>Esta carpeta no contiene los archivos validos para el plugin</b></font>")
                    self.tabWidget.setTabEnabled(1,False)
        
        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        if len(lista_res)>0:
            self.tabWidget.setTabEnabled(5,True)
            self.actualizar_res()
 
# Actualiza el conjunto de datos que me muestran en el Widget
# Adiciona en la lista el conjunto de datos que seran asociados con un CDR 
    def act_tabla_cd(self):    
        #print(self.sender().objectName())
        project.removeAllMapLayers()

        if self.bt_cons.isChecked():
            self.bt_cons.clicked.connect(self.limpiar)
    
        cde = str(ruta)+'/cde.txt'
        if os.stat(cde).st_size != 0:
            f = open (cde, 'r')
            cont = pd.read_csv(f)
            f.close()

            global lista_cde
            lista_cde = cont['CDE'].tolist()
            global lista_cdr
            lista_cdr = cont['CDR'].tolist()

            self.tb_conj_datos.clear()
            self.tb_conj_datos.setRowCount(len(lista_cde))
            self.tb_conj_datos.setColumnCount(3)            
            self.tb_conj_datos.setHorizontalHeaderItem(0, QTableWidgetItem("CDE"))
            self.tb_conj_datos.setHorizontalHeaderItem(1, QTableWidgetItem("CDR"))
            self.tb_conj_datos.setHorizontalHeaderItem(2, QTableWidgetItem("Eliminar"))

            tb_conj_datos = QTableWidget()
            self.tb_conj_datos.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
            self.tb_conj_datos.setColumnWidth(0,200)
            self.tb_conj_datos.setColumnWidth(1,200)
            self.tb_conj_datos.resizeColumnToContents(2)

            self.bt_validar.setEnabled(True)
            self.bp_cdr.setEnabled(True)

            fila = 0
            for registro in lista_cde:
                indice = (registro.rfind('/'))+1
                registro = registro[indice:]
                celda = QTableWidgetItem(registro)
                self.tb_conj_datos.setItem(fila,0,celda)
                fila +=1 

            fila = 0
            for registro in lista_cdr:
                try:
                    reg = float(registro)
                    fila +=1
                except ValueError:
                    indice = (registro.rfind('/'))+1
                    registro = registro[indice:]
                    celda = QTableWidgetItem(registro)
                    self.tb_conj_datos.setItem(fila,1,celda)
                    fila +=1

            i = 0
            for i in range(len(lista_cde)):
                boton = QPushButton("Eliminar", self)
                celda = QTableWidgetItem("X")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tb_conj_datos.setItem(i,2,celda)
                i += 1

            self.cb_cde.clear()
            self.cb_cde.addItems(list(lista_cde))

            iso_archivo = str(ruta)+'/Iso19157.txt'
            if os.stat(iso_archivo).st_size == 0:
                f = open (iso_archivo, 'w')
                linea = "CDE,CDR,COMP,CONS,POSI,TEMP,TEMA,USAB\n"
                f.write(linea)
                for x in range(len(lista_cde)):
                    indice = (lista_cde[x].rfind('shp,'))-3
                    registro_cde = lista_cde[x][:indice]
                    indice = (registro_cde.rfind('/'))+1
                    n_cde = registro_cde[indice:]
                    if lista_cdr[x]=="-":
                        n_cdr=""
                    else:
                        indice = (lista_cdr[x].rfind('shp,'))-3
                        registro_cdr = lista_cdr[x][:indice]
                        indice = (registro_cdr.rfind('/'))+1
                        n_cdr = registro_cdr[indice:]                    
                    linea = f"{n_cde},{n_cdr},False,False,False,False,False,False\n"
                    f.write(linea)
                f.close()


# Funcion para eliminar un conjunto de datos, este se activa al hacer click en el TableWidget y elimina la fila seleccionada.
    def elimina_cd(self,fila,columna):
        #print(self.sender().objectName())
        self.label_8.setText("<font style='color:#00B000'>Elimino registro: "+str(fila+1) + "</fon>" )
        cde = str(ruta)+'/cde.txt'
        f = open (cde, 'r')
        lineas = f.readlines()
        f.close()

        buscado = lineas[fila+1]
      
        f = open (cde, 'w')
        for linea in lineas:
            if linea!=(buscado):
                f.write(linea)
            else:
                now = datetime.now()
                hoy = now.strftime('%Y/%m/%d %H:%M')
                fic = open(ruta+'/Registro.txt','a')
                fic.write('Se eliminó el conjunto de datos: ' + buscado + ' del proyecto ' + str(hoy)+'\n')
                fic.close()
        f.close()

        iso_archivo = str(ruta)+'/Iso19157.txt'
        f = open (iso_archivo, 'r')
        lineas = f.readlines()
        f.close()

        buscado = lineas[fila+1]
        f = open (iso_archivo, 'w')
        for linea in lineas:
            if linea!=(buscado):
                f.write(linea)
        f.close()

        self.act_tabla_cd()

        self.tabWidget.setTabEnabled(2,False)
        self.tabWidget.setTabEnabled(3,False)
        self.tabWidget.setTabEnabled(4,False) 


# Funcion que Adiciona un CDE seleccionado por el usuario desde una ubicacion local
    def add_objeto(self):
        #print(self.sender().objectName())
        dialogo = QFileDialog(self)
        obj = dialogo.getOpenFileName(self, 'Seleccione Archivo Shape', '', "Shape (*.shp)")
        if obj[0]=="":
            self.act_tabla_cd()

        else:
            cde = str(ruta)+'/cde.txt'
            if os.stat(cde).st_size == 0:
                f = open(cde,'w') 
                f.write('CDE,CDR'+"\n")
                f.write(str(obj[0])+",-\n")
                f.close()
                now = datetime.now()
                hoy = now.strftime('%Y/%m/%d %H:%M')
                fic = open(ruta+'/Registro.txt','a')
                fic.write('Se adicionó el conjunto de datos: ' + str(obj[0]) + ' al proyecto ' + str(hoy)+'\n')
                fic.close()
                self.label_8.setText("<font style='color:#00B000'><b>Se cargo con exito el nuevo Conjunto de Datos</b></font>")
                self.act_tabla_cd()                               

            else:
                f = open (cde, 'r')
                cont = pd.read_csv(f)
                f.close()
                lista = cont['CDE'].tolist()

                if str(obj[0]) in lista:
                    self.label_8.setText("<font style='color:#FF0000'><b>Ya esta cargado este Conjunto de Datos</b></font>")
                    self.act_tabla_cd()                               
                else:
                    s = open (cde, "a")
                    s.write(str(obj[0])+",-\n")
                    s.close()
                    now = datetime.now()
                    hoy = now.strftime('%Y/%m/%d %H:%M')
                    fic = open(ruta+'/Registro.txt','a')
                    fic.write('Se adicionó el conjunto de datos: ' + str(obj[0]) + ' al proyecto ' + str(hoy)+'\n')
                    fic.close()
                    self.label_8.setText("<font style='color:#00B000'><b>Se cargo con exito el nuevo Conjunto de Datos</b></font")

                    iso_archivo = str(ruta)+'/Iso19157.txt'
                    f = open(iso_archivo, 'a+')
                    indice = (str(obj[0]).rfind('shp,'))-3
                    registro_cde = str(obj[0])[:indice]
                    indice = (registro_cde.rfind('/'))+1
                    n_cde = registro_cde[indice:]
                    linea = f"{n_cde},,False,False,False,False,False,False\n"
                    f.write(linea)
                    f.close()

                    self.act_tabla_cd()

        self.tabWidget.setTabEnabled(2,False)             
        self.tabWidget.setTabEnabled(3,False)
        self.tabWidget.setTabEnabled(4,False) 

#Funcion que asocia un CDR a un CDE seleccionado por el usuario desde la lista.
    def asociar_cdr(self):
        #print(self.sender().objectName())

        dialogo = QFileDialog(self)
        obj = dialogo.getOpenFileName(self, 'Seleccione Archivo Shape', '', "Shape (*.shp)")


        if obj[0]=="":
            self.act_tabla_cd()

        else:
            cdr = str(ruta)+'/cde.txt'
            g = open (cdr, 'r')
            lineas = g.readlines()
            g.close()

            buscado = (self.cb_cde.currentText())+",-\n"

            # Reescribiendo el archivo ISO19157.txt
            indice = buscado.rfind('/')
            nom_arc_cde = buscado[indice+1:-7]
            indice = str(obj[0]).rfind('/')
            nom_arc_cdr = str(obj[0])[indice+1:-4]
            iso_archivo = str(ruta)+'/Iso19157.txt'
            g = open (iso_archivo, 'r')
            lineas_iso = g.readlines()
            g.close()
            f = open (iso_archivo, 'w')
            for linea in lineas_iso:
                if nom_arc_cde in linea:
                    indice = linea.find(',')
                    linea_c = linea[indice+1:]
                    indice = linea_c.find(',')
                    linea_c = linea_c[indice:]
                    linea_c = nom_arc_cde+","+nom_arc_cdr+linea_c
                    f.write(linea_c)
                else:
                    f.write(linea)
            f.close()
            
            # Reescribendo el archivo cde.txt
            f = open (cdr, 'w')
            for linea in lineas:
                if linea == buscado:
                    indice = (linea.rfind(','))
                    registro = linea[:indice]
                    linea = registro+","+str(obj[0])+"\n"
                    f.write(linea)
                    now = datetime.now()
                    hoy = now.strftime('%Y/%m/%d %H:%M')
                    fic = open(ruta+'/Registro.txt','a')
                    fic.write('Se asoció el conjunto de datos de referencia: ' + str(obj[0]) + ' al conjunto de datos evaluado '+ linea + str(hoy)+'\n')
                    fic.close()
                else:
                    f.write(linea)
            f.close()
            self.act_tabla_cd()

# Funcion para validad las parejas de CDE y CDR, donde se comprueba el Sistema de Coordenadas (de ser necesario reproyecta)
# Verifica que los Conjuntos de datos compartan una extension espacial comun
# Valida que el conjunto de datos tenga la misma topologia.
    def validar_cd(self):
        #print(self.sender().objectName())
        self.tabWidget.setTabEnabled(2,True)       
        self.tabWidget.setCurrentIndex(2)

        project.removeAllMapLayers()
        root = project.layerTreeRoot()
        root.removeAllChildren()

        self.rel_val.clear()

        global capa_cde
        capa_cde = dict()
        global capa_cdr
        capa_cdr = dict()
        

        # Inicia la Validacion de el Sistema de Coordenadas.
        i = 0
        h = 0
        src_cdr = dict()
        src_cde = dict()
        global nom_cde
        nom_cde = list()
        global nom_cdr
        nom_cdr = list()
        dato =""
        global con_reproy 
        con_reproy= list()

        for i in range(len(lista_cde)):
            conteo=i+1
            grupo = "Conj_Datos_"+str(conteo)
            gr_cd = root.addGroup(grupo)
            migrupo = root.findGroup(grupo) 

            indice = (lista_cde[i].rfind('shp,'))-3
            registro_cde = lista_cde[i][:indice]
            indice = (registro_cde.rfind('/'))+1
            registro_cde = registro_cde[indice:]
            nom_cde.append(registro_cde)
            capa_cde[i] = (QgsVectorLayer(lista_cde[i], str(registro_cde)))
            project.addMapLayer(capa_cde[i], False)
            migrupo.addLayer(capa_cde[i])

            src_cde[i] = capa_cde[i].crs().description()
            if lista_cdr[i] != "-":
                indice = (lista_cdr[i].rfind('/'))+1
                registro_cdr = lista_cdr[i][indice:-4]
                nom_cdr.append(registro_cdr)
                capa_cdr[i] = (QgsVectorLayer(lista_cdr[i], str(registro_cdr)))
                project.addMapLayer(capa_cdr[i], False)
                migrupo.addLayer(capa_cdr[i])
                h +=1   
                src_cdr[i] = capa_cdr[i].crs().description()
            else:
                nom_cdr.append("-")

            if i in src_cdr:
                if src_cde[i]!=src_cdr[i]:
                    dato = dato + "<font style='color:#FF0000'><b>Conjunto "+ str(i+1) + ":<br> CDE: </b> " + src_cde[i] + " <b> CDR: </b> " + src_cdr[i] + "</font><br>" 
                    con_reproy.append(i)  
                else:
                    dato = dato + "<b>Conjunto "+ str(i+1) + ":<br> CDE: </b> " + src_cde[i] + " <b> CDR: </b> " + src_cdr[i] + "<br>" 
 
            i += 1

        self.con_src.setText(dato)
        self.label_15.setText(str(i)+" CDE con "+str(h)+" CDR")

        if len(con_reproy)>0:
            self.label_16.setText("<font style='color:#FF0000'><b>Se requiere reproyección</b></font>")
            self.bt_reproy.setEnabled(True)


        else:
            self.label_16.setText("<font style='color:#00B000'><b>No se requiere reproyección</b></font>")
            self.bt_reproy.setEnabled(False)
            self.label_25.setText("<font style='color:#00B000'><b>Valida</b></font>")
        # Finaliza la Validacion del sistema de coordenadas

        # Inicia Validacion de la cobertura espacial
        exten=""
        gr_ext = root.addGroup("Extension_CD")
        gr_ext = root.findGroup("Extension_CD")

            #Extension CDE: Encontrar la Hoja de Marco en la carpeta de CDE. Si: la carga en memoria, NO: Genera la extension con la cobertura de los CDE.
        ruta_cde = lista_cde[0]
        indice = (ruta_cde.rfind('/'))
        ruta_cde = ruta_cde[:indice]
        cont_dir = os.listdir(ruta_cde)
        res = [(string)for indice, string in enumerate(cont_dir) if "MAR_HOJ" in string]
        exten_cde = dict()
        if len(res)>0:
            ind = (res[0].rfind('.'))
            arc = res[0][:ind]
            ruta_arc = ruta_cde+"/"+arc+".shp"
            exten_cde["OUTPUT"] = (QgsVectorLayer(ruta_arc, "Extension_CDE"))
            project.addMapLayer(exten_cde["OUTPUT"], False)

            fill = QgsSimpleFillSymbolLayer()
            fill.setStrokeColor(Qt.red)
            fill.setStrokeWidth(0.5)
            fill.setColor(Qt.transparent)            
            symbol = QgsFillSymbol()
            symbol.changeSymbolLayer(0, fill)
            exten_cde["OUTPUT"].setRenderer(QgsSingleSymbolRenderer(symbol))

            gr_ext.addLayer(exten_cde["OUTPUT"])

            self.label_18.setText(ruta_arc)
            if os.path.isfile(ruta_arc):
                self.label_18.setText("La cobertua del CDE corresponde con: "+arc)

            #Genera la extension con la cobertura de los CDE y CDR.
        else:
            i = 0
            extens= list()
            xmin =list()
            ymin =list()
            xmax =list()
            ymax =list()
            for i in range((len(lista_cde))):
                exten = processing.run("native:polygonfromlayerextent", {'INPUT': capa_cde[i],'ROUND_TO':0,'OUTPUT':'TEMPORARY_OUTPUT'})
                project.addMapLayer(exten["OUTPUT"], False)
                extens.append(exten["OUTPUT"].source())
                
                features = exten["OUTPUT"].getFeatures()
                for feature in features:
                    attrs = feature.attributes()
                    xmin.append(attrs[0])
                    ymin.append(attrs[1])
                    xmax.append(attrs[2])
                    ymax.append(attrs[3])

                x_min = min(xmin)
                y_min = min(ymin)
                x_max = max(xmax)
                y_max = max(ymax)    
                i += 1
            
            if len(lista_cde)<1:
                self.label_18.setText("Se genera Cobertura con la Extension de: "+lista_cde[0])
            else:
                self.label_18.setText("Se genera Cobertura con la Extension máxima y minima de los CDE") 
                if (x_max-x_min)<14800 and (y_max-y_min)<9600:
                    exten = processing.run("native:mergevectorlayers", {'LAYERS': extens,'CRS':None,'OUTPUT':'TEMPORARY_OUTPUT'})
                    project.addMapLayer(exten["OUTPUT"], False)
                else:
                    self.label_18.setText("<font style='color:#FF0000'>Los CDE cargados no corresponden a la misma Hoja o al mismo SRC</font>") 

            exten_cde = processing.run("native:polygonfromlayerextent", {'INPUT': exten["OUTPUT"],'ROUND_TO':0,'OUTPUT':'TEMPORARY_OUTPUT'})
            project.addMapLayer(exten_cde["OUTPUT"], False)

            fill = QgsSimpleFillSymbolLayer()
            fill.setStrokeColor(Qt.red)
            fill.setStrokeWidth(0.5)
            fill.setColor(Qt.transparent)            
            symbol = QgsFillSymbol()
            symbol.changeSymbolLayer(0, fill)
            exten_cde["OUTPUT"].setRenderer(QgsSingleSymbolRenderer(symbol))

            processing.run("native:renamelayer", {'INPUT': exten_cde["OUTPUT"],'NAME': 'Extension_CDE'})
            gr_ext.addLayer(exten_cde["OUTPUT"])

            #Extension CDR: Genera la extension con la cobertura de los CDR.
        if len(lista_cdr)>0:
            i = 0
            cdr_val = 0
            extens= list()
            xmin =list()
            ymin =list()
            xmax =list()
            ymax =list()
            for i in range((len(lista_cdr))):
                if lista_cdr[i] !="-":
                    exten = processing.run("native:polygonfromlayerextent", {'INPUT': capa_cdr[i],'ROUND_TO':0,'OUTPUT':'TEMPORARY_OUTPUT'})
                    project.addMapLayer(exten["OUTPUT"], False)
                    extens.append(exten["OUTPUT"].source())
                
                    features = exten["OUTPUT"].getFeatures()
                    for feature in features:
                        attrs = feature.attributes()
                        xmin.append(attrs[0])
                        ymin.append(attrs[1])
                        xmax.append(attrs[2])
                        ymax.append(attrs[3])

                    x_min = min(xmin)
                    y_min = min(ymin)
                    x_max = max(xmax)
                    y_max = max(ymax)
                    cdr_val += 1    
                i += 1
            
        if cdr_val==0:
            self.label_21.setText("No existe CDR para generar cobertura")
            area_int=1
        else:
            self.label_21.setText("Se genera Cobertura con la Extension máxima y minima de los CDR") 
            exten = processing.run("native:mergevectorlayers", {'LAYERS': extens,'CRS':None,'OUTPUT':'TEMPORARY_OUTPUT'})
            project.addMapLayer(exten["OUTPUT"], False)
           
          #Genera la intersection para verificar la cobertura comun
            exten_cdr = processing.run("native:polygonfromlayerextent", {'INPUT': exten["OUTPUT"],'ROUND_TO':0,'OUTPUT':'TEMPORARY_OUTPUT'})            
            project.addMapLayer(exten_cdr["OUTPUT"], False) 

            fill = QgsSimpleFillSymbolLayer()
            fill.setStrokeColor(Qt.green)
            fill.setStrokeWidth(0.5)
            fill.setColor(Qt.transparent)            
            symbol = QgsFillSymbol()
            symbol.changeSymbolLayer(0, fill)
            exten_cdr["OUTPUT"].setRenderer(QgsSingleSymbolRenderer(symbol))

            processing.run("native:renamelayer", {'INPUT': exten_cdr["OUTPUT"],'NAME': 'Extension_CDR'})
            gr_ext.addLayer(exten_cdr["OUTPUT"])

            inter_cd = processing.run("native:intersection", {'INPUT': exten_cde["OUTPUT"], 'OVERLAY': exten_cdr["OUTPUT"], 'OUTPUT':'TEMPORARY_OUTPUT'})            
            project.addMapLayer(inter_cd["OUTPUT"], False) 

            fill = QgsSimpleFillSymbolLayer()
            fill.setStrokeColor(Qt.blue)
            fill.setStrokeWidth(1)
            fill.setColor(Qt.transparent)            
            symbol = QgsFillSymbol()
            symbol.changeSymbolLayer(0, fill)
            inter_cd["OUTPUT"].setRenderer(QgsSingleSymbolRenderer(symbol))

            processing.run("native:renamelayer", {'INPUT': inter_cd["OUTPUT"],'NAME': 'Cobertura_compartida'})
            gr_ext.addLayer(inter_cd["OUTPUT"])

            area_int=0
            features = inter_cd["OUTPUT"].getFeatures()

            for feature in features:
                geom = feature.geometry()
                area_int = (geom.area())/1000000 
                if area_int=="":
                    area_int=0

            features = exten_cde["OUTPUT"].getFeatures()
            for feature in features:
                geom = feature.geometry()
                area_cde = (geom.area())/1000000 

            if area_int>0:
                self.label_22.setText("El area del CDE :<b>"+ str(round(area_cde)) + " km2</b> - El area a evaluar :<b>"+ str(round(area_int))+ " km2 ( " + str(round(100*area_int/area_cde)) + "% )</b>")
                self.label_23.setText("<font style='color:#00B000'>Se acepta la cobertura de CDE y CDR</font>")
                self.label_26.setText("<font style='color:#00B000'><b>Valida</b></font>")
            else: 
                self.label_22.setText("<font style='color:#FF0000'>No existe area de cobertura comun</font>")
                self.label_23.setText("<font style='color:#FF0000'>Cambiar la relacion de CDE y CDR</font>")

        # Finaliza la validacion del Cobertura espacial


        # Inicia la Validacion de la topologia
        i = 0
        salida = ""
        errores = list()
        for i in range((len(lista_cde))):
            tipo_cde = capa_cde[i].geometryType()
            if tipo_cde==0:
                tipo_cde="Punto"
            elif tipo_cde==1:
                tipo_cde="Linea"
            elif tipo_cde==2:
                tipo_cde="Poligono"

            if lista_cdr[i] != "-":
                tipo_cdr = capa_cdr[i].geometryType()
                if tipo_cdr==0:
                    tipo_cdr="Punto"
                elif tipo_cdr==1:
                    tipo_cdr="Linea"
                elif tipo_cdr==2:
                    tipo_cdr="Poligono"
            else:
                tipo_cdr = "N/A"

            if tipo_cde == tipo_cdr or tipo_cdr == "N/A":
                salida = salida + "<b>Conjunto "+ str(i+1) + ":<br> CDE: </b> " + tipo_cde + " <b> CDR: </b> " + tipo_cdr + "<br>"
            else: 
                errores.append(str(i+1))
                salida = salida + "<font style='color:#FF0000'><b>Conjunto "+ str(i+1) + ":<br> CDE: </b> " + tipo_cde + " <b> CDR: </b> " + tipo_cdr + "</font><br>"
           

        self.con_topo.setText(salida)

        if len(errores)>0:
            self.label_24.setText("<font style='color:#FF0000'>Se deben cambiar CDR de: " + str(errores)+ "</font>")
        else: 
            self.label_24.setText("<font style='color:#00B000'>Pasó la verificación</font>")
            self.label_27.setText("<font style='color:#00B000'><b>Valida</b></font>")

        # Finaliza la validacion de la tolopogia 

        # Se activa boton "CONTINUAR" si coinciden los SCR, existe cobertura que permita la evalaucion, y si las topologias de CDE y CDR son iguales.

        if len(con_reproy)==0 and len(errores)==0 and area_int>0:
            self.bt_element.setEnabled(True)


# Funcion para reproyectar los CDR al sistema de coordenadas del CDE.
    def reproyecta(self):
        #print(self.sender().objectName())
        i = 0
        for i in range(len(con_reproy)):
            cont = con_reproy[i]
            c_cde = capa_cde[cont].crs().authid()
            c_cdr = capa_cdr[cont].crs().authid()

            ver_cde = QgsCoordinateReferenceSystem(c_cde)
            ver_cdr = QgsCoordinateReferenceSystem(c_cdr)

            if ver_cde.isValid()==True and ver_cdr.isValid()==True:
                cdr_transf = "Entro"

                salida = ruta+'/CD/'+capa_cdr[cont].name()+'.shp'
                processing.run("native:reprojectlayer", {'INPUT':capa_cdr[cont],'TARGET_CRS':ver_cde,'OUTPUT':salida})

                cdr = str(ruta)+'/cde.txt'
                g = open (cdr, 'r')
                lineas = g.readlines()
                g.close()
            
                f = open (cdr, 'w')
                lin = 0
                for linea in lineas:
                    if (lin-1) == cont:
                        indice = (linea.rfind(','))
                        registro = linea[:indice]
                        linea = registro+","+salida+"\n"
                        f.write(linea)
                        now = datetime.now()
                        hoy = now.strftime('%Y/%m/%d %H:%M')
                        fic = open(ruta+'/Registro.txt','a')
                        fic.write('Se reproyectó el conjunto de datos de referencia: ' + salida + ' al proyecto ' + str(hoy)+'\n')
                        fic.close()
                    else:
                        f.write(linea)
                    lin += 1
                f.close()

            else:
                self.label_16.setText("<font style='color:#FF0000'><b>No</b> se puede reproyectar</font>")
        i += 1
        self.act_tabla_cd()
        self.validar_cd()
   

    # Funcion para la seleccion de los elementos de calidad a evaluar.
    def sel_elementos(self):
        #print(self.sender().objectName())
        self.tabWidget.setTabEnabled(3,True)       
        self.tabWidget.setCurrentIndex(3)

        self.tabla1.clear()
        self.tabla1.setRowCount(len(lista_cde))
        self.tabla1.setColumnCount(8)            
        self.tabla1.setHorizontalHeaderItem(0, QTableWidgetItem("CDE"))
        self.tabla1.setHorizontalHeaderItem(1, QTableWidgetItem("CDR"))
        self.tabla1.setHorizontalHeaderItem(2, QTableWidgetItem("Com"))
        self.tabla1.setHorizontalHeaderItem(3, QTableWidgetItem("C.Log"))
        self.tabla1.setHorizontalHeaderItem(4, QTableWidgetItem("E.pos"))
        self.tabla1.setHorizontalHeaderItem(5, QTableWidgetItem("C.Tem"))
        self.tabla1.setHorizontalHeaderItem(6, QTableWidgetItem("E.Tem"))
        self.tabla1.setHorizontalHeaderItem(7, QTableWidgetItem("Usa"))
        
        self.label_28.setText("<b>Com:</b>&nbsp;Compleción&nbsp;&nbsp;&nbsp;<b>C.Log:</b>&nbsp;Consistencia lógica&nbsp;&nbsp;&nbsp;<b>E.pos:</b>&nbsp;Exactitud posicional&nbsp;&nbsp;&nbsp;<br><b>C.Tem:</b>&nbsp;Calidad Temporal&nbsp;&nbsp;&nbsp;<b>E.Tem:</b>&nbsp;Exactiud temática&nbsp;&nbsp;&nbsp;<b>Usa:</b>&nbsp;Usabilidaad")

        x=0
        f_cdr = dict()
        global comp
        comp = dict()
        global cons
        cons = dict()
        global posi
        posi = dict()
        global temp
        temp = dict()
        global tema
        tema = dict()
        global usab
        usab = dict()
        
        v_comp = list()
        v_cons = list()
        v_posi = list()
        v_temp = list()
        v_tema = list()
        v_usab = list()

        iso_archivo = str(ruta)+'/Iso19157.txt'
        
        if os.stat(iso_archivo).st_size != 0:
            f = open (iso_archivo, 'r')
            cont = pd.read_csv(f)
            f.close()
            v_comp = cont['COMP'].tolist()
            v_cons = cont['CONS'].tolist()
            v_posi = cont['POSI'].tolist()
            v_temp = cont['TEMP'].tolist()
            v_tema = cont['TEMA'].tolist()
            v_usab = cont['USAB'].tolist()
        else:
            x=0
            for x in range(len(nom_cde)):
                v_comp.append(True) 
                v_cons.append(True)
                v_posi.append(True)
                v_temp.append(True)
                v_tema.append(False)
                v_usab.append(False)


        tabla1 = QTableWidget()
        self.tabla1.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
        self.tabla1.setColumnWidth(0,250)
        self.tabla1.resizeColumnToContents(1)
        self.tabla1.resizeColumnToContents(2)
        self.tabla1.resizeColumnToContents(3)
        self.tabla1.resizeColumnToContents(4)
        self.tabla1.resizeColumnToContents(5)
        self.tabla1.resizeColumnToContents(6)
        self.tabla1.resizeColumnToContents(7)
     
        for x in range(len(nom_cde)):

            celda = QTableWidgetItem(str(nom_cde[x]))
            self.tabla1.setItem(x,0,celda)

            if nom_cdr[x]!="-":
                celda = QTableWidgetItem("SI")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tabla1.setItem(x,1,celda)     
            else:
                celda = QTableWidgetItem("NO")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tabla1.setItem(x,1,celda) 
     

            if nom_cdr[x]!="-":
                comp[str(x)] = QCheckBox("")
                comp[str(x)].setChecked(v_comp[x])
                comp[str(x)].stateChanged.connect(self.state_changed)
                self.tabla1.setCellWidget(x,2,comp[str(x)])
            else:
                comp[str(x)] = QCheckBox("")
                comp[str(x)].setChecked(False)
                celda = QTableWidgetItem("-")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tabla1.setItem(x,2,celda) 


            cons[str(x)] = QCheckBox("")
            cons[str(x)].setChecked(v_cons[x])
            cons[str(x)].stateChanged.connect(self.state_changed)
            self.tabla1.setCellWidget(x,3,cons[str(x)])

            if nom_cdr[x]!="-":
                posi[str(x)] = QCheckBox("")
                posi[str(x)].setChecked(v_posi[x])
                posi[str(x)].stateChanged.connect(self.state_changed)
                self.tabla1.setCellWidget(x,4,posi[str(x)])
            else:
                posi[str(x)] = QCheckBox("")
                posi[str(x)].setChecked(False)
                celda = QTableWidgetItem("-")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tabla1.setItem(x,4,celda)                   

            temp[str(x)] = QCheckBox("")
            temp[str(x)].setChecked(v_temp[x])
            temp[str(x)].stateChanged.connect(self.state_changed)
            self.tabla1.setCellWidget(x,5,temp[str(x)])

            if nom_cdr[x]!="-":
                tema[str(x)] = QCheckBox("")
                tema[str(x)].setChecked(v_tema[x])
                tema[str(x)].setEnabled(False)
                tema[str(x)].stateChanged.connect(self.state_changed)
                self.tabla1.setCellWidget(x,6,tema[str(x)])
            else:
                tema[str(x)] = QCheckBox("")
                tema[str(x)].setChecked(False)
                celda = QTableWidgetItem("-")
                celda.setTextAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
                self.tabla1.setItem(x,6,celda)   
         
            usab[str(x)] = QCheckBox("")
            usab[str(x)].setChecked(v_usab[x])
            usab[str(x)].setEnabled(False)
            usab[str(x)].stateChanged.connect(self.state_changed)
            self.tabla1.setCellWidget(x,7,usab[str(x)])

    # Funcion para desactivar el menu de evaluación si se ha cambiado la seleccion de los elementos de calidad a evaluar
    def state_changed(self, int):
        self.tabWidget.setTabEnabled(4,False)              
       
    # Funcion para guardar los item de la evaluacion de calidad seleccionados por el usuario.     
    def iniciar_val(self):
        #print(self.sender().objectName())
        self.tabWidget.setTabEnabled(4,True)       
        self.tabWidget.setCurrentIndex(4)      
        self.rel_val.clear()

        nom_cde_a=""
        iso_archivo = str(ruta)+'/Iso19157.txt'
        f = open (iso_archivo, 'w')
        linea = "CDE,CDR,COMP,CONS,POSI,TEMP,TEMA,USAB\n"
        f.write(linea)
 
        for x in range(len(nom_cde)):
            linea = nom_cde[x] + "," + nom_cdr[x] + "," + str(comp[str(x)].isChecked()) + "," + str(cons[str(x)].isChecked()) + "," + str(posi[str(x)].isChecked()) + "," + str(temp[str(x)].isChecked()) + "," + str(tema[str(x)].isChecked()) + "," + str(usab[str(x)].isChecked()) + "\n"
            f.write(linea)
        
        f.close()
        
        self.iniciar_car()

    # Funcion para guardar los item de la evaluacion de calidad seleccionados por el usuario.      
    def iniciar_car(self):
        #print(self.sender().objectName())
        iso_archivo = str(ruta)+'/Iso19157.txt'

        self.bt_resultado.setEnabled(False)
        
        if os.stat(iso_archivo).st_size != 0:
            f = open (iso_archivo, 'r')
            cont = pd.read_csv(f)
            f.close()
            global v_comp
            v_comp = cont['COMP'].tolist()
            global v_cons
            v_cons = cont['CONS'].tolist()
            global v_posi
            v_posi = cont['POSI'].tolist()
            global v_temp
            v_temp = cont['TEMP'].tolist()
            global v_tema
            v_tema = cont['TEMA'].tolist()
            global v_usab
            v_usab = cont['USAB'].tolist()


        if True in v_comp:
            self.bt_comp.setEnabled(True)
        if True in v_cons:
            self.bt_cons.setEnabled(True)
        if True in v_posi:
            self.bt_posi.setEnabled(True)
        if True in v_temp:
            self.bt_temp.setEnabled(True)
        if True in v_tema:
            self.bt_tema.setEnabled(True) 
        if True in v_usab:
            self.bt_usab.setEnabled(True) 

    # Funcion para la evaluacion de calidad -- CONSISTENCIA LÓGICA --
    def fun_topo(self):
        #print(self.sender().objectName())
        self.bt_cons.setStyleSheet("QPushButton {background-color: red;}")
        self.pbr_elem.setValue(5)
        #hilo_topo = threading.Thread(name='Consistencia Lógica', target=conLogica(self,capa_cde,nom_cde,ruta))
        #hilo_topo.setDaemon(True)
        #hilo_topo.start()
        
        capa_cde_cons = capa_cde.copy()
        nom_cde_cons = nom_cde.copy()
        for x in reversed(range(0,len(v_cons))):
            if v_cons[x]==False:      
                capa_cde_cons.pop(x)
                nom_cde_cons.pop(x)  

        conLogica(self,capa_cde_cons,nom_cde_cons,ruta)
        
        self.pbr_elem.setValue(100)
        self.bt_cons.setStyleSheet("QPushButton {background-color: #f0f0f0;}")  

        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        now = datetime.now()
        hoy = now.strftime('%Y/%m/%d %H:%M')
        fic = open(ruta+'/Registro.txt','a')
        fic.write('Se realizó la evaluación de calidad para el elemento Consistencia Lógica ' + str(hoy)+'\n')
        fic.close()

        if len(lista_res)>0:
            self.tabWidget.setTabEnabled(5,True)
            self.actualizar_res()

    # Funcion para la evaluacion de calidad -- COMPLECIÓN --
    def fun_comp(self):
        #print(self.sender().objectName())
        capa_cde_comp = capa_cde.copy()
        nom_cde_comp = nom_cde.copy()
        capa_cdr_comp = capa_cdr.copy()
        nom_cdr_comp = nom_cdr.copy()
        lista_key=capa_cdr_comp.keys()

        for x in reversed(range(0,len(v_comp))):
            if v_comp[x]==False:      
                capa_cde_comp.pop(x)
                nom_cde_comp.pop(x)
                if x in lista_key:
                    capa_cdr_comp.pop(x)
                nom_cdr_comp.pop(x)

        self.bt_comp.setStyleSheet("QPushButton {background-color: red;}")
        self.pbr_elem.setValue(5)
        hilo_topo = threading.Thread(name='Complecion', target=complecion(self,capa_cde_comp,capa_cdr_comp,nom_cde_comp,nom_cdr_comp,ruta))
        hilo_topo.setDaemon(True)
        hilo_topo.start()
        self.pbr_elem.setValue(100)
        self.bt_comp.setStyleSheet("QPushButton {background-color: #f0f0f0;}")  

        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        now = datetime.now()
        hoy = now.strftime('%Y/%m/%d %H:%M')
        fic = open(ruta+'/Registro.txt','a')
        fic.write('Se realizó la evaluación de calidad para el elemento Complesión ' + str(hoy)+'\n')
        fic.close()

        if len(lista_res)>0:
            self.tabWidget.setTabEnabled(5,True)
            self.actualizar_res()

    # Funcion para la evaluacion de calidad -- POSICIONAL --
    def fun_posi(self):
        #print(self.sender().objectName())
        capa_cde_posi = capa_cde.copy()
        nom_cde_posi = nom_cde.copy()
        lista_cde_posi = lista_cde.copy()
        capa_cdr_posi = capa_cdr.copy()
        nom_cdr_posi = nom_cdr.copy()
        lista_cdr_posi = lista_cdr.copy()
        lista_key=capa_cdr_posi.keys()

        for x in reversed(range(0,len(v_posi))):
            if v_posi[x]==False:      
                capa_cde_posi.pop(x)
                if x in lista_key:
                    capa_cdr_posi.pop(x)
                nom_cde_posi.pop(x)  
                nom_cdr_posi.pop(x)
                lista_cde_posi.pop(x)
                lista_cdr_posi.pop(x)

        self.bt_posi.setStyleSheet("QPushButton {background-color: red;}")
        self.pbr_elem.setValue(5)
        hilo_topo = threading.Thread(name='Posicional', target=posicional(self,capa_cde_posi,capa_cdr_posi,nom_cde_posi,nom_cdr_posi,ruta,lista_cde_posi,lista_cdr_posi))
        hilo_topo.setDaemon(True)
        hilo_topo.start()
        self.pbr_elem.setValue(100)
        self.bt_comp.setEnabled(True)
        self.bt_posi.setStyleSheet("QPushButton {background-color: #f0f0f0;}")        

        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        now = datetime.now()
        hoy = now.strftime('%Y/%m/%d %H:%M')
        fic = open(ruta+'/Registro.txt','a')
        fic.write('Se realizó la evaluación de calidad para el elemento Exactitud posicional ' + str(hoy)+'\n')
        fic.close()

        if len(lista_res)>0:
            self.tabWidget.setTabEnabled(5,True)
            self.actualizar_res()

    # Funcion para la evaluacion de calidad -- CONSISTENCIA TEMPORAL --
    def fun_temp(self):
        #print(self.sender().objectName())
        capa_cde_temp = capa_cde.copy()
        nom_cde_temp = nom_cde.copy()
        
        for x in reversed(range(0,len(v_temp))):
            if v_temp[x]==False:      
                capa_cde_temp.pop(x)
                nom_cde_temp.pop(x)  
                
        self.bt_temp.setStyleSheet("QPushButton {background-color: red;}")
        self.pbr_elem.setValue(5)
        caltemporal(self,capa_cde_temp,nom_cde_temp,ruta)
        self.pbr_elem.setValue(100)
        self.bt_temp.setStyleSheet("QPushButton {background-color: #f0f0f0;}")  
   
        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        now = datetime.now()
        hoy = now.strftime('%Y/%m/%d %H:%M')
        fic = open(ruta+'/Registro.txt','a')
        fic.write('Se realizó la evaluación de calidad para el elemento Calidad Temporal ' + str(hoy)+'\n')
        fic.close()

        if len(lista_res)>0:
            self.tabWidget.setTabEnabled(5,True)
            self.actualizar_res()

    def ver_result_cons(self):
        resultado = str(ruta)+'/Resultados/Consistencia_logica.html'
        webbrowser.open(resultado, new=0, autoraise=True)

    def ver_result_comp(self):
        resultado = str(ruta)+'/Resultados/Complecion.html'
        webbrowser.open(resultado, new=0, autoraise=True)

    def ver_result_temp(self):
        resultado = str(ruta)+'/Resultados/Calidad_temporal.html'
        webbrowser.open(resultado, new=0, autoraise=True)

    def ver_result_posi(self):
        resultado = str(ruta)+'/Resultados/Calidad_posicional.html'
        webbrowser.open(resultado, new=0, autoraise=True)

    def limpiar(self):
        self.rel_val.clear()

    def ayudas_in(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#resumen')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_cd(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#conjunto')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_vl(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#validar')
        webbrowser.open(ruta_help, new=0, autoraise=True)
    
    def ayudas_elem(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#elementos')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_log(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#logica')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_com(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#complesion')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_posi(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#posicional')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_temp(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#temporal')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_tema(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#tematica')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def ayudas_usab(self):
        ruta_help = os.path.join(os.path.dirname(__file__), r'help\index.html#usabilidad')
        webbrowser.open(ruta_help, new=0, autoraise=True)

    def actualizar_res(self):
        ubi = ruta+"/Resultados"
        contenido = os.listdir(ruta+"/Resultados")
        lista_res = []
        for fichero in contenido:
            if os.path.isfile(os.path.join(ubi, fichero)) and fichero.endswith('.html'):
                lista_res.append(fichero)

        if 'Consistencia_logica.html' in lista_res:
            self.bt_cons_2.setEnabled(True)

        if 'Complecion.html' in lista_res:
            self.bt_comp_2.setEnabled(True)

        if 'Calidad_temporal.html' in lista_res:
            self.bt_temp_2.setEnabled(True)

        if 'Calidad_posicional.html' in lista_res:
            self.bt_posi_2.setEnabled(True)