
/************************************************************/
/*                  Information Technology                 */
/*                                                                        */
/************************************************************/

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.event.*;

/************************************************************/
/************************************************************/

public class Calculator extends JFrame implements ActionListener,MouseListener,
   ListSelectionListener
{	
	JTextField screenText;     //text in screen label
    JButton []BAraay = new JButton[40];  //array of all buttons
    JMenuItem on,off,copy,paste,about,contents,maginta,black,white,pink,orange,green,red,LIGHT_GRAY,thick;
	
	//borders
	 Border magintaBorder = new LineBorder(new Color(204,102,255), 5, true);
     Border blackBorder = new LineBorder(Color.black, 5, true);
     Border whiteBorder = new LineBorder(Color.white, 5, true);
     Border pinkBorder = new LineBorder(Color.pink, 5, true);
     Border orangeBorder = new LineBorder(new Color(204,153,51), 5, true);
     Border greenBorder = new LineBorder(new Color(0,153,255), 5, true);
     Border redBorder = new LineBorder(Color.gray, 5, true);
     Border LIGHT_GRAYBorder = new LineBorder(Color.LIGHT_GRAY, 5, true);
	
	boolean clearOnNextDigit;
	double lastNumber,result;
	char lastOperator;	
	final int MAX_INPUT_LENGTH = 17;
	String PI = String.valueOf(Math.PI);
	double buffer;   //for copy and paste
	
    int displayMode;
	final int INPUT_MODE = 0;
	/*INPUT_MODE the number being entered by the user
    if the user types a digit when the program is
    in INPUT_MODE, the program should append the digit to the 
    number currently in the display*/
    
    final int RESULT_MODE = 1;
    //result of the last calculation
    /* the display should be cleared and the new digit put at 
     the start.*/
     
    final int ERROR_MODE = 2;//used when exception occures
	
	public Calculator()
	{
		getContentPane().setLayout(new BorderLayout(15,15));
	    setTitle("Calculator");
	    setResizable(false);
	    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	   
/*****************************************************************/	    
	    //Menues
	    
	    JMenuBar mb = new JMenuBar();
	    setJMenuBar(mb);
	    JMenu Edit = new JMenu("Edit");
	    JMenu Help = new JMenu("Help");
	    JMenu Style1 = new JMenu("Style");
	    JMenu Switch = new JMenu("Switch");
	    mb.add(Switch);
	    mb.add(Edit);
	    mb.add(Style1);
	    mb.add(Help);
	    
	    copy = new JMenuItem("Copy");
	    paste = new JMenuItem("Paste");
	    copy.setAccelerator(KeyStroke.getKeyStroke
	    (KeyEvent.VK_C,ActionEvent.CTRL_MASK));
	    paste.setAccelerator(KeyStroke.getKeyStroke
	    (KeyEvent.VK_P,ActionEvent.CTRL_MASK));
	    Edit.add(copy);	    
	    Edit.add(paste);	    
	    
	    about = new JMenuItem("about calculator");
	    contents = new JMenuItem("help contents");
	    Help.add(about);
	    Help.add(contents);
	    
	    on = new JMenuItem("On");
	    off = new JMenuItem("Off");
	    on.setAccelerator(KeyStroke.getKeyStroke
	    (KeyEvent.VK_N,ActionEvent.CTRL_MASK));
	    off.setAccelerator(KeyStroke.getKeyStroke
	    (KeyEvent.VK_F,ActionEvent.CTRL_MASK));
	    Switch.add(on);
	    Switch.add(off);
	    
	    maginta = new JMenuItem("light_maginta");
	    black = new JMenuItem("black color");
	    white = new JMenuItem("white color");
	    pink = new JMenuItem("pink color");
	    orange = new JMenuItem("orange color");
	    green = new JMenuItem("blue");
	    red = new JMenuItem("grey color");
	    LIGHT_GRAY = new JMenuItem("LIGHT_GRAY");
	    
	    Style1.add(maginta);
	    Style1.add(pink);
	    Style1.add(orange);
	    Style1.add(white);
	    Style1.add(black);
	    Style1.add(green);
	    Style1.add(red);
	    Style1.add(LIGHT_GRAY);
	    
	    Edit.addActionListener(this);
	    Help.addActionListener(this);
	    copy.addActionListener(this);
	    paste.addActionListener(this);
	    about.addActionListener(this);
	    contents.addActionListener(this);
	    on.addActionListener(this);
	    off.addActionListener(this);
        maginta.addActionListener(this);
        pink.addActionListener(this);
        orange.addActionListener(this);
        white.addActionListener(this);
        black.addActionListener(this);
        green.addActionListener(this);
        red.addActionListener(this);
        LIGHT_GRAY.addActionListener(this);
 
/*****************************************************************/	    
	    //screen
	    JPanel screen = new JPanel();
	    screenText = new JTextField(25);
	    screenText.setBackground(Color.white);
	    screenText.setEditable(false);
	    screen.add(screenText);
/*****************************************************************/	    
	    //first Panel
	    JPanel FPanel = new JPanel(new GridLayout(4,5,4,4));
	    BAraay[0] = new JButton("sin");
	    BAraay[1] = new JButton("cos");
	    BAraay[2] = new JButton("tan");
	    BAraay[3] = new JButton("floor");
	    BAraay[4] = new JButton("ceil");
	    BAraay[5] = new JButton("sin-1");
	    BAraay[6] = new JButton("cos-1");
	    BAraay[7] = new JButton("tan-1");
	    BAraay[8] = new JButton("roun");	   
	    BAraay[9] = new JButton("rint");
	    BAraay[10] = new JButton("x^2");
	    BAraay[11] = new JButton("x^3");	    
	    BAraay[12] = new JButton("x^y");
	    BAraay[13] = new JButton("e^x");
	    BAraay[14] = new JButton("1/x");    
	    BAraay[15] = new JButton("log");	   
	    BAraay[16] = new JButton("abs");	    	    
	    BAraay[17] = new JButton("n!");
	    BAraay[18] = new JButton("sqrt");	    
	    BAraay[19] = new JButton("-/+");
	    
	    //font for all buttons in calculator
	    Font font = new Font("Arial",Font.BOLD,12);
	    
	    for(int i=0 ; i < 20 ; i++)
	    {
	    //set Font & size to Buttons  
	      BAraay[i].setFont(font);	    	    
	    //Set foreground for buttons
	      BAraay[i].setForeground(Color.blue);	     
	    //Add Buttons to FPanel
	      FPanel.add(BAraay[i]);
	    }
/******************************************************************/	    
	    //second panel
	    JPanel SPanel = new JPanel(new GridLayout(1,2,15,15));
	    
	    //Buttons
	    BAraay[20] = new JButton("7");
	    BAraay[21] = new JButton("8");
	    BAraay[22] = new JButton("9");
	    BAraay[32] = new JButton("Del");
	    BAraay[33] = new JButton("AC");
	    BAraay[23] = new JButton("4");
	    BAraay[24] = new JButton("5");
	    BAraay[25] = new JButton("6");
	    BAraay[34] = new JButton("*");
	    BAraay[35] = new JButton("/");
	    BAraay[26] = new JButton("1");
	    BAraay[27] = new JButton("2");
	    BAraay[28] = new JButton("3");
	    BAraay[36] = new JButton("+");
	    BAraay[37] = new JButton("-");
	    BAraay[29] = new JButton("0");
	    BAraay[30] = new JButton(".");
	    BAraay[31] = new JButton("PI");
	    BAraay[38] = new JButton("%");
	    BAraay[39] = new JButton("=");
	   
	  for(int ii = 20 ; ii<30 ; ii++)
	  {
	    //set font to buttons
	    BAraay[ii].setFont(font);
	    //set Foreground for buttons
	    BAraay[ii].setForeground(Color.magenta);
	  }
	  BAraay[30].setFont(font);
	  BAraay[30].setForeground(Color.blue);
	  BAraay[31].setFont(font);
	  BAraay[31].setForeground(Color.blue);
	  for(int k=32 ; k < 38 ; k++)
	  {
	    BAraay[k].setFont(font);
	    BAraay[k].setForeground(Color.red);
	  }
	  BAraay[38].setFont(font);
	  BAraay[38].setForeground(Color.blue);
	  BAraay[39].setFont(font);
	  BAraay[39].setForeground(Color.red);
	    /////////////////////////////
	    
	    //Numbers Panel	    
	    JPanel numbers = new JPanel(new GridLayout(4,3,4,4));
	    for(int iii=20 ; iii<32 ;iii++)
	      numbers.add(BAraay[iii]);
	    //////////////////////////////
	    //Operation Panel 
	    JPanel Operations = new JPanel(new GridLayout(4,3,4,4));
	    for(int j=32 ; j<40 ; j++)
	      Operations.add(BAraay[j]);
	    
	    //adding numbers and operations to SPanel	    
	    SPanel.add(numbers);
	    SPanel.add(Operations);
/******************************************************************/
     //Add action listener for all buttons 
       for(int jj=0 ; jj<40 ; jj++)
       {
         BAraay[jj].addActionListener(this);
         BAraay[jj].setBackground(new Color(200,230,255));
         BAraay[jj].setBorder(redBorder);
       } 
	   for(int i=0 ; i<40 ; i++)
    	  BAraay[i].addMouseListener(this);	   
	    	 
/******************************************************************/	    	    
	    JPanel p = new JPanel(new BorderLayout());
	    
	    p.add(screen,BorderLayout.NORTH);	
		p.add(FPanel,BorderLayout.CENTER);
		getContentPane().add(p,BorderLayout.CENTER);
		getContentPane().add(SPanel,BorderLayout.SOUTH);
		
		displayResult(0);
		setLocation(150,100);
	  
		pack();
	}
//============================================================
	int i;
	public void actionPerformed(ActionEvent e)
	{	
	   if(e.getSource() instanceof JButton)   
	     processButton(e.getActionCommand());
	   if(e.getSource() instanceof JMenuItem)
	   {
	   	 if(e.getSource() == on)
	   	 {
	   	   for(i=0 ; i<40 ;i++)
	   	     BAraay[i].setEnabled(true);
	   	   setDisplayString("0.0");
	   	 }
	   	 if(e.getSource() == off)
	   	 {
	   	   for(i=0 ; i<40 ;i++)
	   	     BAraay[i].setEnabled(false);
	   	   setDisplayString("");
	   	 }
	     if(e.getSource() == copy)
	       operat('c');
	     if(e.getSource() == paste)
	       operat('p');
	     if(e.getSource() == about)
	       operat('a');
	       
	     if(e.getSource() == maginta)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(magintaBorder);
	     if(e.getSource() == black)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(blackBorder); 
	     if(e.getSource() == white)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(whiteBorder);
	     if(e.getSource() == pink)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(pinkBorder);
	     if(e.getSource() == orange)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(orangeBorder);
	     if(e.getSource() == green)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(greenBorder);
	     if(e.getSource() == red)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(redBorder);
	     if(e.getSource() == LIGHT_GRAY)
	       for(i=0 ; i < 40 ; i++)
	         BAraay[i].setBorder(LIGHT_GRAYBorder); 
	     if(e.getSource() == about)
	       aboutCal();    
	     if(e.getSource() == contents)
	       contents(); 
	   }
	}
//============================================================
    void processButton(String command) 
	{
	   if (command.equals("0")) addDigit(0);
	   if (command.equals("1")) addDigit(1);
	   if (command.equals("2")) addDigit(2);
	   if (command.equals("3")) addDigit(3);
	   if (command.equals("4")) addDigit(4);
	   if (command.equals("5")) addDigit(5);
	   if (command.equals("6")) addDigit(6);
	   if (command.equals("7")) addDigit(7);
	   if (command.equals("8")) addDigit(8);
	   if (command.equals("9")) addDigit(9);
	   if (command.equals(".")) addDecimalPoint();
	   if (command.equals("PI")) setDisplayString(PI);
	   if (command.equals("*")) processOperator('*');
	   if (command.equals("-")) processOperator('-');
	   if (command.equals("/")) processOperator('/');
	   if (command.equals("+")) processOperator('+');
	   if (command.equals("%")) processOperator('%');
	   if (command.equals("=")) processEquals();
	   if (command.equals("-/+")) processSignChange();
	   if (command.equals("AC")) clearAll();
	   if (command.equals("Del")) clearLastEntry();
	   if (command.equals("1/x")) processOperator('x');
	   if (command.equals("sqrt")) processOperator('q');
	   if (command.equals("n!")) processOperator('n');
	   if (command.equals("sin")) processOperator('s');
	   if (command.equals("cos")) processOperator('c');
	   if (command.equals("tan")) processOperator('t');
	   if (command.equals("x^2")) processOperator('2');
	   if (command.equals("x^3")) processOperator('3');
	   if (command.equals("x^y")) processOperator('y');
	   if (command.equals("log")) processOperator('l');
	   if (command.equals("e^x")) processOperator('e');
	   if (command.equals("abs")) processOperator('a');
	   if (command.equals("round")) processOperator('r');
	   if (command.equals("ceil")) processOperator('i');
	   if (command.equals("floor")) processOperator('f');
	   if (command.equals("rint")) processOperator('4');
	   if (command.equals("sin-1")) processOperator('5');
	   if (command.equals("cos-1")) processOperator('6');
	   if (command.equals("tan-1")) processOperator('7');
    }
//============================================================
    void addDigit(int digit)
	{
	  if (clearOnNextDigit)
		setDisplayString("");

	  String inputString = getDisplayString();
	  if ((!inputString.equals("0") || digit > 0)  && inputString.length() < MAX_INPUT_LENGTH)
	  {
		setDisplayString(inputString + digit);
	  }
	  displayMode = INPUT_MODE;
	  clearOnNextDigit = false;
	}
	
//============================================================
    void addDecimalPoint()
	{
	   displayMode = INPUT_MODE;
	   if (clearOnNextDigit)//to prevent put . in the last input
		 setDisplayString("");
	   String inputString = getDisplayString();

	   if (inputString.indexOf(".") < 0) //to prevent put . more than once
		 setDisplayString(new String(inputString + "."));
	}
//============================================================
    double processLastOperator()throws DivideByZeroException
	{
	  double result = 0;
	  double numberInDisplay = getNumberInDisplay();
	  switch (lastOperator)
	  {
		case '*':
			result = lastNumber * numberInDisplay;
			break;
		case '+':
			result = lastNumber + numberInDisplay;
			break;
		case '-':
			result = lastNumber - numberInDisplay;
			break;
		case '/':
			if (numberInDisplay == 0)
				throw (new DivideByZeroException());
			result = lastNumber / numberInDisplay;
			break;
	    case '%':
	        result = lastNumber % numberInDisplay;
	        break;  
   
	    case 'x':
	        result = 1 / lastNumber;
	        break;
	    case 'q':
	        result = Math.sqrt(lastNumber);
	        break;
	    case 'n':
	        result = factorial(lastNumber);
	        break;
	    case 's':
	        result = Math.sin(lastNumber);
	        break;
	    case 'c':
	        result = Math.cos(lastNumber);
	        break;
	    case 't':
	        result = Math.tan(lastNumber);
	        break;
	    case '2':
	        result = Math.pow(lastNumber,2);
	        break;
	    case '3':
	        result = Math.pow(lastNumber,3);
	        break;
	    case 'y':
	        result = Math.pow(lastNumber,numberInDisplay);
	        break;
	    case 'l':
	        result = Math.log(lastNumber);
	        break;
	    case 'e':
	        result = Math.exp(lastNumber);
	        break;
	    case 'a':
	        result = Math.abs(lastNumber);
	        break;
	    case 'r':
	        result = Math.round(lastNumber);
	        break;
	    case 'i':
	        result = Math.ceil(lastNumber);
	        break;
	    case 'f':
	        result = Math.floor(lastNumber);
	        break;
	    case '4':
	        result = Math.rint(lastNumber);
	        break;
	    case '5':
	        result = 1/Math.sin(lastNumber);
	        break;
	    case '6':
	        result = 1/Math.cos(lastNumber);
	        break;
	    case '7':
	        result = 1/Math.tan(lastNumber);
	        break;

	  }		
	return result;
	}
//============================================================
    void processOperator(char op) 
	{
	if (displayMode != ERROR_MODE)
		{
		double numberInDisplay = getNumberInDisplay();
		if (lastOperator != 0)	
		{
			try
			{
				double result = processLastOperator();
				displayResult(result);
				lastNumber = result;
			}
			catch (DivideByZeroException e)
			{
				displayError("Division by zero!");
			}
		}
		else
		{
			lastNumber = numberInDisplay;
		}
		clearOnNextDigit = true;
		lastOperator = op;
		}
	}
//=============================================================
    void displayError(String errorMessage)
	{
	  setDisplayString(errorMessage);
	  lastNumber = 0;
	  displayMode = ERROR_MODE;
	  clearOnNextDigit = true;
	}

//============================================================
    void processEquals()
	{
	  if (displayMode != ERROR_MODE)
	  {
		try
		{
			double result = processLastOperator();
			displayResult(result);
		}
		catch (DivideByZeroException e)
		{
			displayError("Division by zero!");
		}
		lastOperator = 0;
	  }
	}
//============================================================
    void processSignChange()
	{
	  if (displayMode == INPUT_MODE)//display is string
	  {
		String input = getDisplayString();
		if (input.length() > 0)
		{
			if (input.indexOf("-") == 0)
				setDisplayString(input.substring(1));
			else
				setDisplayString("-" + input);
		}
	  }
	  else if (displayMode == RESULT_MODE)//result is double
	  {
		double numberInDisplay = getNumberInDisplay();
		if (numberInDisplay != 0)
			displayResult(-numberInDisplay);
	  }
	}	

//============================================================ 
    void setDisplayString(String s)
	{
	  screenText.setText(s);
	}
//============================================================
    String getDisplayString ()
	{
	  return screenText.getText();
	}
//============================================================
    double getNumberInDisplay()
	{
	   String input = screenText.getText();
	   return Double.parseDouble(input);
	}	
//============================================================
    void displayResult(double result)
	{
	   setDisplayString(Double.toString(result));
	   lastNumber = result;
	   displayMode = RESULT_MODE;
	   clearOnNextDigit = true;
	}
//============================================================    
    void clearLastEntry()
	{
	   String input = screenText.getText();
	   setDisplayString(input.substring(0,input.length()-1));
	   clearOnNextDigit = true;
	   displayMode = INPUT_MODE;
	}
//============================================================
    void clearAll()
	{
	  setDisplayString("0");
	  lastOperator = 0;
	  lastNumber = 0;
	  displayMode = INPUT_MODE;
	  clearOnNextDigit = true;
	}
//============================================================
    double factorial(double number)
    {
    	if(number <= 1)
    	  return 1;
    	else
    	  return (number * factorial(number-1));
    }
//============================================================
    public void operat(char op)
    {
    	double input = getNumberInDisplay();
    	switch(op)
    	{
    		case 'c':
    		    buffer = input;
    		    break;
    		case 'p':
    		    setDisplayString(String.valueOf(buffer));
    		    break;
    		case 'a':
    		    break;
    	}
    }
    
//===========================================================
    public void mouseClicked(MouseEvent e)
    {}
    public void mouseEntered(MouseEvent e)
    {
     if(e.getSource() instanceof JButton)
      {
      	for(int i=0 ; i<40 ; i++)
      	  if(e.getSource() == BAraay[i])
      	  {
    	    BAraay[i].setBackground(Color.white);
          }
      }
    }
    public void mouseExited(MouseEvent e)
    {
      if(e.getSource() instanceof JButton)
      {
      	for(int i=0 ; i<40 ; i++)
      	if(e.getSource() == BAraay[i])
    	  BAraay[i].setBackground(new Color(200,230,255));
      }
    }
    public void mouseReleased(MouseEvent e)
    {}
    public void mousePressed(MouseEvent e)
    {}  
    
//============================================================
    JPanel aboutC;
    void aboutCal()
    {
       JFrame f = new JFrame("about calculator");
       aboutC = new JPanel();
       JLabel pic = new JLabel(new ImageIcon("1.jpg"),SwingConstants.LEFT);
       JLabel text1 = new JLabel("CopyRight is reserved to Amani Dorgham");
       JLabel text2 = new JLabel("This is the first version of this product");
       JLabel text3 = new JLabel("Try it & enjoy your calculations!");
       aboutC.add(pic);
       aboutC.add(text1);
       aboutC.add(text2);
       aboutC.add(text3);
       /*Comic Sans MS*/
       Color color = new Color(0,153,255);
       Font font = new Font("Monotype Corsiva",Font.BOLD,16);
       
       text1.setForeground(color);
       text2.setForeground(color);
       text3.setForeground(color);
       text1.setFont(font);
       text2.setFont(font);
       text3.setFont(font);
       
       f.getContentPane().add(aboutC,BorderLayout.CENTER);
       f.setSize(300,280);
       f.setLocation(220,100);
       f.setResizable(false);
       f.setVisible(true);
    }
    
//===========================================================
JList list;
JTextArea text ;
JPanel p2;
void contents()
{
	JFrame f = new JFrame("Help contents");
	String []s = new String[2];
	s[0] = new String ("General view about calculator");
	s[1] = new String ("Perform calculations");
	list = new JList(s);
	
	//panel 1
	JPanel p1 = new JPanel();
	p1.add(list);
	
	//panel 2
	p2 = new JPanel();
	p2.setForeground(Color.blue);
	text = new JTextArea(13,17);
	text.setWrapStyleWord(true);
	text.setLineWrap(true);
	JScrollPane scroll = new JScrollPane(text);
	p2.add(scroll);
	
	JPanel p3 = new JPanel();
	JLabel l = new JLabel("Welcome in calculator!!");
	Color color = new Color(0,153,255);
    Font font = new Font("Monotype Corsiva",Font.BOLD,16);
	l.setFont(font);
	l.setForeground(color);
	p3.add(l);
	
	JPanel center = new JPanel(new BorderLayout());
	center.add(p1,BorderLayout.WEST);
	center.add(p2,BorderLayout.CENTER);
	//center.setBorder(BorderFactory.createLineBorder(Color.black));
    Border blue = new LineBorder(new Color(0,153,255), 5, true);
	center.setBorder(blue);
	
    f.getContentPane().add(center, BorderLayout.EAST);
    f.getContentPane().add(p3, BorderLayout.NORTH);
	
	list.addListSelectionListener(this);
	//f.setSize(400,280);
	f.pack();
    f.setLocation(220,100);
    f.setResizable(false);
    f.setVisible(true);
}    

//===========================================================
  public void valueChanged(ListSelectionEvent e)
  {
  	 int index = list.getSelectedIndex();
  	 
  	 if(index == 0)
  	 {
  	    String s = new String("General view about calculator: \n\nYou can use calculators to accomplish any of the regular calculations, which are usually used hand calculators created. Calculator complete account statute, such as additions and subtractions, in addition to existing posts in scientific calculator, such as algorithms and factors beating.\n\nGood Luck");
  	    text.setText(s);
  	 }
  	 if(index == 1)
  	 {
  	 	String str = new String("To complete the process of simple or comlex arithmetic operation :\n\n Enter the first number in the calculation.Click + in addition to, or - for subtraction, * for multiply, or / partition.Enter the following number in the calculation.Click = \n\nGood Luck");
  	 	text.setText(str);
  	 }
  }
//===========================================================
    
    public static void main(String []args)
	{
		Calculator frame = new Calculator();
		frame.setVisible(true);
	}
}

/************************/
/************************/
class DivideByZeroException extends Exception
{
	DivideByZeroException()
	{
   	  super("Divide by zero");
	}
}
	