import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

;
/**
 * MathProgram contains two panels, one for inputs, a second for results.
 */
public class MathProgram
{
    private JFrame frame;
    private JPanel leftPanel,centerPanel,southPanel,rightPanel;
    private JButton resultButton;
    private JTextArea resultArea,testArea;
    private JTextField inputField1,inputField2;
    private JList mathList;
    private JLabel label1, label2;
    private JSlider slider1, slider2;
    private int sliderValue1, sliderValue2;
    /**
     * Create an ImageViewer show it on screen.
     */
    public MathProgram()
    {
        makeFrame();
    }
    
    /**
     * Create the Swing frame and its content.
     */
    private void makeFrame()
    {
        frame = new JFrame("Math Program");
        makeMenuBar(frame);
        
        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new BorderLayout());
        

        leftPanel = new JPanel();
        leftPanel.setLayout(new GridLayout(5,1));
        centerPanel = new JPanel();
        GridBagLayout gridbag = new GridBagLayout();
        centerPanel.setLayout(gridbag);
        GridBagConstraints c = new GridBagConstraints();
        southPanel = new JPanel();
        southPanel.setLayout(gridbag);
        rightPanel = new JPanel();

        //LEFT Panel Contents
        inputField1 = new JTextField(" Input 1 ",30);
        leftPanel.add(inputField1);
        
        inputField2 = new JTextField(" Input 2 ",30);
        leftPanel.add(inputField2);
        
        
        resultButton = new JButton("compute");
        leftPanel.add(resultButton);
        
        
         resultButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) { computeResults(); }
         });

         //CENTER Panel Contents
         // JList will let you choose the calculation that is
         // performed whent the calculate button is hit.
         // add the list of operations
         c.gridheight = 13;
         c.weighty = 1.0;
         String[] math = {"Add","Subtract","Multiply",
             "Divide","Mod","Integer Division","Ceil",
             "Sqrt","Log","Sin","Cos","Power","Circle Area"};
         mathList = new JList(math);
         gridbag.setConstraints(mathList,c);
         centerPanel.add(mathList);
         
         // JRadioButtons perform the operation when they are selected.
         // add the radiobuttons to choose from
         JRadioButton addButton = new JRadioButton("Add");
         addButton.setSelected(true);
         JRadioButton subtractButton = new JRadioButton("Subtract");
         JRadioButton multiplyButton = new JRadioButton("Multiply");
         JRadioButton divideButton = new JRadioButton("Divide");
         JRadioButton modButton = new JRadioButton("Mod");
         JRadioButton integerDivisionButton = new JRadioButton("Integer Division");
         JRadioButton ceilButton = new JRadioButton("Ceil");
         JRadioButton sqrtButton = new JRadioButton("Sqrt");
         JRadioButton logButton = new JRadioButton("Log");
         JRadioButton sinButton = new JRadioButton("Sin");
         JRadioButton cosButton = new JRadioButton("Cos");
         JRadioButton powerButton = new JRadioButton("Power");
         JRadioButton circleAreaButton = new JRadioButton("Circle Area");
         
         // put the radio buttons into a group
         ButtonGroup group = new ButtonGroup();
         group.add(addButton);
         group.add(subtractButton);
         group.add(multiplyButton);
         group.add(divideButton);
         group.add(modButton);
         group.add(integerDivisionButton);
         group.add(ceilButton);
         group.add(sqrtButton);
         group.add(logButton);
         group.add(sinButton);
         group.add(cosButton);
         group.add(powerButton);
         group.add(circleAreaButton);
         
         // add the radio buttons to the panel and make them operational
         c.gridheight = 1;
         c.gridwidth = GridBagConstraints.REMAINDER;
         gridbag.setConstraints(addButton,c);
         addButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { add(); }
         });
         centerPanel.add(addButton);
         gridbag.setConstraints(subtractButton,c);
         subtractButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { subtract(); }
         });
         centerPanel.add(subtractButton);
         gridbag.setConstraints(multiplyButton,c);
         multiplyButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { multiply(); }
         });
         centerPanel.add(multiplyButton);
         gridbag.setConstraints(divideButton,c);
         divideButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { divide(); }
         });
         centerPanel.add(divideButton);
         gridbag.setConstraints(modButton,c);
         modButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { mod(); }
         });
         centerPanel.add(modButton);
         gridbag.setConstraints(integerDivisionButton,c);
         integerDivisionButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { integerDivision(); }
         });
         centerPanel.add(integerDivisionButton);
         gridbag.setConstraints(ceilButton,c);
         ceilButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { ceil(); }
         });
         centerPanel.add(ceilButton);
         gridbag.setConstraints(sqrtButton,c);
         sqrtButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { sqrt(); }
         });
         centerPanel.add(sqrtButton);
         gridbag.setConstraints(logButton,c);
         logButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { log(); }
         });
         centerPanel.add(logButton);
         gridbag.setConstraints(sinButton,c);
         sinButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { sin(); }
         });
         centerPanel.add(sinButton);
         gridbag.setConstraints(cosButton,c);
         cosButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { cos(); }
         });
         centerPanel.add(cosButton);
         gridbag.setConstraints(powerButton,c);
         powerButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { power(); }
         });
         centerPanel.add(powerButton);
         gridbag.setConstraints(circleAreaButton,c);
         circleAreaButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) { circleArea(); }
         });
         centerPanel.add(circleAreaButton);
         
         //SOUTH Panel Contents
         c.weightx = 0.3;
         label1 = new JLabel("Input 1");
         southPanel.add(label1);
         c.gridwidth = GridBagConstraints.REMAINDER;
         slider1 = new JSlider(0,100,50);
         slider1.addChangeListener(new ChangeListener() {
             public void stateChanged(ChangeEvent e) {
                 inputField1.setText("" + slider1.getValue());
             }
         });
         southPanel.add(slider1);
         c.weightx = 0.3;
         label2 = new JLabel("Input 2");
         southPanel.add(label2);
         c.gridwidth = GridBagConstraints.REMAINDER;
         slider2 = new JSlider(0,100,50);
         slider2.addChangeListener(new ChangeListener() {
             public void stateChanged(ChangeEvent e) {
                 inputField2.setText("" + slider2.getValue());
             }
         });
         southPanel.add(slider2);
         
         //testArea = new JTextArea("Test Area",10,50);
         //southPanel.add(testArea);

         //RIGHT Panel Contents
         resultArea = new JTextArea("Result Area",20,20);
         rightPanel.add(resultArea);

         // add all of the panels to the contentPane
         contentPane.add(leftPanel,BorderLayout.WEST);
         contentPane.add(centerPanel,BorderLayout.CENTER);
         contentPane.add(southPanel,BorderLayout.SOUTH);
         contentPane.add(rightPanel,BorderLayout.EAST);
        
         // building is done - arrange the components and show        
         frame.setSize(800,400);
         frame.setVisible(true);
    
    }
    
    /**
     * Make the menubar for the frame.
     */
    public void makeMenuBar(JFrame frame)
    {
        JMenuBar menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);
        
        JMenu menu;
        JMenuItem item;
        
        // create the Math menu
        menu = new JMenu("Math");
        menuBar.add(menu);
        
        item = new JMenuItem("Add");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { add(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Subtract");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { subtract(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Multiply");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { multiply(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Divide");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { divide(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Mod");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { mod(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Integer Division");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { integerDivision(); }
             });
        menu.add(item);

        // create the Functions menu
        menu = new JMenu("Functions");
        menuBar.add(menu);
        
        item = new JMenuItem("Ciel");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { ceil(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Sqrt");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { sqrt(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Log");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { log(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Sin");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { sin(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Cos");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { cos(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Power");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { power(); }
             });
        menu.add(item);
        
        item = new JMenuItem("Circle Area");
            item.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) { circleArea(); }
             });
        menu.add(item);
    }
    
    // ---- Menu Bar Functions ----
    
    // Math functions
    
    /**
     * Add function adds two numbers.
     */
    private void add()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double z = x + y;
            String results = "\n    " + x + " + " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Subtract two numbers.
     */
    private void subtract()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double z = x - y;
            String results = "\n    " + x + " - " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Multiply two numbers.
     */
    private void multiply()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double z = x * y;
            String results = "\n    " + x + " * " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Divide two numbers.
     */
    private void divide()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double z = x / y;
            String results = "\n    " + x + " / " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Apply the mod function to two numbers.
     */
    private void mod()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            int x = Integer.parseInt(xString);
            int y = Integer.parseInt(yString);
            int z = (int) ( x - Math.floor( x / y ) * y );
            String results = "\n    " + x + " mod " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Does integer division.
     */
    private void integerDivision()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            int x = Integer.parseInt(xString);
            int y = Integer.parseInt(yString);
            int z = (int)Math.floor( x / y );
            int r = (int)Math.round( x - Math.floor( x / y ) * y );
            String results = "\n    " + x + " / " + y + " = " + z + " r" + r;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    // Function functions
    
    /**
     * Ciel applies the ceiling function
     */
    private void ceil()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // find the ceiling of the first number
        try {
            double x = Double.parseDouble(xString);
            int ceil = (int)Math.ceil( x );
            String results = "\n    Ciel " + x + " = " + ceil;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("\nNumber is not formatted properly");
        }
        
        // find the ceiling of the second number
        try {
            double y = Double.parseDouble(yString);
            int ceil = (int)Math.ceil( y );
            String results = "\n    Ciel " + y + " = " + ceil;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("\nNumber is not formatted properly");
        }
    }
    
    /**
     * Sqrt applies the square root function.
     */
    private void sqrt()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // take the square root of the first text field
        try {
            double x = Double.parseDouble(xString);
            double sqrt = Math.sqrt( x );
            String results = "\n    Sqrt " + x + " = " + sqrt;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
        
        // take the square root of the second text field
        try {
            double y = Double.parseDouble(yString);
            double sqrt = Math.sqrt( y );
            String results = "\n    Sqrt " + y + " = " + sqrt;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Log applies the logorithm function
     */
    private void log()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // apply the function to the text fields.
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double log = Math.log( x ) / Math.log( y );
            String results = "\n    Log " + x + " (base " + y + ") = " + log;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Sin applies the sine wave function.
     */
    private void sin()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // apply the function to the first text field.
        try {
            double x = Double.parseDouble(xString);
            double sin = Math.sin( Math.toRadians( x ));
            String results = "\n    Sin " + x + " = " + sin;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }

        // apply the function to the second text field.
        try {
            double y = Double.parseDouble(yString);
            double sin = Math.sin( Math.toRadians( y ));
            String results = "\n    Sin " + y + " = " + sin;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Cos applies the cosine wave function.
     */
    private void cos()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // apply the function to the first text field.
        try {
            double x = Double.parseDouble(xString);
            double cos = Math.cos( Math.toRadians( x ));
            String results = "\n    Cos " + x + " = " + cos;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }

        // apply the function to the second text field.
        try {
            double y = Double.parseDouble(yString);
            double cos = Math.cos( Math.toRadians( y ));
            String results = "\n    Cos " + y + " = " + cos;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Power applies the power function.
     */
    private void power()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        try {
            double x = Double.parseDouble(xString);
            double y = Double.parseDouble(yString);
            double z = Math.pow( x , y );
            String results = "\n    " + x + " ^ " + y + " = " + z;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    
    /**
     * Circle Area calculates the area of a circle of a given radius.
     */
    private void circleArea()
    {
        String xString = inputField1.getText();
        String yString = inputField2.getText();
        
        // apply the function to the first text field.
        try {
            double x = Double.parseDouble(xString);
            double circle = Math.PI*x*x;
            String results = "\n    pi * " + x + " ^ 2 = " + circle;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }

        // apply the function to the second text field.
        try {
            double y = Double.parseDouble(yString);
            double circle = Math.cos( Math.toRadians( y ));
            String results = "\n    pi * " + y + " ^ 2 = " + circle;
            resultArea.append(results);
        }
        catch(NumberFormatException e)
        {
            resultArea.append("Number is not formatted properly");
        }
    }
    /**
     * Calculate the results of the computation.
     */
    private void computeResults()
    {
        int operation = mathList.getSelectedIndex();
        if(operation == 0) { add(); }
        else if(operation == 1) { subtract(); }
        else if(operation == 2) { multiply(); }
        else if(operation == 3) { divide(); }
        else if(operation == 4) { mod(); }
        else if(operation == 5) { integerDivision(); }
        else if(operation == 6) { ceil(); }
        else if(operation == 7) { sqrt(); }
        else if(operation == 8) { log(); }
        else if(operation == 9) { sin(); }
        else if(operation == 10) { cos(); }
        else if(operation == 11) { power(); }
        else if(operation == 12) { circleArea(); }
        else {
            resultArea.append("Please select an operation from the list");
        }
    }
}
    
    
    


