from datos.Config import ConfigManager
import dearpygui.dearpygui as dpg
from log_register.Register import Register
import logica.controladores.feature_extractor_controller as controlador

config = ConfigManager()
slider_features = None

registro = Register()

is_updating = True

def model_matcher_is_configured():
    for checkbox_tag in ["exhaustive", "sequential", "spatial", "transitive", "vocab_tree"]:
        if dpg.get_value(checkbox_tag):
            return True
        
    return False
        
def aabb_scale_is_configured():
    for val in ["1", "2", "4", "8", "16", "32", "64", "128"]:
        if dpg.get_value(val):
            return True
        
    return False

def set_model_matcher(sender):
    # Desmarcamos todos los otros checkboxes
    for checkbox_tag in ["exhaustive", "sequential", "spatial", "transitive", "vocab_tree"]:
        if checkbox_tag != sender:
            dpg.set_value(checkbox_tag, False)

    # Actualizamos el modelo matcher global
    controlador.set_model_matcher(sender)

    registro.append_config("TIPO_RECONOCIMIENTO", sender)

def set_abb_scale(sender):
    for val in ["1", "2", "4", "8", "16", "32", "64", "128"]:
        if val != sender:
            dpg.set_value(val, False)

	# Actualizamos el aabb scale global
    controlador.set_aabb_scale(int(sender))
     
    registro.append_config("ESCALA_AABB", sender)

# Al seleccionar carpeta de Caracteristicas
	# Se inicializa la carpeta de la base de datos
	# Se inicializa la carpeta base (donde se guarda el .db)
	# Se inicializa el archivo registro .json
def select_database_folder_callback():
    result, folder = controlador.seleccionar_carpeta()

    if result == 0:
        config.set_base_folder(folder)
        config.set_dir_database(folder)
        
        dpg.configure_item("folder_database", default_value=config.DIR_DATABASE)

        registro.append_config("DIR_ACT", config.DIR_ACT)
        registro.append_config("DIR_DATABASE", config.DIR_DATABASE)

def main_view(parent):
    global slider_features
    controlador.init_output_view()

    grupo_general = dpg.add_group(parent=parent, tag="feature_extraction", show=True)

    dpg.add_spacer(height=20, parent=grupo_general)
    with dpg.group(horizontal=False, show=True, parent=grupo_general, tag="input_fe"):
        dpg.add_input_text(label="Working Folder", show=True, default_value=config.DIR_DATABASE, enabled=False, tag="folder_database")
        dpg.add_spacer(height=5)
        dpg.add_button(label="Select Folder", show=True, callback=select_database_folder_callback)

    dpg.add_spacer(height=10, show=True, parent=grupo_general)

    with dpg.group(horizontal=False, show=True, tag="main_options_matcher", parent=grupo_general):
        dpg.add_text("Recognition Type:", show=True)

        with dpg.group(horizontal=True, show=True, tag="options_matcher"):
            dpg.add_checkbox(label="Exhaustive", default_value=is_tipo_reconocimiento_set("exhaustive"), show=True, callback=set_model_matcher, tag="exhaustive")
            dpg.add_checkbox(label="Sequential", default_value=is_tipo_reconocimiento_set("sequential"), show=True, callback=set_model_matcher, tag="sequential")
            dpg.add_checkbox(label="Spatial", default_value=is_tipo_reconocimiento_set("spatial"), show=True, callback=set_model_matcher, tag="spatial")
            dpg.add_checkbox(label="Transitive", default_value=is_tipo_reconocimiento_set("transitive"), show=True, callback=set_model_matcher, tag="transitive")
            dpg.add_checkbox(label="Vocab Tree", default_value=is_tipo_reconocimiento_set("vocab_tree"), show=True, callback=set_model_matcher, tag="vocab_tree")

    dpg.add_spacer(height=10, show=True, parent=grupo_general)

    with dpg.group(horizontal=True, show=True, tag="options_aabb", parent=grupo_general):
        dpg.add_text("AABB Scale:", show=True)
        dpg.add_checkbox(label="1", default_value=is_escala_aabb_set(1), show=True, callback=set_abb_scale, tag="1")
        dpg.add_checkbox(label="2", default_value=is_escala_aabb_set(2), show=True, callback=set_abb_scale, tag="2")
        dpg.add_checkbox(label="4", default_value=is_escala_aabb_set(4), show=True, callback=set_abb_scale, tag="4")
        dpg.add_checkbox(label="8", default_value=is_escala_aabb_set(8), show=True, callback=set_abb_scale, tag="8")
        dpg.add_checkbox(label="16", default_value=is_escala_aabb_set(16), show=True, callback=set_abb_scale, tag="16")
        dpg.add_checkbox(label="32", default_value=is_escala_aabb_set(32), show=True, callback=set_abb_scale, tag="32")
        dpg.add_checkbox(label="64", default_value=is_escala_aabb_set(64), show=True, callback=set_abb_scale, tag="64")
        dpg.add_checkbox(label="128", default_value=is_escala_aabb_set(128), show=True, callback=set_abb_scale, tag="128")
	
    dpg.add_spacer(height=10, show=True, parent=grupo_general)

    with dpg.group(horizontal=True, show=True, parent=grupo_general):
        dpg.add_button(label="Extract Features", show=True, callback=feature_extraction_callback)
    
    dpg.add_spacer(height=20, show=True, parent=grupo_general)

    dpg.add_separator(show=True, parent=grupo_general)

    dpg.add_spacer(height=20, show=True, parent=grupo_general)

    dpg.add_text("Opciones Keyoints", show=True, parent=grupo_general)
    with dpg.group(horizontal=True, show=True, parent=grupo_general):
        dpg.add_button(label="Save Images with Keypoints", show=True, callback=save_images_with_keypoints)
        dpg.add_button(label="Load Images with Keypoints", show=True, callback=cargar_imagenes)

    dpg.add_spacer(height=10, show=True, parent=grupo_general)

    dpg.add_text("Matches Options", show=True, parent=grupo_general)
    with dpg.group(horizontal=True, show=True, parent=grupo_general):
        dpg.add_button(label="Save Images with Matches", show=True, callback=save_images_with_matches)
        dpg.add_button(label="Load Images with Matches", show=True, callback=cargar_imagenes_matches)

    dpg.add_spacer(height=10, show=True, parent=grupo_general)

    with dpg.group(horizontal=False, show=True, tag="imagenes_features", parent=grupo_general):
        dpg.add_text("Images with keypoints:", show=True)

    with dpg.group(horizontal=False, show=True, tag="imagenes_matches", parent=grupo_general):
        dpg.add_text("Images with matches:", show=True)

    with dpg.item_handler_registry(show=False, tag="handler_extract") as handler_extractor:
        dpg.add_item_visible_handler(callback=update_data)

    dpg.bind_item_handler_registry("feature_extraction", "handler_extract")

def update_data():
    configure_tipo_reconocimiento()
    configure_escala_aabb()
    dpg.configure_item("folder_database", default_value=config.DIR_DATABASE)


def configure_tipo_reconocimiento():
    for checkbox_tag in ["exhaustive", "sequential", "spatial", "transitive", "vocab_tree"]:
        dpg.set_value(checkbox_tag, is_tipo_reconocimiento_set(checkbox_tag))

def configure_escala_aabb():
    for val in ["1", "2", "4", "8", "16", "32", "64", "128"]:
        dpg.set_value(val, is_escala_aabb_set(val))

def is_tipo_reconocimiento_set(type):
    return config.TIPO_RECONOCIMIENTO == type

def is_escala_aabb_set(scale):
    return str(config.ESCALA_AABB) == scale

def hide_view():
	dpg.hide_item("feature_extraction")
     
def feature_extraction_callback():
    # Comprobar si se ha seleccionado un tipo de reconocimiento
    if not model_matcher_is_configured():
        controlador.set_output("You must select a type of recognition.")
        return
    
    # Comprobar si se ha seleccionado una escala AABB
    if not aabb_scale_is_configured():
        controlador.set_output("You must select an AABB scale.")
        return
    
    controlador.init_feature_extraction()

    registro.append_config("TIPO_RECONOCIMIENTO", controlador.get_model_matcher())
    registro.append_config("ESCALA_AABB", controlador.get_aabb_scale())

def save_images_with_keypoints():
    controlador.save_images_with_keypoints()

def cargar_imagenes():
    controlador.load_images_with_keypoints()

def save_images_with_matches():
    controlador.save_images_with_matches()

def cargar_imagenes_matches():
    controlador.load_images_with_matches()

def show_view():
    global is_updating
    is_updating = False
    
    update_data()
    is_updating = True

    dpg.show_item("feature_extraction")