/*
   Calculator Homework #4
   Java GUI Programming using AWT, JFC and Swing
   basic extension of the java.applet.Applet class

   Author: Jeffrey Rodriguez

   This calculator works as Homework3 Calculator but it is implemented in Swing
**/

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/*
    Swing Calculator.

**/

public class Calculatorx extends JApplet {
    private final static int  JButtonWIDTH  =  60;
    private final static int  JButtonHEIGHT =  52;
    private final static String  functionName[] = { "Hyp", "Mod", "AND", "Sin", "+/-", "OR", "Cos", "1/x", "NOT", "Tan", "x!", "<",
        "Log", "X^2", ">", "Ln", "x^y", ">>", "Inv", "EE", "%"};
    private final static String  calcNumber[] = { "A", "B", "C", "Clr", "AC", "D", "E", "F", "(", ")",
        "7", "8", "9", "x", "M-", "4", "5", "6", "/", "M+", "1", "2", "3", "+", 
        "MR", "", "0", "=", "-", "MC"};

    private final static String baseNumber[] = { "Hex", "Dec", "Oct", "Bin"};
    private final static String angleType[]  = { "Deg", "Rad", "Gra"};
    private static String _numberBase = baseNumber[1]; // Dec base default

    final JTextField calculatorInput = new JTextField();



    Calculatorx calc;
    public Calculatorx()
    { 
        JPanel   functions          = new JPanel();
        JButton  functionJButton[]  = new JButton[21];
        int   deltx = 56;
        int   delty = 30;

        Container contentPane       = getContentPane();


        contentPane.setLayout(null);
        contentPane.setBackground(new Color(216,182,163));
        contentPane.setSize(460,450);


        functions.setLayout(new GridLayout(7,4,5,5));
        contentPane.add(functions);
        functions.setBounds(18,82,156,270);


        int    positionX = 0;
        int    positionY = 0;

        Font font = new Font("Dialog", Font.PLAIN, 10);
        
        for ( int i = 0 ; i < functionJButton.length; i++ ) {
            functionJButton[i] = new JButton(functionName[i]);
            functionJButton[i].setFont( font );

            if ( functionName[i].equals( "+/-"  ) ) {
                functionJButton[i].addActionListener( new ActionListener() {
                                                          public void   actionPerformed( ActionEvent e )
                                                          {
                                                              String        calcBase  = getCalculatorBase();
                                                              StringDisplay display   = null;
                                                              String        cmd       = e.getActionCommand();
                                                              System.out.println( "JButton event" + e );

                                                              if ( calcBase.equals( "Dec" ) ) // Floating point buffer
                                                                  display = StringDisplay.getInstance( true );
                                                              else
                                                                  display = StringDisplay.getInstance( false ); // integer buffer

                                                              if ( cmd.equals( "+/-" ) ) {
                                                                  System.out.println( "Hit +/-" );

                                                                  if ( calcBase.equals( "Dec" ) ) {
                                                                      Double  fValue = Double.valueOf( display.getStringDisplay() );
                                                                      double  dispValue  =  (double ) ( fValue.doubleValue() ) * -1.0;
                                                                      display.deleteAll();
                                                                  } else {
                                                                      Integer  iValue = Integer.valueOf( display.getStringDisplay() );
                                                                      int      dispValue = iValue.intValue() * -1;
                                                                      display.deleteAll();
                                                                  }
                                                                  display.add( '-' );
                                                              }
                                                          }
                                                      });
            }

            functions.add( functionJButton[i] );
            functionJButton[i].setBackground( Color.lightGray );
            functionJButton[i].setBounds( positionX, positionY, JButtonHEIGHT, JButtonWIDTH );
            if ( ( (i+1) % 3 ) == 0 ) {
                positionX  = 0;
                positionY += delty;
            } else {
                positionX += deltx;
            }
        }


        JButton  calculatorJButton[] = new JButton[30];
        JPanel calculatorFuncts       = new JPanel();
        calculatorFuncts.setLayout(new GridLayout(6,6,5,5));
        contentPane.add(calculatorFuncts);
        calculatorFuncts.setBounds(180,82,264,234);

        for ( int i = 0 ; i < calculatorJButton.length; i++ ) {
            calculatorJButton[i] = new JButton(calcNumber[i]);
            calculatorJButton[i].setFont( font );
            


            calculatorJButton[i].addActionListener( new ActionListener( ) {
                                                        public void   actionPerformed( ActionEvent e )
                                                        {
                                                            String        calcBase  = getCalculatorBase();
                                                            StringDisplay display   = null;
                                                            String        cmd       = e.getActionCommand();

                                                            System.out.println( "JButton event" + e );


                                                            if ( calcBase.equals( "Dec" ) ) // Floating point buffer
                                                                display = StringDisplay.getInstance( true );
                                                            else
                                                                display = StringDisplay.getInstance( false ); // integer buffer

                                                            if ( cmd.equals( "Clr" ) ) {
                                                                display.delete();
                                                                calculatorInput.setText( display.getStringDisplay() ); 
                                                                calculatorInput.setCaretPosition( display.getCursor() );
                                                            } else if ( cmd.equals( "AC" ) ) {
                                                                display.deleteAll();
                                                                calculatorInput.setText( display.getStringDisplay() ); 
                                                                calculatorInput.setCaretPosition( display.length() );
                                                            } else if ( cmd.equals( "1" ) || cmd.equals( "2" ) || cmd.equals( "3" ) ||
                                                                        cmd.equals( "4" ) || cmd.equals( "5" ) || cmd.equals( "6" ) ||
                                                                        cmd.equals( "7" ) || cmd.equals( "8" ) || cmd.equals( "9" ) ||
                                                                        cmd.equals( "0" ) || cmd.equals( "A" ) || cmd.equals( "B" ) ||
                                                                        cmd.equals( "C" ) || cmd.equals( "D" ) || cmd.equals( "E" ) ||
                                                                        cmd.equals( "F" ) ) {

                                                                char typeChar = cmd.charAt( 0 );

                                                                //System.out.println( "Char = " + typeChar );
                                                                if ( calcBase.equals( "Dec" ) ) {
                                                                    display = StringDisplay.getInstance( true );
                                                                    if ( typeChar >= '0' && typeChar <= '9' ) {
                                                                        if ( display.getCursor() >5 )
                                                                            display.add( typeChar );//Otherwise ignore more input
                                                                    }
                                                                } else {
                                                                    display = StringDisplay.getInstance( false );

                                                                    if ( calcBase.equals( "Bin" )    ) {
                                                                        if ( typeChar >= '0' && typeChar <= '1' ) {
                                                                            if ( display.getCursor() > 5  )
                                                                                display.add( typeChar );
                                                                            else {
                                                                                display.deleteAll();
                                                                                display.writeString( "Result_is_too_large_" );
                                                                            }
                                                                        }
                                                                    } else if ( calcBase.equals( "Oct" ) ) {
                                                                        if ( typeChar >= '0' && typeChar <= '7' ) {
                                                                            if (  ( display.length() - display.getCursor() ) < 12 ) // only 12 Oct allowed
                                                                                display.add( typeChar );
                                                                            else {
                                                                                display.deleteAll();
                                                                                display.writeString( "Result_is_too_large_" );
                                                                            }
                                                                        }
                                                                    } else if ( calcBase.equals( "Hex" )   ) {
                                                                        if ( ( typeChar >= '0' && typeChar <= '9' ) || ( typeChar >= 'A' && typeChar <= 'F' ) ||
                                                                             ( typeChar >= 'a' && typeChar <= 'f' ) ) {
                                                                            if (  ( display.length() - display.getCursor() ) < 8 ) // only 8 Hex allowed
                                                                                display.add( typeChar );
                                                                            else {
                                                                                display.deleteAll();
                                                                                display.writeString( "Result_is_too_large_" );
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                calculatorInput.setText( display.getStringDisplay() ); 
                                                                calculatorInput.setCaretPosition( display.getCursor() );
                                                                calculatorInput.requestFocus();
                                                            }
                                                        }
                                                    }  );



            calculatorFuncts.add( calculatorJButton[i] );
            calculatorJButton[i].setBackground( Color.lightGray );
            calculatorJButton[i].setBounds( positionX, positionY, JButtonHEIGHT, JButtonWIDTH );
            if ( ( (i+1) % 6 ) == 0  ) {
                positionX  = 0;
                positionY += delty;
            } else {
                positionX += deltx;
            }
        }


        RadioButtonPanel basePanel = new RadioButtonPanel( baseNumber,  "Dec", 
                                                           new ActionListener() {
                                                               public void actionPerformed( ActionEvent e )
                                                               {
                                                                   calc.setCalculatorBase( ( String) e.getActionCommand() );
                                                                   System.out.println( "Just called setCalculatorBase" );
                                                               }
                                                           }, new Rectangle( 4,46,222,24  ) );
        contentPane.add( basePanel );

        RadioButtonPanel anglePanel = new RadioButtonPanel( angleType,  "Deg",  null,
                                                            new Rectangle( 264,46,168,24 ) );
        contentPane.add( anglePanel );



        JTextField bottom1 = new JTextField();
        JTextField bottom2 = new JTextField();
        JTextField bottom3 = new JTextField();



        contentPane.add(bottom1);
        bottom1.setBounds(18,376,66,24);

        contentPane.add(bottom2);
        bottom2.setBounds(90,376,96,24);

        contentPane.add(bottom3);
        bottom3.setBounds(192,376,240,24);

        calculatorInput.setColumns( 36 );

        contentPane.add(calculatorInput);
        calculatorInput.setBounds(198,10,240, 24 );

        calculatorInput.setBackground(new Color(190,190,190));

        calculatorInput.addKeyListener(  new KeyAdapter() {
                                             public void keyPressed( KeyEvent e)
                                             {
                                                 char  typedChar       = e.getKeyChar();
                                                 int   keyCode         = e.getKeyCode();
                                                 String keyText        = KeyEvent.getKeyText( keyCode );
                                                 String      calcBase  = getCalculatorBase();

                                                 StringDisplay display = null;

                                                 System.out.println( "Calcbase.keyprss = " + calcBase );
                                                 System.out.println( "keyText.keyprss = " +  keyText );


                                                 if ( calcBase.equals( "Dec" ) ) // Floating point buffer
                                                     display = StringDisplay.getInstance( true );
                                                 else
                                                     display = StringDisplay.getInstance( false ); // integer buffer

                                                 if ( keyText.equals( "Backspace" ) || keyText.equals( "Left" ) ) {
                                                     display.delete();
                                                     calculatorInput.setText( display.getStringDisplay() ); 
                                                     calculatorInput.setCaretPosition( display.getCursor() );
                                                 } else if ( keyText.equals( "Delete" ) ) {
                                                     display.deleteAll();
                                                     calculatorInput.setText( display.getStringDisplay() ); 
                                                     calculatorInput.setCaretPosition( display.length() );
                                                 }

                                                 e.consume();
                                             }

                                             public void keyReleased( KeyEvent e )
                                             {
                                                 e.consume();
                                             }

                                             public void keyTyped( KeyEvent e ) 
                                             {
                                                 char            typeChar  = e.getKeyChar();
                                                 String          calcBase  = getCalculatorBase();
                                                 StringDisplay   display   = null;

                                                 System.out.println( "Calcbase = " + calcBase );

                                                 if ( calcBase.equals( "Dec" ) ) {
                                                     display = StringDisplay.getInstance( true );
                                                     if ( typeChar >= '0' && typeChar <= '9' ) {
                                                         if ( display.getCursor() >5 )
                                                             display.add( typeChar );//Otherwise ignore more input
                                                     }
                                                 } else {
                                                     display = StringDisplay.getInstance( false );

                                                     if ( calcBase.equals( "Bin" )    ) {
                                                         if ( typeChar >= '0' && typeChar <= '1' ) {
                                                             if ( display.getCursor() > 5  )
                                                                 display.add( typeChar );
                                                             else {
                                                                 display.deleteAll();
                                                                 display.writeString( "Result_is_too_large_" );
                                                             }
                                                         }
                                                     } else if ( calcBase.equals( "Oct" ) ) {
                                                         if ( typeChar >= '0' && typeChar <= '7' ) {
                                                             if (  ( display.length() - display.getCursor() ) < 12 ) // only 12 Oct allowed
                                                                 display.add( typeChar );
                                                             else {
                                                                 display.deleteAll();
                                                                 display.writeString( "Result_is_too_large_" );
                                                             }


                                                         }
                                                     } else if ( calcBase.equals( "Hex" )   ) {
                                                         if ( ( typeChar >= '0' && typeChar <= '9' ) || ( typeChar >= 'A' && typeChar <= 'F' ) ||
                                                              ( typeChar >= 'a' && typeChar <= 'f' ) ) {
                                                             if (  ( display.length() - display.getCursor() ) < 8 ) // only 8 Hex allowed
                                                                 display.add( typeChar );
                                                             else {
                                                                 display.deleteAll();
                                                                 display.writeString( "Result_is_too_large_" );
                                                             }
                                                         }
                                                     }
                                                 }
                                                 calculatorInput.setText( display.getStringDisplay() ); 
                                                 calculatorInput.setCaretPosition( display.getCursor() );
                                                 e.consume();
                                             }
                                         } );

    }  


    public String getCalculatorBase()
    {
        return _numberBase;
    } 
    public void init()
    {
        calc = new Calculatorx();
    }  
    public static void main( String[] args )
    {
        //Calculatorx calc     = new Calculatorx();
        JFrame f  = new JFrame( "Swing - Calculator Homework" );
        JApplet  applet = new Calculatorx();
        applet.init();
        f.setContentPane( applet.getContentPane() );
        f.setBounds( 100, 100, 508, 500 );
        f.setTitle( "Calculator" );
        f.setVisible( true );
        f.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); 
        f.addWindowListener( new WindowAdapter() {        
            public void windowClosed( WindowEvent e ) {
               System.exit( 0 );
            }
        } );
                                  

    }  
    public synchronized void setCalculatorBase( String numberBase )
    {
        System.out.println( "Numberbase = " + numberBase);
        _numberBase = numberBase;
    } 
    public void start()
    {
        calc.setVisible( true );
    }  

    public class  RadioButtonPanel  extends JPanel {
        public RadioButtonPanel( String[] arrayOfButtonsNames, String defaultChoice,
                                 ActionListener listener, Rectangle rect  ) {

            setLayout( new GridLayout( 1, arrayOfButtonsNames.length, 0, 0 )); // Set layout tp GridLayout

            setBounds( rect.x, rect.y, rect.width, rect.height );

            JRadioButton     baseNumberChk[]  = new JRadioButton[arrayOfButtonsNames.length]; // Declare radio button
            ButtonGroup      baseNumberGroup  = new ButtonGroup();                           //Instantiate Button Group
            for ( int i = 0; i< arrayOfButtonsNames.length; i++ ) { // Base Number 
                baseNumberChk[i] = new JRadioButton( arrayOfButtonsNames[i] );
                if ( arrayOfButtonsNames[i].equals( defaultChoice ) )
                    baseNumberChk[i].setSelected( true );

                baseNumberGroup.add( baseNumberChk[i] ); // Add button to group

                if ( listener != null )
                    baseNumberChk[i].addActionListener( listener ); //Add listener

                add(  baseNumberChk[i] );   // Add button to panel
            }
        }
    }

}
