package oracle.forms.jvr;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.UIManager;

import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import oracle.forms.ui.CustomEvent;
import oracle.forms.ui.VBean;


public class Calculator extends VBean implements ActionListener, KeyListener
{
  public JFrame frame;
  public JButton[] btnBotones;
  public JTextField txtResultado;
  public Container cpane;
  public IHandler  m_handler;  
  public String etiqueta, titulo, modo;
  public int origen = 0;
  public Point posicion = new Point(300,150);
  public ArrayList  tokens = new ArrayList();
  public WindowListener wl;
  public CalculatorOperations d = new CalculatorOperations();
  public final static ID CALCULATOR_EVENT = ID.registerProperty("CALCULATOR_EVENT");    
  public final static ID CALCULATOR_VALOR = ID.registerProperty("CALCULATOR_VALOR");    
  public final static ID SHOW              = ID.registerProperty("SHOW");   
  public final static ID SET_TITULO        = ID.registerProperty("SET_TITULO"); 
  public final static ID SET_BOTON         = ID.registerProperty("SET_BOTON"); 
  public final static ID SET_POSICION      = ID.registerProperty("SET_POSICION"); 
  public final static ID SET_VALORINICIAL  = ID.registerProperty("SET_VALORINICIAL"); 
  public final static ID SET_MODO          = ID.registerProperty("SET_MODO"); 
      
  public Calculator() 
  { 
      System.out.println ("*****************************");
      System.out.println ("***      Calculator      ***");
      System.out.println ("*****************************");  

    wl = new WindowAdapter() 
       {
         public void windowClosing(WindowEvent e) 
        {                    
          frame.setVisible(false);
        }
       };   
        
     try
     {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
     }
       catch(Exception e)
     {;}
  }
        
  public void init(IHandler handler)
  {
      m_handler = handler;
      super.init(handler);
  }   
  
  public void setEtiqueta (String valor)
  {
    this.etiqueta = valor;
  }

  public String getEtiqueta ()
  {
    return this.etiqueta;
  }

  public void setTitulo (String valor)
  {
    this.titulo = valor;
  }

  public String getTitulo ()
  {
    return this.titulo;
  }
  
  public void setPosicion (int x, int y) 
  {
    this.posicion = new Point (x,y);
  }  

  public Point getPosicion ()
  {
    return this.posicion;
  }  
  
  public void setValorInicial (int x)
  {
    this.origen = x;
  }
  
  public int getValorInicial ()
  {
    return this.origen;
  }  

  public void setModo (String valor)
  {
    this.modo = valor;      
  }

  public String getModo ()
  {
    return this.modo;
  }  
 
    public void cargarCalculadoraCientifica()
    {      
      try
      {
        frame = new JFrame(getTitulo()) ;
        frame.addWindowListener(wl);  
        btnBotones   = new JButton[37];
        txtResultado = new JTextField(0);  
        txtResultado.addKeyListener(this);  
        int cont=0;
        btnBotones[cont++]=new JButton("7");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("8");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("9");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("/");     
        btnBotones[cont++]=new JButton("sqrt");  
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("x^2");  
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("sin");           
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("asin");           
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("4");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("5");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("6");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("*");
        btnBotones[cont++]=new JButton("%");
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("x^3");  
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton("cos");       
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("acos");       
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("1");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("2");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("3");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("-");      
        btnBotones[cont++]=new JButton("1/x");  
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("x^n");
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton("tan");       
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("atan");       
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("0");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("+/-"); 
        btnBotones[cont++]=new JButton(","); 
        btnBotones[cont++]=new JButton("+"); 
        btnBotones[cont++]=new JButton("Log");
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton("x!");
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton("PI");
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("E");
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton(getEtiqueta ());
        btnBotones[cont-1].setFont(new Font ("Arial",Font.BOLD,12));
        btnBotones[cont++]=new JButton("=");      
        btnBotones[cont++]=new JButton("RND");
        btnBotones[cont-1].setForeground(Color.BLUE);
        btnBotones[cont++]=new JButton("ABS");
        btnBotones[cont-1].setForeground(Color.BLUE);      
        btnBotones[cont++]=new JButton("CE");
        btnBotones[cont-1].setForeground(Color.BLUE);

        cpane = frame.getContentPane();
        cpane.setLayout(null);

        txtResultado.setBounds(10,10,455,25);
        txtResultado.setEditable(false);
        txtResultado.setBackground(Color.white);
        txtResultado.setHorizontalAlignment(JTextField.RIGHT);      
        txtResultado.setForeground(Color.red);      
        txtResultado.setFont(new Font ("Arial",Font.BOLD,14));
        cpane.add(txtResultado);
        
        int x=10;
        int y=15;
        
        for (int i=0;i<btnBotones.length;i++)
        {
            if (i%8==0)
            {
                x=10;
                y+=25;
            }
            else
            {
                x+=57;
            }
            if ((i!=32) && (i!=36))
            {
                btnBotones[i].setBounds(x,y,57,25);
            }
            else 
            {
                if (i==32)
                {
                  btnBotones[i].setBounds(x,y,171,25);
                  x+=114;
                }
               else 
                {
                  btnBotones[i].setBounds(x,y,114,25);
                  x+=114;
                }
            }          
                                  
            btnBotones[i].addActionListener(this);
            cpane.add(btnBotones[i]);
        }
          
        frame.pack();
        frame.setSize(475,205);
        frame.setResizable(false);
        frame.setDefaultLookAndFeelDecorated(true);
        frame.setLocation(posicion);
        frame.setVisible(true);
     }
     
     catch (Exception e)
     {
         System.out.println(e.getMessage());
     }
    }

    public void cargarCalculadoraEstandar()
    {      
      try
      {
        frame = new JFrame(getTitulo()) ;
        frame.addWindowListener(wl);  
        btnBotones   = new JButton[19];
        txtResultado = new JTextField(0);  
        txtResultado.addKeyListener(this);  
        
        int cont=0;
        btnBotones[cont++]=new JButton("7");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("8");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("9");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("/");     
        btnBotones[cont++]=new JButton("4");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("5");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("6");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("*");
        btnBotones[cont++]=new JButton("1");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("2");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("3");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("-");      
        btnBotones[cont++]=new JButton("0");
        btnBotones[cont-1].setForeground(Color.RED);
        btnBotones[cont++]=new JButton("+/-"); 
        btnBotones[cont++]=new JButton(","); 
        btnBotones[cont++]=new JButton("+"); 
        btnBotones[cont++]=new JButton(getEtiqueta ());
        btnBotones[cont-1].setFont(new Font ("Arial",Font.BOLD,12));
        btnBotones[cont++]=new JButton("=");      
        btnBotones[cont++]=new JButton("CE");
        btnBotones[cont-1].setForeground(Color.BLUE);

        cpane = frame.getContentPane();
        cpane.setLayout(null);
      
        txtResultado.setBounds(10,10,228,25);
        txtResultado.setEditable(false);
        txtResultado.setBackground(Color.white);
        txtResultado.setHorizontalAlignment(JTextField.RIGHT);      
        txtResultado.setForeground(Color.red);      
        txtResultado.setFont(new Font ("Arial",Font.BOLD,14));
        cpane.add(txtResultado);
      
        int x=10;
        int y=15;
        
        for (int i=0;i<btnBotones.length;i++)
        {
            if (i%4==0)
            {
                x=10;
                y+=25;
            }
            else
            {
                x+=57;
            }
            if (i!=16)
            {
                btnBotones[i].setBounds(x,y,57,25);
            }
            else 
            {
                btnBotones[i].setBounds(x,y,114,25);
                x+=57;
            }          
                                  
            btnBotones[i].addActionListener(this);
            cpane.add(btnBotones[i]);
        }
          
        frame.pack();
        frame.setSize(250,205);
        frame.setResizable(false);
        frame.setDefaultLookAndFeelDecorated(true);
        frame.setLocation(posicion);
        frame.setVisible(true);
     }
     
     catch (Exception e)
     {
         System.out.println(e.getMessage());
     }
    }
     
/*
  public static void main(String[] args)
  {
      Calculator c = new Calculator();
      c.setEtiqueta ("Obtener Valor");
      c.setTitulo ("Calculator");
      c.setPosicion(300,150);
      c.setValorInicial(323);
      c.setProperty(SET_MODO,"E");
      c.setProperty(SHOW,"");
  }
*/

  public boolean setProperty(ID property, Object value)
  {
    if (property == SHOW) 
    {        
        if (getModo().equals("C"))
          {
            cargarCalculadoraCientifica();
          }
        else
          {
            cargarCalculadoraEstandar();
          }
          
        return true;
    }

    else if (property == SET_POSICION) 
    {
        String sValue = ','+ value.toString();
        tokens= parseInput(sValue, 2, ',');
        setPosicion (Integer.parseInt((String)tokens.get(0)), Integer.parseInt((String)tokens.get(1)));
        return true;
    }
      
    else if (property == SET_TITULO) 
    {
        String sValue = value.toString();
        setTitulo(sValue);
        return true;
    }
    
    else if (property == SET_BOTON) 
    {
        String sValue = value.toString();
        setEtiqueta(sValue);
        return true;
    }    

    else if (property == SET_VALORINICIAL) 
    {
        int sValue = Integer.parseInt(value.toString());
        setValorInicial(sValue);
        return true;
    }    

    else if (property == SET_MODO) 
    {
        String sValue = value.toString();
        setModo(sValue);
        return true;
    }
      
    else
    {
        return super.setProperty(property, value);
    }        
  }
  
  public void cargarValorInicial ()
  {
    String value = ""+getValorInicial();
    if (value.equals("0"))
      txtResultado.setText("");
    else
      txtResultado.setText(value);
  }
  
  public void actionPerformed(ActionEvent e)  
  {
      if (e.getActionCommand().equals("CE"))
      {
          txtResultado.setText("");
      }
      
      if (e.getActionCommand().equals("0")||
          e.getActionCommand().equals("1")||
          e.getActionCommand().equals("2")||
          e.getActionCommand().equals("3")||
          e.getActionCommand().equals("4")||
          e.getActionCommand().equals("5")||
          e.getActionCommand().equals("6")||
          e.getActionCommand().equals("7")||
          e.getActionCommand().equals("8")||
          e.getActionCommand().equals("9"))            
      {
          txtResultado.setText(txtResultado.getText()+e.getActionCommand());
      }
    
      if (e.getActionCommand().equals("+")||
          e.getActionCommand().equals("-")||
          e.getActionCommand().equals("*")||
          e.getActionCommand().equals("/")||
          e.getActionCommand().equals("x^n"))
      {
          if (e.getActionCommand().equals("x^n"))
            d.setOperacion('x');
          else   
            d.setOperacion(e.getActionCommand().charAt(0));
            
            d.setNumeroA(Double.parseDouble(txtResultado.getText()));
            txtResultado.setText("");
      }    

      boolean decimalPointFound;
      if (e.getActionCommand().equals(","))
      {
          decimalPointFound = false;
          for (int i =0; i < txtResultado.getText().length(); ++i)
          {
            if (txtResultado.getText().charAt(i) == '.')
            {
              decimalPointFound = true;
              continue;
            }
          }
           if (!decimalPointFound && txtResultado.getText().length()!=0)
             txtResultado.setText(txtResultado.getText()+".");                    
           if(!decimalPointFound && txtResultado.getText().length()==0)
             txtResultado.setText("0.");
      }   

      if (e.getActionCommand().equals("sqrt"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.sqrt();
        txtResultado.setText(String.valueOf(d.getResultado()));          
      }

      if (e.getActionCommand().equals("1/x"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.fraccion();
        txtResultado.setText(String.valueOf(d.getResultado()));          
      }

      if (e.getActionCommand().equals("%"))
      {
        d.setNumeroB(Double.parseDouble(txtResultado.getText()));
        d.porcentaje();
        txtResultado.setText(String.valueOf(d.getResultado()));          
      }

      if (e.getActionCommand().equals("+/-") && (txtResultado.getText().length()>0))
      {            
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.signo();
        txtResultado.setText(String.valueOf(d.getResultado()));          
      }
      
      if (e.getActionCommand().equals("RND"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.redondear();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }

      if (e.getActionCommand().equals("Ceil"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.redondearArriba();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }

      if (e.getActionCommand().equals("Floor"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.redondearAbajo();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }
      
      if (e.getActionCommand().equals("ABS"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.absoluto();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }
      
      if (e.getActionCommand().equals("sin"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.seno();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }

      if (e.getActionCommand().equals("asin"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.arcoseno();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }

      if (e.getActionCommand().equals("cos"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.coseno();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }

      if (e.getActionCommand().equals("acos"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.arcocoseno();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }
      
      if (e.getActionCommand().equals("tan"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.tangente();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }      

      if (e.getActionCommand().equals("atan"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.arcotangente();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }  
      
      if (e.getActionCommand().equals("PI"))
      {
        d.PI();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }          

      if (e.getActionCommand().equals("E"))
      {
        d.E();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }  

      if (e.getActionCommand().equals("Log"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.log();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }  

      if (e.getActionCommand().equals("x^2"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.alCuadrado();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }  

      if (e.getActionCommand().equals("x^3"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.alCubo();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }  

      if (e.getActionCommand().equals("x!"))
      {
        d.setNumeroA(Double.parseDouble(txtResultado.getText()));
        d.factorial();
        txtResultado.setText(String.valueOf(d.getResultado()));                  
      }     
      
      if (e.getActionCommand().equals("="))
      {
          d.setNumeroB(Double.parseDouble(txtResultado.getText()));

          switch (d.getOperacion())
          {
              case '+':
                  d.suma();
                  break;
              case '-':
                  d.resta();
                  break;
              case '*':
                  d.multiplicacion();
                  break;
              case '/':
                  d.division();
                  break;
              case 'x':
                  d.exponencial();
                  break;
          }          
          txtResultado.setText(String.valueOf(d.getResultado()));          
      }
      
      if (e.getActionCommand().equals(getEtiqueta ()))
      {
          try
          {         
             System.out.println(getTitulo()+": "+txtResultado.getText());
             CustomEvent ce = new CustomEvent (m_handler, CALCULATOR_EVENT);
             m_handler.setProperty (CALCULATOR_VALOR, d.resultado);
             dispatchCustomEvent(ce);  
             frame.setVisible(false);             
          } 
          catch (Exception f) 
          {
            System.out.println(f.getMessage());
          }
      }
      txtResultado.requestFocus();
  }  

      
    public ArrayList parseInput(String inputData, int count, char fieldSep)
    {
    int indic;
    int ind;
    
      for(indic=0;indic<count-1;indic++)
      {
        ind = inputData.indexOf(fieldSep);
        inputData=inputData.substring(ind+1,inputData.length());
        tokens.add(inputData.substring(0,inputData.indexOf(fieldSep)));    
      }
      tokens.add(inputData.substring(inputData.indexOf(fieldSep)+1,inputData.length()));
    return tokens;
    }

    public void keyTyped(KeyEvent e) 
    {
    }

    public void keyReleased(KeyEvent e) 
    {
    }
    
    public void keyPressed(KeyEvent e) 
    {
        String keyString =  ""+e.getKeyChar();
        
      if (keyString.equals("0")||
          keyString.equals("1")||
          keyString.equals("2")||
          keyString.equals("3")||
          keyString.equals("4")||
          keyString.equals("5")||
          keyString.equals("6")||
          keyString.equals("7")||
          keyString.equals("8")||
          keyString.equals("9"))            
      {
          txtResultado.setText(txtResultado.getText()+keyString);
      }
    
      if (keyString.equals("+")||
          keyString.equals("-")||
          keyString.equals("*")||
          keyString.equals("/")||
          keyString.equals("x^n"))
      {
          if (keyString.equals("x^n"))
            d.setOperacion('x');
          else   
            d.setOperacion(keyString.charAt(0));
            
            d.setNumeroA(Double.parseDouble(txtResultado.getText()));
            txtResultado.setText("");
      }    

      boolean decimalPointFound;
      if (keyString.equals(",") || keyString.equals("."))
      {
          decimalPointFound = false;
          for (int i =0; i < txtResultado.getText().length(); ++i)
          {
            if (txtResultado.getText().charAt(i) == '.')
            {
              decimalPointFound = true;
              continue;
            }
          }
           if (!decimalPointFound && txtResultado.getText().length()!=0)
             txtResultado.setText(txtResultado.getText()+".");                    
           if(!decimalPointFound && txtResultado.getText().length()==0)
             txtResultado.setText("0.");
      } 

      if (keyString.equals("=") || e.getKeyCode()==10)
      {
          d.setNumeroB(Double.parseDouble(txtResultado.getText()));

          switch (d.getOperacion())
          {
              case '+':
                  d.suma();
                  break;
              case '-':
                  d.resta();
                  break;
              case '*':
                  d.multiplicacion();
                  break;
              case '/':
                  d.division();
                  break;
          }          
          txtResultado.setText(String.valueOf(d.getResultado()));          
      }      
    }        
}   


