// -------------------------------------------------------------------------------------
// xsEasyCpp
// Demo de Objeto ListaArbolOpciones
// g++ -g ListaArbolOpciones.cpp -lxseasycpp -LC:/msys64/mingw64/lib -lgtk-3 -lgdk-3 -lz -lgdi32 -limm32 -lshell32 -lole32 -Wl,-luuid -lwinmm -ldwmapi -lsetupapi -lcfgmgr32 -lpangowin32-1.0 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0 -o ListaArbolOpciones.exe
// g++ -g ListaArbolOpciones.cpp %PKG-XSEASYCPP% -o ListaArbolOpciones.exe
// -------------------------------------------------------------------------------------

// Incluye las librería de xsWindows
#include "include/xsEasyCpp.hpp"

// Función para crear el Arbol del Modelo del Primer Combo
Estatica xsModeloArbol* fnCrearModeloDatos (Vacio);

// Detiene el Ciclo Principal iniciado por gtk_main cuando la ventana es destruida
Estatica Vacio fnSalida(xsObjetoGUI* ventana, xsApuntador datos);

// Función para controlar el Cierre de una Ventana
Estatica Entero fnCierre(xsObjetoGUI* ventana, xsEvento *evento);

// Función para controlar la selección en el Opcion
Vacio fnOpcionSeleccionada(xsObjetoGUI* objeto, Entero* columna);

// Función para Insertar el Elemento Seleccionado
Vacio fnInsertar(xsObjetoGUI* boton, xsApuntador lista);

// Función para modificar el Elemento Seleccionado
Vacio fnModificarSeleccionado(xsObjetoGUI* boton, xsApuntador lista);

// Función para modificar por Elemento Indicado
Vacio fnModificarElemento(xsObjetoGUI* boton, xsApuntador lista);

// Función para eliminar el Elemento Seleccionado
Vacio fnEliminarSeleccionado(xsObjetoGUI* boton, xsApuntador lista);

// Función para eliminar Elemento
Vacio fnEliminarElemento(xsObjetoGUI* boton, xsApuntador lista);

// Función para Seleccionar
Vacio fnSeleccionar(xsObjetoGUI* boton, xsApuntador lista);

// Función para DesSeleccionar el primer Elemento
Vacio fnDesSeleccionar(xsObjetoGUI* boton, xsApuntador lista);

// Función para eliminar todos
Vacio fnEliminarTodos(xsObjetoGUI* boton, xsApuntador lista);

// Función para eliminar todos
Vacio fnDesplegarTodos(xsObjetoGUI* boton, xsApuntador lista);

// Función para Desplegar por Elemento
Vacio fnDesplegarPorElemento(xsApuntador lista, xsCadena elemento);

// La variable para la entrada
xsEntrada entDato;

// Función principal de xsEasyWindow
xsPrincipal
{
  // Iniciamos xsEasyWindows
  xsAppInicia;

  // Definimos un objeto de la Clase xsVentana
  xsVentana oVentana(XS_CON_CONTENEDOR);

  // Estableciendo un tamaño para la Ventana                                  
  oVentana.colocarDimensiones(400,400);

  // Centrar
  oVentana.centrar();

  // Coloca el Título
  oVentana.colocarTitulo("xsEasyCpp Demo Lista Arbol Opciones");

  // Establece el Icono
  oVentana.colocarIcono("img/js.ico");

  // Establecemos el Bordel del Contenedor
  oVentana.colocarBordeContenedor(10);
    
  // Establece la función de Salida
  oVentana.colocarFuncionSalida(XS_FUNCION_RETORNO (fnSalida));

  // Establece la función de Cierre
  oVentana.colocarFuncionCierre(XS_FUNCION_RETORNO (fnCierre));

  // Preparamos datos para insertar en la Opcion
  xsArbolIterador iterador;
  xsModeloArbol*  modeloMensajes;

  // Crea los modelos
  modeloMensajes = fnCrearModeloDatos ();

  // Declaramos una opcion
  xsListaArbolOpciones oListaArbolDatos;
  oListaArbolDatos.crear();

  // Establece el Modelo para la Opcion de Sistemas Operativos
  oListaArbolDatos.colocarModelo(modeloMensajes);
  xsObjeto_desreferenciar(modeloMensajes);

  // Visualiza la Columna de Capitales
  oListaArbolDatos.visualizarColumna(xsListaArbolOpciones::tipoColumna::Texto,"text",0);
  
  // Conecta la Señal del Opcion
  Entero columnaTexto = 0;
  oListaArbolDatos.conectarSenal(XS_EVENTO_CAMBIADO,XS_FUNCION_RETORNO (fnOpcionSeleccionada),&columnaTexto);
  
  // Agregamos la Lista al Contenedor
  oVentana.agregarAlContenedor(oListaArbolDatos.obtenerManejador());

  // Creamos una Entrada
  entDato.crear("Capture dato Insertar-Modificar");

  // Agregamos la Entrada al Contenedor
  oVentana.agregarAlContenedor(entDato.obtenerManejador());

  // Creamos un botón de Insertar
  xsBoton btnInsertar("Insertar",FALSO);

  // Capturamos la señal del Botón de Insertar
  btnInsertar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnInsertar),oListaArbolDatos.obtenerManejador());

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnInsertar.obtenerManejador());

  // Creamos un botón de Seleccionar
  xsBoton btnSeleccionar("Seleccionar",FALSO);

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnSeleccionar.obtenerManejador());

  // Capturamos la señal del Botón de Seleccionar
  btnSeleccionar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnSeleccionar),oListaArbolDatos.obtenerManejador());

  // Creamos un botón de Modificar
  xsBoton btnModificarSeleccionado("Modificar el Dato Seleccionado",FALSO);

  // Capturamos la señal del Botón de Modificar
  btnModificarSeleccionado.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnModificarSeleccionado),oListaArbolDatos.obtenerManejador());

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnModificarSeleccionado.obtenerManejador());

  // Creamos un botón de Modificar
  xsBoton btnModificarElemento("Modificar Elemento con 'Modificado'",FALSO);

  // Capturamos la señal del Botón de Modificar
  btnModificarElemento.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnModificarElemento),oListaArbolDatos.obtenerManejador());

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnModificarElemento.obtenerManejador());

  // Creamos un botón de Eliminar
  xsBoton btnEliminarSeleccionado("Eliminar Seleccionado",FALSO);

  // Capturamos la señal del Botón de Eliminar
  btnEliminarSeleccionado.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnEliminarSeleccionado),oListaArbolDatos.obtenerManejador());

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnEliminarSeleccionado.obtenerManejador());

  // Creamos un botón de Eliminar Elemento
  xsBoton btnEliminarElemento("Eliminar Elemento",FALSO);

  // Capturamos la señal del Botón de Eliminar
  btnEliminarElemento.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnEliminarElemento),oListaArbolDatos.obtenerManejador());

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnEliminarElemento.obtenerManejador());

  // Creamos un botón de Eliminar Todos
  xsBoton btnEliminarTodos("Eliminar Todos",FALSO);

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnEliminarTodos.obtenerManejador());

  // Capturamos la señal del Botón de Eliminar Todos
  btnEliminarTodos.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnEliminarTodos),oListaArbolDatos.obtenerManejador());

  // Creamos un botón de Desplegar Todos
  xsBoton btnDesplegarTodos("Desplegar Todos",FALSO);

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnDesplegarTodos.obtenerManejador());

  // Capturamos la señal del Botón de Desplegar Todos
  btnDesplegarTodos.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnDesplegarTodos),oListaArbolDatos.obtenerManejador());
  
  // Creamos un botón de DesSeleccionar
  xsBoton btnDesSeleccionar("DesSeleccionar",FALSO);

  // Agregamos el botón al contenedor
  oVentana.agregarAlContenedor(btnDesSeleccionar.obtenerManejador());

  // Capturamos la señal del Botón de DesSeleccionar
  btnDesSeleccionar.conectarSenal(XS_EVENTO_CLICKED,XS_FUNCION_RETORNO (fnDesSeleccionar),oListaArbolDatos.obtenerManejador());

  // Muestra todos los objetos
  oVentana.mostrarTodo();

  // Ciclo
  xsAppCiclo;

  // Finaliza retornando 0
  retorna 0;

}


// Detiene el Ciclo Principal iniciado por gtk_main cuando la ventana es destruida
Estatica Vacio fnSalida(xsObjetoGUI* ventana, xsApuntador datos)
{
   // Llama a la función de la Librería que sale del Ciclo Main  
   xsAppSalida;
}

// Función para controlar el Cierre de una Ventana
Estatica Entero fnCierre(xsObjetoGUI* ventana, xsEvento *evento)
{
  retorna Falso; // Para que se cierre, lo contrario para que no se cierre
}

// Función para crear el Arbol para el Modelo del Combo
Estatica xsModeloArbol* fnCrearModeloDatos (Vacio)
{  
  // Variables
  xsArbolIterador iterador1, iterador2;
  xsArbolDatos*   arbol;
  Entero          indice;

  // Crea el árbol
  arbol = xsObjeto_Arbol_crear (1, XS_TIPO_CADENA);
  
  // Retorna el árbol como Modelo
  retorna XS_ARBOL_MODELO (arbol);
}

// Función para controlar opción Seleccionada
Vacio fnOpcionSeleccionada(xsObjetoGUI* objeto, Entero* columna)
{  
  // Crea un objeto opcionTexto
  xsListaArbolOpciones lista;
  lista.crear();

  // Le asigna el manejador
  lista.asignarManejador(objeto);

  // Coloca el Texto en la Entrada
  entDato.colocarTexto(lista.obtenerTextoSeleccionado(*columna));
  
  // Imprime el indice
  xsImprimir("Indice del Seleccionado");
  xsImprimir(lista.obtenerIndiceSeleccionado());

  xsImprimir("Nivel del Seleccionado");
  xsImprimir(lista.obtenerNivelSeleccionado());
}

// Función para Insertar
Vacio fnInsertar(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));
   
   // Define un vector de datos para agrega un Renglon
   vector<xsListaArbolOpciones::renglonListaArbolOpciones> arrRenglon;

   // Defino un dato para establecer el renglon
   xsListaArbolOpciones::renglonListaArbolOpciones renglon;

   // Establezco lo que tendrá el renglón
   renglon.tipo = xsListaArbolOpciones::tipoColumna::Texto;
   renglon.posicion = 0;
   renglon.texto = entDato.obtenerTexto();
   
   // Agrega el dato al arreglo
   arrRenglon.push_back(renglon);

   // Verifica que haya capturado algo
   si (entDato.obtenerLongitudTexto()>0)
   {
      // Inserta
      lstTemporal.insertar(arrRenglon);

      xsImprimir("Longitud despues de Insertar ...");
      xsImprimir(lstTemporal.longitud(""));

      // Limpia la entrada y coloca el foco
      entDato.limpiar();
      entDato.colocarFoco();
   }
   deOtroModo
      xsVentana::mensajeInformacion("xsEasyCpp - Demo ListaArbolOpciones","Capture dato para insertar");
}

// Función para modificar el Seleccionado
Vacio fnModificarSeleccionado(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Verifica que haya capturado algo
   si (entDato.obtenerLongitudTexto()>0)
      // Modifica el Seleccionado
      lstTemporal.modificarSeleccionado(0,entDato.obtenerTexto());
   deOtroModo
      xsVentana::mensajeInformacion("xsEasyCpp - Demo ListaArbolOpciones","Capture dato para modificar");
}

// Función para modificar el Elemento
Vacio fnModificarElemento(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Verifica que haya capturado algo
   si (entDato.obtenerLongitudTexto()>0)
      // Modifica el Seleccionado
      lstTemporal.modificarElemento(entDato.obtenerTexto(),0,"Modificado");
   deOtroModo
      xsVentana::mensajeInformacion("xsEasyCpp - Demo ListaArbolOpciones","Capture dato para modificar");
}

// Función para eliminar el Seleccionado
Vacio fnEliminarSeleccionado(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Modifica el Seleccionado
   lstTemporal.eliminarSeleccionado();
}

// Función para eliminar el Primero
Vacio fnEliminarElemento(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Verifica que haya algo en la Entrada
   si (entDato.obtenerLongitudTexto()>0)
      // Modifica el Seleccionado
      lstTemporal.eliminar(entDato.obtenerTexto());
   deOtroModo
      xsVentana::mensajeInformacion("xsEasyCpp - Demo ListaArbolOpciones","Capture elemento a Eliminar (nivel:indice)");   
}


// Función para Seleccionar el Primero
Vacio fnSeleccionar(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Verifica que haya algo en la entrada
   si (entDato.obtenerLongitudTexto()>0)
   {
      // Selecciona el Primero
      lstTemporal.seleccionar(entDato.obtenerTexto());
   }
   deOtroModo
      xsVentana::mensajeInformacion("xsEasyCpp - Demo ListaArbolOpciones","Capture elemento a Seleccionar (nivel:indice)");   
}

// Función para DesSeleccionar
Vacio fnDesSeleccionar(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Selecciona el Primero
   lstTemporal.desseleccionar();

   xsImprimir("Longitud despues de DesSeleccionar Todos:");
   xsImprimir(lstTemporal.longitud(""));
}

// Función para eliminar Todos
Vacio fnEliminarTodos(xsObjetoGUI* boton, xsApuntador lista)
{
   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

   // Elimina todos
   lstTemporal.limpiar();

   // Imprime
   xsImprimir("Longitud despues de Borrar Todos:");
   xsImprimir(lstTemporal.longitud(""));
}

// Función para Desplegar Todos
Vacio fnDesplegarTodos(xsObjetoGUI* boton, xsApuntador lista)
{
   // Llama a la Función que busca por elemento
   fnDesplegarPorElemento(lista,"");   
}

// Función para desplegar los Elementos de un Nodo
Vacio fnDesplegarPorElemento(xsApuntador lista, xsCadena elemento)
{
   // Para obtener el texto
   Caracter* texto;

	// Variable para la ruta (indice)
	xsCadena ruta;

	// Variable para el Indice
	Entero indice;

	// Variable para el Modelo
	xsModeloArbol*  modelo;

    // Variable para el Iterador
	xsArbolIterador iterador;

	// Verifica si es un elemento
	si (elemento.size()>0)
	   // Le agrega los ":"
	   elemento=elemento+":";

   // Lista Temporal
   xsListaArbolOpciones lstTemporal;

   // Asignamos los manejadores
   lstTemporal.asignarManejador(XS_OBJETOGUI(lista));

	// Obtiene el Modelo
   modelo = xsObjeto_Opcion_obtener_modelo(XS_OPCION(lstTemporal.obtenerManejador()));
		
	// Ciclo para verificar cada dato
	for (indice=0;VERDAD;indice++)
	{
		// Obtiene la ruta por el indice
		ruta = elemento+to_string(indice);	
	
   	// Verifica que NO obtuvo algo
		si (NO xsObjeto_Arbol_obtener_iterador_cadena (modelo, &iterador,ruta.c_str()))
		{
			// Sale del Ciclo
		    salirCiclo;
		}
      deOtroModo
      {
         xsObjeto_Arbol_obtener_modelo(modelo, &iterador, 0, &texto,  -1);
         xsVentana::mensajeInformacion("xsEasyCpp Demo ListaArbolOpciones",texto);
      }
		
        // Verifica si tiene hijos
	    si (xsObjeto_Arbol_obtener_iterador_cadena (modelo, &iterador,(ruta+":0").c_str()))
		    // Se ejecuta recursividad
		    fnDesplegarPorElemento(lista,ruta.c_str());
	}	

	// Devuelve el Contador de Elementos
	retorna;

}