package Capitulo_6.Cajero2;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

/**
   A frame displaying the components of an ATM
*/

class ATM extends JFrame
{
   private int estado;
   private int NumeroCliente;
   private Cliente ClienteActual;
   private Cuenta CuentaActual;
   private Banco elBanco;
   
   private JButton boton_A;
   private JButton Boton_B;
   private JButton Boton_C;
   
   private TecladoNumerico teclado;
   private JTextArea display;
   
   private static final int ESTADO_INICIAL = 1;
   private static final int ESTADO_CLAVE = 2;
   private static final int ESTADO_CUENTA = 3;
   private static final int ESTADO_TRANSACCION = 4;

   private static final int CUENTA_DE_CHEQUES = 1;
   private static final int CUENTA_DE_AHORROS = 2;
   
   /**
      Constructs the user interface of the ATM application.
   */
   
   public ATM()
   {  
      // initialize Banco and Clientes

      elBanco = new Banco();
       
      elBanco.leeClientes();

      
      // construct components

      teclado = new TecladoNumerico();

      display = new JTextArea(4, 20);
      
      boton_A = new JButton("  A  ");
      boton_A.addActionListener(new AButtonListener());

      Boton_B = new JButton("  B  ");
      Boton_B.addActionListener(new BButtonListener());

      Boton_C = new JButton("  C  ");
      Boton_C.addActionListener(new CButtonListener());
      
      // add components to content pane

      JPanel buttonPanel = new JPanel();
      buttonPanel.setLayout(new GridLayout(3, 1));
      buttonPanel.add(boton_A);
      buttonPanel.add(Boton_B);
      buttonPanel.add(Boton_C);
      
      Container contentPane = getContentPane();
      contentPane.setLayout(new FlowLayout());
      contentPane.add(teclado);
      contentPane.add(display);
      contentPane.add(buttonPanel);

      muestraEstado(ESTADO_INICIAL);  
      this.setTitle("Banco Nacional de Java (BANAJAVA)");      
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setVisible(true);
      this.pack();
   }
   
   /** 
      Sets the current Cliente number to the keypad value
      and sets estado to PIN.
   */
   
   public void setNumeroCliente() 
   {  
       try{
           NumeroCliente = (int)teclado.getValue();
       }
       catch(NumberFormatException ex) {
           muestraEstado(ESTADO_INICIAL);
           return;
       }       
      muestraEstado(ESTADO_CLAVE);
   }

   /** 
      Gets PIN from keypad, finds Cliente in Banco.
      If found sets estado to ACCOUNT, else to START.
   */
   
   public void seleccionaCliente()
   {  
       int pin = 0;
       
       try{
           pin = (int)teclado.getValue();
       }
       catch(NumberFormatException ex) {
            muestraEstado(ESTADO_INICIAL);
            return;
           
       }
       
      ClienteActual = elBanco.buscaCliente(NumeroCliente, pin);
      
      if (ClienteActual == null) 
         muestraEstado(ESTADO_INICIAL);
      else 
         muestraEstado(ESTADO_CUENTA);
   }
   
   /** 
      Sets current account to checking or savings. Sets 
      estado to TRANSACT
      @param account one of CUENTA_DE_CHEQUES or SAVINGS_ACCOUNT
   */
   
   public void seleccionaCuenta(int account)
   {
      if (account == CUENTA_DE_CHEQUES)
         CuentaActual = ClienteActual.obten_cuenta_de_Cheques();
      else
         CuentaActual = ClienteActual.obten_cuenta_de_Ahorros();
      muestraEstado(ESTADO_TRANSACCION);
   }

   /** 
      retiros amount typed in keypad from current account. 
      Sets estado to ACCOUNT. 
   */
   
   public void retiro()
   {  
      CuentaActual.retiro(teclado.getValue());
      muestraEstado(ESTADO_CUENTA);
   }

   /** 
      depositos amount typed in keypad to current account. 
      Sets estado to ACCOUNT. 
   */
   
   public void deposito()
   {  
      CuentaActual.deposito(teclado.getValue());
      muestraEstado(ESTADO_CUENTA);
   }

   /** 
      Sets estado and updates display message.
      @param estado the next estado
   */
   
   public void muestraEstado(int estadoNuevo)
   {  
      estado = estadoNuevo;
      teclado.clear();
      if (estado == ESTADO_INICIAL)
         display.setText("Ingrese un Numero de Cliente \nA = OK");
      else if (estado == ESTADO_CLAVE)
         display.setText("Ingrese su Clave\nA = OK");
      else if (estado == ESTADO_CUENTA)
         display.setText("Seleccione tipo de Cuenta\n" 
           + "A = Cheques\nB = Ahorros\nC = Salir");
      else if (estado == ESTADO_TRANSACCION)
         display.setText("Balance = " 
            + CuentaActual.obtenBalance() 
            + "\nIngrese el monto  y seleccione una Operacion\n"
            + "A = Retiro\nB = Deposito\nC = Cancelar");
   }
   
   private class AButtonListener implements ActionListener
   {  
      public void actionPerformed(ActionEvent event)
      {  
         if (estado == ESTADO_INICIAL)
            setNumeroCliente();
         else if (estado == ESTADO_CLAVE)
            seleccionaCliente();
         else if (estado == ESTADO_CUENTA)
            seleccionaCuenta(CUENTA_DE_CHEQUES);
         else if (estado == ESTADO_TRANSACCION)
            retiro();
      }
   }
   
   private class BButtonListener implements ActionListener
   {  
      public void actionPerformed(ActionEvent event)
      {  
         if (estado == ESTADO_CUENTA)
            seleccionaCuenta(CUENTA_DE_AHORROS);
         else if (estado == ESTADO_TRANSACCION)
            deposito();
      }
   }

   private class CButtonListener implements ActionListener
   {  
      public void actionPerformed(ActionEvent event)
      {  
         if (estado == ESTADO_CUENTA)
            muestraEstado(ESTADO_INICIAL);
         else if (estado == ESTADO_TRANSACCION)
            muestraEstado(ESTADO_CUENTA);
      }
   }
}
