package Formularios;

import com.digitalpersona.onetouch.DPFPDataPurpose;
import com.digitalpersona.onetouch.DPFPFeatureSet;
import com.digitalpersona.onetouch.DPFPGlobal;
import com.digitalpersona.onetouch.DPFPSample;
import com.digitalpersona.onetouch.DPFPTemplate;
import com.digitalpersona.onetouch.capture.DPFPCapture;
import com.digitalpersona.onetouch.capture.event.DPFPDataAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPDataEvent;
import com.digitalpersona.onetouch.capture.event.DPFPErrorAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPErrorEvent;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusEvent;
import com.digitalpersona.onetouch.capture.event.DPFPSensorAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPSensorEvent;
import com.digitalpersona.onetouch.processing.DPFPEnrollment;
import com.digitalpersona.onetouch.processing.DPFPFeatureExtraction;
import com.digitalpersona.onetouch.processing.DPFPImageQualityException;
import com.digitalpersona.onetouch.verification.DPFPVerification;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import BD.ConexionBD;
import conectionDB.ConectionDB;
import entidades.Empleado;
import presentacion.Log;
import presentacion.VentanaPrincipal;

import com.digitalpersona.onetouch.verification.DPFPVerificationResult;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.GroupLayout.Alignment;
import javax.swing.GroupLayout;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.TitledBorder;
import java.awt.Color;

/**
 *
 * @author ING JARC
 */
public class VerificarHuella extends javax.swing.JDialog {

	/** Creates new form CapturaHuella */
	public VerificarHuella() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, "Imposible modificar el tema visual", "Lookandfeel invÃ¡lido.",
					JOptionPane.ERROR_MESSAGE);
		}
		initComponents();
		txtArea.setEditable(false);
	}

	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed" desc="Generated
	// Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		panHuellas = new javax.swing.JPanel();
		jPanel1 = new javax.swing.JPanel();
		lblImagenHuella = new javax.swing.JLabel();
		panBtns = new javax.swing.JPanel();
		jPanel2 = new javax.swing.JPanel();
		btnIdentificar = new javax.swing.JButton();
		jPanel4 = new javax.swing.JPanel();
		jScrollPane1 = new javax.swing.JScrollPane();
		txtArea = new javax.swing.JTextArea();
		jPanel3 = new javax.swing.JPanel();

		setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
		setTitle("Huellas Dactilares - J@RC 2011 4500 Fingerprint Reader DP");
		setResizable(false);
		addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent evt) {
				formWindowClosing(evt);
			}

			public void windowOpened(java.awt.event.WindowEvent evt) {
				formWindowOpened(evt);
			}
		});

		panHuellas.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Huella Digital Capturada",
				javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
		panHuellas.setPreferredSize(new java.awt.Dimension(400, 270));
		panHuellas.setLayout(new java.awt.BorderLayout());

		jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
		jPanel1.setLayout(new java.awt.BorderLayout());
		jPanel1.add(lblImagenHuella, java.awt.BorderLayout.CENTER);

		panHuellas.add(jPanel1, java.awt.BorderLayout.CENTER);

		getContentPane().add(panHuellas, java.awt.BorderLayout.NORTH);

		panBtns.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Coloca tu indice derecho en el lector de huellas", TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0, 0)));
		panBtns.setPreferredSize(new java.awt.Dimension(400, 190));
		panBtns.setLayout(new java.awt.BorderLayout());

		jPanel2.setPreferredSize(new java.awt.Dimension(366, 90));

		btnIdentificar.setText("Identificar");
		btnIdentificar.setPreferredSize(new java.awt.Dimension(71, 23));
		btnIdentificar.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				btnIdentificarActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
		jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING)
				.addGroup(jPanel2Layout.createSequentialGroup().addGap(169)
						.addComponent(btnIdentificar, GroupLayout.PREFERRED_SIZE, 102, GroupLayout.PREFERRED_SIZE)
						.addContainerGap(170, Short.MAX_VALUE)));
		jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING).addGroup(Alignment.LEADING,
				jPanel2Layout.createSequentialGroup().addGap(26)
						.addComponent(btnIdentificar, GroupLayout.PREFERRED_SIZE, 39, GroupLayout.PREFERRED_SIZE)
						.addContainerGap(25, Short.MAX_VALUE)));
		jPanel2.setLayout(jPanel2Layout);

		panBtns.add(jPanel2, java.awt.BorderLayout.NORTH);

		jPanel4.setLayout(new java.awt.BorderLayout());

		txtArea.setColumns(20);
		txtArea.setFont(new java.awt.Font("Lucida Sans", 1, 10));
		txtArea.setRows(5);
		jScrollPane1.setViewportView(txtArea);

		jPanel4.add(jScrollPane1, java.awt.BorderLayout.CENTER);

		panBtns.add(jPanel4, java.awt.BorderLayout.CENTER);

		jPanel3.setPreferredSize(new java.awt.Dimension(366, 20));

		javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
		jPanel3Layout.setHorizontalGroup(
				jPanel3Layout.createParallelGroup(Alignment.TRAILING).addGap(0, 441, Short.MAX_VALUE));
		jPanel3Layout
				.setVerticalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGap(0, 20, Short.MAX_VALUE));
		jPanel3.setLayout(jPanel3Layout);

		panBtns.add(jPanel3, java.awt.BorderLayout.SOUTH);

		getContentPane().add(panBtns, java.awt.BorderLayout.SOUTH);

		java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((screenSize.width - 459) / 2, (screenSize.height - 499) / 2, 459, 499);
	}// </editor-fold>//GEN-END:initComponents

	private void btnIdentificarActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_btnIdentificarActionPerformed
		try {
			identificarHuella();
			Reclutador.clear();
		} catch (IOException ex) {
			Logger.getLogger(CapturaHuella.class.getName()).log(Level.SEVERE, null, ex);
		}
	}// GEN-LAST:event_btnIdentificarActionPerformed

	private void formWindowOpened(java.awt.event.WindowEvent evt) {// GEN-FIRST:event_formWindowOpened
		Iniciar();
		start();
		EstadoHuellas();
		// btnGuardar.setEnabled(false);
		btnIdentificar.setEnabled(true);
		// btnVerificar.setEnabled(false);
		// btnSalir.grabFocus();
	}// GEN-LAST:event_formWindowOpened

	private void formWindowClosing(java.awt.event.WindowEvent evt) {// GEN-FIRST:event_formWindowClosing
		stop();
	}// GEN-LAST:event_formWindowClosing

	// Varible que permite iniciar el dispositivo de lector de huella conectado
	// con sus distintos metodos.
	private DPFPCapture Lector = DPFPGlobal.getCaptureFactory().createCapture();

	// Varible que permite establecer las capturas de la huellas, para determina
	// sus caracteristicas
	// y poder estimar la creacion de un template de la huella para luego poder
	// guardarla
	private DPFPEnrollment Reclutador = DPFPGlobal.getEnrollmentFactory().createEnrollment();

	// Esta variable tambien captura una huella del lector y crea sus
	// caracteristcas para auntetificarla
	// o verificarla con alguna guardada en la BD
	private DPFPVerification Verificador = DPFPGlobal.getVerificationFactory().createVerification();

	// Variable que para crear el template de la huella luego de que se hallan
	// creado las caracteriticas
	// necesarias de la huella si no ha ocurrido ningun problema
	private DPFPTemplate template;
	public static String TEMPLATE_PROPERTY = "template";

	protected void Iniciar() {
		Lector.addDataListener(new DPFPDataAdapter() {
			@Override
			public void dataAcquired(final DPFPDataEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("La Huella Digital ha sido Capturada");
						ProcesarCaptura(e.getSample());
					}
				});
			}
		});

		Lector.addReaderStatusListener(new DPFPReaderStatusAdapter() {
			@Override
			public void readerConnected(final DPFPReaderStatusEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("El Sensor de Huella Digital esta Activado o Conectado");
					}
				});
			}

			@Override
			public void readerDisconnected(final DPFPReaderStatusEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("El Sensor de Huella Digital esta Desactivado o no Conectado");
					}
				});
			}
		});

		Lector.addSensorListener(new DPFPSensorAdapter() {
			@Override
			public void fingerTouched(final DPFPSensorEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("El dedo ha sido colocado sobre el Lector de Huella");
					}
				});
			}

			@Override
			public void fingerGone(final DPFPSensorEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("El dedo ha sido quitado del Lector de Huella");
					}
				});
			}
		});

		Lector.addErrorListener(new DPFPErrorAdapter() {
			public void errorReader(final DPFPErrorEvent e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						EnviarTexto("Error: " + e.getError());
					}
				});
			}
		});
	}

	public DPFPFeatureSet featuresinscripcion;
	public DPFPFeatureSet featuresverificacion;

	public void ProcesarCaptura(DPFPSample sample) {
		// Procesar la muestra de la huella y crear un conjunto de
		// caracterÃ­sticas con el propÃ³sito de inscripciÃ³n.
		featuresinscripcion = extraerCaracteristicas(sample, DPFPDataPurpose.DATA_PURPOSE_ENROLLMENT);

		// Procesar la muestra de la huella y crear un conjunto de
		// caracterÃ­sticas con el propÃ³sito de verificacion.
		featuresverificacion = extraerCaracteristicas(sample, DPFPDataPurpose.DATA_PURPOSE_VERIFICATION);

		// Comprobar la calidad de la muestra de la huella y lo aÃ±ade a su
		// reclutador si es bueno
		if (featuresinscripcion != null)
			try {
				System.out.println("Las Caracteristicas de la Huella han sido creada");
				Reclutador.addFeatures(featuresinscripcion);// Agregar las
															// caracteristicas
															// de la huella a la
															// plantilla a crear

				// Dibuja la huella dactilar capturada.
				Image image = CrearImagenHuella(sample);
				DibujarHuella(image);

				// btnVerificar.setEnabled(true);
				btnIdentificar.setEnabled(true);

			} catch (DPFPImageQualityException ex) {
				System.err.println("Error: " + ex.getMessage());
			}

			finally {
				EstadoHuellas();
				// Comprueba si la plantilla se ha creado.
				switch (Reclutador.getTemplateStatus()) {
				case TEMPLATE_STATUS_READY: // informe de Ã©xito y detiene la
											// captura de huellas
					stop();
					setTemplate(Reclutador.getTemplate());
					EnviarTexto("La Plantilla de la Huella ha Sido Creada, ya puede Verificarla o Identificarla");
					btnIdentificar.setEnabled(false);
					// btnVerificar.setEnabled(false);
					// btnGuardar.setEnabled(true);
					// btnGuardar.grabFocus();
					break;

				case TEMPLATE_STATUS_FAILED: // informe de fallas y reiniciar la
												// captura de huellas
					Reclutador.clear();
					stop();
					EstadoHuellas();
					setTemplate(null);
					JOptionPane.showMessageDialog(VerificarHuella.this,
							"La Plantilla de la Huella no pudo ser creada, Repita el Proceso",
							"Inscripcion de Huellas Dactilares", JOptionPane.ERROR_MESSAGE);
					start();
					break;
				}
			}
	}

	public DPFPFeatureSet extraerCaracteristicas(DPFPSample sample, DPFPDataPurpose purpose) {
		DPFPFeatureExtraction extractor = DPFPGlobal.getFeatureExtractionFactory().createFeatureExtraction();
		try {
			return extractor.createFeatureSet(sample, purpose);
		} catch (DPFPImageQualityException e) {
			return null;
		}
	}

	public Image CrearImagenHuella(DPFPSample sample) {
		return DPFPGlobal.getSampleConversionFactory().createImage(sample);
	}

	public void DibujarHuella(Image image) {
		lblImagenHuella.setIcon(new ImageIcon(
				image.getScaledInstance(lblImagenHuella.getWidth(), lblImagenHuella.getHeight(), Image.SCALE_DEFAULT)));
		repaint();
	}

	public void EstadoHuellas() {
		EnviarTexto("Muestra de Huellas Necesarias para Guardar Template " + Reclutador.getFeaturesNeeded());
	}

	public void EnviarTexto(String string) {
		txtArea.append(string + "\n");
	}

	public void start() {
		Lector.startCapture();
		EnviarTexto("Utilizando el Lector de Huella Dactilar ");
	}

	public void stop() {
		Lector.stopCapture();
		EnviarTexto("No se estÃ¡ usando el Lector de Huella Dactilar ");
	}

	public DPFPTemplate getTemplate() {
		return template;
	}

	public void setTemplate(DPFPTemplate template) {
		DPFPTemplate old = this.template;
		this.template = template;
		firePropertyChange(TEMPLATE_PROPERTY, old, template);
	}

	ConexionBD con = new ConexionBD();

	/*
	 * Guarda los datos de la huella digital actual en la base de datos
	 */
	public void guardarHuella() {
		// Obtiene los datos del template de la huella actual
		ByteArrayInputStream datosHuella = new ByteArrayInputStream(template.serialize());
		Integer tamañoHuella = template.serialize().length;

		// Pregunta el nombre de la persona a la cual corresponde dicha huella
		String nombre = JOptionPane.showInputDialog("Nombre:");
		try {
			// Establece los valores para la sentencia SQL
			Connection c = con.conectar(); // establece la conexion con la BD
			PreparedStatement guardarStmt = c.prepareStatement("INSERT INTO somhue(huenombre, huehuella) values(?,?)");

			guardarStmt.setString(1, nombre);
			guardarStmt.setBinaryStream(2, datosHuella, tamañoHuella);
			// Ejecuta la sentencia
			guardarStmt.execute();
			guardarStmt.close();
			JOptionPane.showMessageDialog(null, "Huella Guardada Correctamente");
			con.desconectar();
			// btnGuardar.setEnabled(false);
			// btnVerificar.grabFocus();
		} catch (SQLException ex) {
			// Si ocurre un error lo indica en la consola
			System.err.println("Error al guardar los datos de la huella.");
		} finally {
			con.desconectar();
		}
	}

	/**
	 * Verifica la huella digital actual contra otra en la base de datos
	 */
	public void verificarHuella(String nom) {
		try {
			// Establece los valores para la sentencia SQL
			Connection c = con.conectar();
			// Obtiene la plantilla correspondiente a la persona indicada
			PreparedStatement verificarStmt = c.prepareStatement("SELECT huehuella FROM somhue WHERE huenombre=?");
			verificarStmt.setString(1, nom);
			ResultSet rs = verificarStmt.executeQuery();

			// Si se encuentra el nombre en la base de datos
			if (rs.next()) {
				// Lee la plantilla de la base de datos
				byte templateBuffer[] = rs.getBytes("huehuella");
				// Crea una nueva plantilla a partir de la guardada en la base
				// de datos
				DPFPTemplate referenceTemplate = DPFPGlobal.getTemplateFactory().createTemplate(templateBuffer);
				// Envia la plantilla creada al objeto contendor de Template del
				// componente de huella digital
				setTemplate(referenceTemplate);

				// Compara las caracteriticas de la huella recientemente
				// capturda con la
				// plantilla guardada al usuario especifico en la base de datos
				DPFPVerificationResult result = Verificador.verify(featuresverificacion, getTemplate());

				// compara las plantilas (actual vs bd)
				if (result.isVerified())
					JOptionPane.showMessageDialog(null, "Las huella capturada coinciden con la de " + nom,
							"Verificacion de Huella", JOptionPane.INFORMATION_MESSAGE);
				else
					JOptionPane.showMessageDialog(null, "No corresponde la huella con " + nom, "Verificacion de Huella",
							JOptionPane.ERROR_MESSAGE);

				// Si no encuentra alguna huella correspondiente al nombre lo
				// indica con un mensaje
			} else {
				JOptionPane.showMessageDialog(null, "No existe un registro de huella para " + nom,
						"Verificacion de Huella", JOptionPane.ERROR_MESSAGE);
			}
		} catch (SQLException e) {
			// Si ocurre un error lo indica en la consola
			System.err.println("Error al verificar los datos de la huella.");
		} finally {
			con.desconectar();
		}
	}

	/**
	 * Identifica a una persona registrada por medio de su huella digital
	 */
	public void identificarHuella() throws IOException {
		try {
			// Establece los valores para la sentencia SQL
			Connection c = ConectionDB.getConection();

			// Obtiene todas las huellas de la bd
			PreparedStatement identificarStmt = c.prepareStatement("SELECT dni,nombre,apellido,cargo,huella FROM empleados");
			ResultSet rs = identificarStmt.executeQuery();
			// Si se encuentra el nombre en la base de datos
			while (rs.next()) {
				
				// Lee la plantilla de la base de datos
				byte templateBuffer[] = rs.getBytes("huella");
				String dni = rs.getString("dni");
				String nombre = rs.getString("nombre");
				String apellido = rs.getString("apellido");
				String cargo = rs.getString("cargo");
				
				Empleado employed = new Empleado();
				
				employed.setDni(dni);
				employed.setNombre(nombre);
				employed.setApellido(apellido);
				employed.setCargo(cargo);
				
				Log.setUsuario(employed);
				
				// Crea una nueva plantilla a partir de la guardada en la base de datos
				
				DPFPTemplate referenceTemplate = DPFPGlobal.getTemplateFactory().createTemplate(templateBuffer);
				
				// Envia la plantilla creada al objeto contendor de Template del
				// componente de huella digital
				setTemplate(referenceTemplate);

				// Compara las caracteriticas de la huella recientemente
				// capturda con la
				// alguna plantilla guardada en la base de datos que coincide
				// con ese tipo
				DPFPVerificationResult result = Verificador.verify(featuresverificacion, getTemplate());

				// compara las plantilas (actual vs bd)
				// Si encuentra correspondencia dibuja el mapa
				// e indica el nombre de la persona que coincidiÃ³.
				if (result.isVerified()) {
					// crea la imagen de los datos guardado de las huellas
					// guardadas en la base de datos
					
					//JOptionPane.showMessageDialog(null, "Las huella capturada es de " + nombre, "Verificacion de Huella", JOptionPane.INFORMATION_MESSAGE);
					

			            String datosUsuario = Log.Usuario.getNombre()+ " "+Log.Usuario.getApellido();
	                    JOptionPane.showMessageDialog(null, "Bienvenido! "+ datosUsuario);
	                    
	                    VentanaPrincipal miVentanaPrincipal = new VentanaPrincipal();
						miVentanaPrincipal.setMiVentanaPrincipal(miVentanaPrincipal);
						
						dispose();
	                    
	                    if(Log.Usuario.getCargo().equals("Administrador")){
	                    	miVentanaPrincipal.getBtnClientes().setEnabled(true);
	                    	miVentanaPrincipal.getBtnEmpleados().setEnabled(true);
	                    	miVentanaPrincipal.getBtnProductos().setEnabled(true);
	                    	miVentanaPrincipal.getBtnReportes().setEnabled(true);
	                    	
	                    	
	                    }else{
	                    	if(Log.Usuario.getCargo().equals("Vendedor")){
	                    		miVentanaPrincipal.getBtnVentas().setEnabled(true);
	                    		miVentanaPrincipal.getBtnClientes().setEnabled(true);
	                    		miVentanaPrincipal.setEmpleadoqueIngreso(Log.Usuario);
	                    	}
	                    }
	                    miVentanaPrincipal.setVisible(true);
					
					return;
				}
			}
			// Si no encuentra alguna huella correspondiente al nombre lo indica
			// con un mensaje
			JOptionPane.showMessageDialog(null, "No existe ningun registro que coincida con la huella",
					"Verificacion de Huella", JOptionPane.ERROR_MESSAGE);
			setTemplate(null);
		} catch (SQLException e) {
			// Si ocurre un error lo indica en la consola
			System.err.println("Error al identificar huella dactilar." + e.getMessage());
		} finally {
			con.desconectar();
		}
	}

	/*
	 * @param args the command line arguments
	 */

	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new VerificarHuella().setVisible(true);
			}
		});
	}

	private javax.swing.JButton btnIdentificar;
	private javax.swing.JPanel jPanel1;
	private javax.swing.JPanel jPanel2;
	private javax.swing.JPanel jPanel3;
	private javax.swing.JPanel jPanel4;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JLabel lblImagenHuella;
	private javax.swing.JPanel panBtns;
	private javax.swing.JPanel panHuellas;
	private javax.swing.JTextArea txtArea;
	// End of variables declaration//GEN-END:variables

}
