package docen_servlet_applet;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import java.net.URL;
import java.net.*;
import java.io.*;
import java.util.*;

/***********************************************************************************
 * Applet que recibe de una conexión con servlet un vector de objetos. Los objetos se
 * consiguen mediante una consulta a base de datos.
 * Los objetos recibidos se representan en un arbol (JTree).
 * La clase utiliza:
 * - Clase de utilidades, para obtener url, imagenes, etc. (Utilidades)
 * - Clase renderer del arbol (BasicoRenderer)
 * - Clase de dialogo con barra de progreso (BasicoDialogoProgreso)
 ***********************************************************************************/
public class BasicoApplet extends JApplet {

   Utilidades util = new Utilidades();    // Clase de utilidades

   //// Panel de scroll y su arbol
   JScrollPane pnlSArbol;
   JTree arbol = new JTree();

   /********** Inicializar el applet **********/
   public void init() {
      try { jbInit(); }
      catch(Exception e) {  e.printStackTrace(); }
   }

   /****************************************************************************
    *  Inicializar componentes
    ****************************************************************************/
   private void jbInit() throws Exception {

      //// Mostrar ventana de dialogo con barra de progreso
      BasicoDialogoProgreso dlg = new BasicoDialogoProgreso("Cargando datos. Espere unos instantes");
      dlg.show();

      //// El path donde está el archivo de propiedades es host + 'propiedades/paquete'
      String pathPropiedades = getCodeBase().getProtocol() + "://" + getCodeBase().getHost() + ":" +
				getCodeBase().getPort() +"/propiedades/docen_servlet_applet/";
      util.cargarPropiedades( pathPropiedades );

      //// Si no hay error al cargar las propiedades, continuo
      if (util.mensajeError == null) {

	 //// Asigno arbol a su panel de scroll
	 pnlSArbol = new JScrollPane( arbol, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				      JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

	 //// Configuro arbol
	 //// Modo de selección simple y muestra manejadores (iconos +/- para expandir/colapsar)
	 arbol.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	 arbol.setShowsRootHandles( true );
	 arbol.setCellRenderer( new BasicoRenderer( util ));  // Renderer
	 cargarArbol( arbol );                                // Inserta nodos

	 //// Añadir componentes al contenedor raiz
	 Container cont_raiz = getContentPane();
	 cont_raiz.setLayout( new BorderLayout() );
	 cont_raiz.add( pnlSArbol, BorderLayout.CENTER );
      }
      //// Si hubo error al cargar propiedades, aviso
      else
	 JOptionPane.showMessageDialog( getContentPane(), util.mensajeError);

      dlg.setVisible(false);  // Cierra ventana de dialogo
   }

   /************************************************************************
    * Abre una conexión de entrada con el servlet para recibir un vector de objetos.
    * Carga el vector en el modelo de datos. Al final, asigna el modelo al arbol.
    ***********************************************************************/
   public void cargarArbol( JTree a ) throws InterruptedException {

      try {

	 //// Obtengo la URL del servlet y a partir de la URL abro la conexión
	 String pathServlet = util.getHostHTTP()+"servlet/basicoservlet";
	 URL urlServlet = new URL( pathServlet );
	 URLConnection conServlet = urlServlet.openConnection(); // Abro conexión con url
	 conServlet.setUseCaches( false );                       // El navegador no usa caché

	 //// Creamos un stream de entrada a partir de la conexión. Recibimos vector de objetos.
	 ObjectInputStream streamEntrada = new ObjectInputStream (conServlet.getInputStream());
	 Vector filas = (Vector) streamEntrada.readObject();  // Obtenemos objetos
	 streamEntrada.close();

	 //// Si el primer elemento del vector es un String, esto significa que se ha
	 //// producido un error. Muestro el string y salgo.
	 Object ob = filas.get(0);
	 if ( ob instanceof String ) {
	    JOptionPane.showMessageDialog( getContentPane(), "Recibido en applet un mensaje de error: "+
					   ob.toString());
	    return;
	 }

	 //// Creo nodo raiz y modelo de arbol
	 DefaultMutableTreeNode nodoRaiz = new DefaultMutableTreeNode( "Clientes" );
	 DefaultTreeModel modeloArbol = new DefaultTreeModel( nodoRaiz );

	 DefaultMutableTreeNode nodoNuevo;

	 //// Recorremos el vector para añadir nodos. Cada nodo almacena un objeto del
	 //// vector recibido
	 for (int i=0; i < filas.size(); i++) {
	    nodoNuevo = new DefaultMutableTreeNode( filas.get(i) ); // El nuevo nodo contiene el objeto
	    nodoRaiz.add( nodoNuevo );  // Añado el nuevo nodo a su nodo padre (nodo raiz)
	    //Thread.sleep(500); // Para simular "tardanza"
	 }

	 a.setModel( modeloArbol ); // Asigno modelo al arbol
      }
      catch (MalformedURLException em) { // Hija de IOException
	 JOptionPane.showMessageDialog( this.getContentPane(), "Error en Applet. URL INCORRECTA. " +
					em.getMessage());
      }
      catch (IOException eio) { // Hija de Exception
 	 JOptionPane.showMessageDialog( this.getContentPane(),"Error en Applet. EXCEPCION IO. " +
					 eio.getMessage());
      }
      catch (ClassNotFoundException ec) { // Hija de Exception
 	 JOptionPane.showMessageDialog( this.getContentPane(),"Error en Applet. CLASE NO ENCONTRADA. " +
					 ec.getMessage());
      }
      catch (Exception ex) {
 	 JOptionPane.showMessageDialog( this.getContentPane(),"Error en Applet. EXCEPCION  GENERICA. " +
					 ex.getMessage());
      }
   }
}
