/*
 *   Copyright (C) 2001 Bryce Allen
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;

public class TransformApplet extends JApplet
	implements ActionListener, ItemListener, SwingConstants
{
	private DrawPanel2D canvas;
	private MatrixPanel matrixPanel;
	private JRadioButton rotateButton;
	private JRadioButton translateButton;
	private JRadioButton scaleButton;
	private JRadioButton shearButton;

	private JTextField rotationAngleField;
	private JTextField rotationXField;
	private JTextField rotationYField;

	private JTextField translationXField;
	private JTextField translationYField;

	private JTextField xScaleField;
	private JTextField yScaleField;

	private JTextField xShearField;
	private JTextField yShearField;

	private JTextField repeatField;
		
	public void init()
	{
//		setTitle("TransformApplet");
		setSize(720, 520);
		Container contentPane = getContentPane();
		canvas = new DrawPanel2D();
		contentPane.add(canvas, "Center");

		Box controlPanel = new Box(BoxLayout.Y_AXIS);
		
		Border border = BorderFactory.createEtchedBorder();
		border = BorderFactory.createTitledBorder(border, "Rotate",
												  TitledBorder.LEFT, 
												  TitledBorder.TOP);
		JPanel rotatePanel = new JPanel();
		rotatePanel.setBorder(border);
		rotatePanel.add(new JLabel("Theta:", RIGHT));
		rotationAngleField = new JTextField("45", 3);
		rotatePanel.add(rotationAngleField);
		rotatePanel.add(new JLabel("x:", RIGHT));
		rotationXField = new JTextField("0", 4);
		rotatePanel.add(rotationXField);
		rotatePanel.add(new JLabel("y:", RIGHT));
		rotationYField = new JTextField("0", 4);
		rotatePanel.add(rotationYField);
		JButton rotateButton = new JButton("Rotate");
		rotateButton.addActionListener(this);
		rotatePanel.add(rotateButton);
		controlPanel.add(rotatePanel);
		
		border = BorderFactory.createEtchedBorder();
		border = BorderFactory.createTitledBorder(border, "Translate",
												  TitledBorder.LEFT, 
												  TitledBorder.TOP);
		JPanel trasnlatePanel = new JPanel();
		trasnlatePanel.setBorder(border);
		trasnlatePanel.add(new JLabel("x:", RIGHT));
		translationXField = new JTextField("0", 4);
		trasnlatePanel.add(translationXField);
		trasnlatePanel.add(new JLabel("y:", RIGHT));
		translationYField = new JTextField("0", 4);
		trasnlatePanel.add(translationYField);
		JButton translateButton = new JButton("Translate");
		translateButton.addActionListener(this);
		trasnlatePanel.add(translateButton);
		controlPanel.add(trasnlatePanel);
	
		border = BorderFactory.createEtchedBorder();
		border = BorderFactory.createTitledBorder(border, "Scale",
												  TitledBorder.LEFT, 
												  TitledBorder.TOP);
		JPanel scalePanel = new JPanel();
		scalePanel.setBorder(border);
		scalePanel.add(new JLabel("x:", RIGHT));
		xScaleField = new JTextField("1", 2);
		scalePanel.add(xScaleField);
		scalePanel.add(new JLabel("y:", RIGHT));
		yScaleField = new JTextField("1", 2);
		scalePanel.add(yScaleField);
		JButton scaleButton = new JButton("Scale");
		scaleButton.addActionListener(this);
		scalePanel.add(scaleButton);
		controlPanel.add(scalePanel);
	
		border = BorderFactory.createEtchedBorder();
		border = BorderFactory.createTitledBorder(border, "Shear",
												  TitledBorder.LEFT, 
												  TitledBorder.TOP);
		JPanel shearPanel = new JPanel();
		shearPanel.setBorder(border);
		shearPanel.add(new JLabel("x:", RIGHT));
		xShearField = new JTextField("0", 2);
		shearPanel.add(xShearField);
		shearPanel.add(new JLabel("y:", RIGHT));
		yShearField = new JTextField("0", 2);
		shearPanel.add(yShearField);
		JButton shearButton = new JButton("Shear");
		shearButton.addActionListener(this);
		shearPanel.add(shearButton);
		controlPanel.add(shearPanel);

		border = BorderFactory.createEtchedBorder();
		border = BorderFactory.createTitledBorder(border, "Reflect",
												  TitledBorder.LEFT, 
												  TitledBorder.TOP);
		JPanel reflectPanel = new JPanel();
		reflectPanel.setBorder(border);
		JButton reflectXButton = new JButton("Reflect X");
		reflectXButton.addActionListener(this);
		reflectPanel.add(reflectXButton);
		JButton reflectYButton = new JButton("Reflect Y");
		reflectYButton.addActionListener(this);
		reflectPanel.add(reflectYButton);
		controlPanel.add(reflectPanel);

		JPanel resetPanel = new JPanel();
		JButton clearShapesButton = new JButton("Clear Screen");
		clearShapesButton.addActionListener(this);
		resetPanel.add(clearShapesButton);
		JButton resetButton = new JButton("Clear Transformations");
		resetButton.addActionListener(this);
		resetPanel.add(resetButton);
		controlPanel.add(resetPanel);
		
		JPanel repeatPanel = new JPanel();
		repeatField = new JTextField("1", 4);
		repeatPanel.add(new JLabel("Repeat:"));
		repeatPanel.add(repeatField);
		controlPanel.add(repeatPanel);

		matrixPanel = new MatrixPanel();
		controlPanel.add(matrixPanel);
		
		JPanel drawToolPanel = new JPanel();
		ButtonGroup drawToolGroup = new ButtonGroup();
		JRadioButton vectorButton = new JRadioButton("Vector", true);
		vectorButton.addActionListener(this);
		drawToolGroup.add(vectorButton);
		JRadioButton lineButton = new JRadioButton("Line");
		lineButton.addActionListener(this);
		drawToolGroup.add(lineButton);
		JRadioButton rectButton = new JRadioButton("Rectangle");
		rectButton.addActionListener(this);
		drawToolGroup.add(rectButton);
		drawToolPanel.add(vectorButton);
		drawToolPanel.add(lineButton);
		drawToolPanel.add(rectButton);
		
		JPanel optionPanel = new JPanel();
		JCheckBox showAxesCheck = new JCheckBox("Show axes", true);
		JCheckBox showGridCheck = new JCheckBox("Show grid", true);
		JCheckBox showCoordinatesCheck = new JCheckBox("Show coordinates", true);
		JCheckBox snapToGridCheck = new JCheckBox("Snap to grid", true);
		JCheckBox cartesianCoordinatesCheck = new JCheckBox("Cartesian coordinates", false);
		showAxesCheck.addItemListener(this);
		showGridCheck.addItemListener(this);
		showCoordinatesCheck.addItemListener(this);
		snapToGridCheck.addItemListener(this);
		cartesianCoordinatesCheck.addItemListener(this);
		optionPanel.add(showAxesCheck);
		optionPanel.add(showGridCheck);
		optionPanel.add(showCoordinatesCheck);
		optionPanel.add(snapToGridCheck);
		optionPanel.add(cartesianCoordinatesCheck);
		
		contentPane.add(drawToolPanel, "North");
		contentPane.add(controlPanel, "East");
		contentPane.add(optionPanel, "South");
	}

	public void actionPerformed(ActionEvent ae)
	{
		Object source = ae.getSource();
		String command = ae.getActionCommand();
		if (command.equalsIgnoreCase("rotate"))
		{
			double theta = Double.parseDouble(rotationAngleField.getText());
			double x = Double.parseDouble(rotationXField.getText());
			double y = Double.parseDouble(rotationYField.getText());
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.rotate(theta, x, y);
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("translate"))
		{
			double x = Double.parseDouble(translationXField.getText());
			double y = Double.parseDouble(translationYField.getText());
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.translate(x, y);
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("scale"))
		{
			double xScale = Double.parseDouble(xScaleField.getText());
			double yScale = Double.parseDouble(yScaleField.getText());
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.scale(xScale, yScale);
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("shear"))
		{
			double xShear = Double.parseDouble(xShearField.getText());
			double yShear = Double.parseDouble(yShearField.getText());
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.shear(xShear, yShear);
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("reflect x"))
		{
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.reflectAcrossX();
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("reflect y"))
		{
			int repeat = Integer.parseInt(repeatField.getText());
			for(int i=0; i < repeat; ++i)
			{
				canvas.reflectAcrossY();
			}
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("clear transformations"))
		{
			canvas.resetTransform();
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("clear screen"))
		{
			canvas.clearAll();
			matrixPanel.setMatrix(canvas.getMatrix());
		}
		else if (command.equalsIgnoreCase("vector"))
		{
			canvas.setDrawMode(DrawPanel2D.DRAW_MODE_VECTOR);
		}
		else if (command.equalsIgnoreCase("line"))
		{
			canvas.setDrawMode(DrawPanel2D.DRAW_MODE_LINE);
		}
		else if (command.equalsIgnoreCase("rectangle"))
		{
			canvas.setDrawMode(DrawPanel2D.DRAW_MODE_RECT);
		}
	}

	 public void itemStateChanged(ItemEvent e)
	 {
		JCheckBox src = (JCheckBox)e.getItemSelectable();
		String name = src.getText();
		boolean value = (e.getStateChange() == ItemEvent.SELECTED);
		if(name.equalsIgnoreCase("show axes"))
		{
			canvas.setShowAxes(value);
		}
		else if(name.equalsIgnoreCase("show grid"))
		{
			canvas.setShowGrid(value);
		}
		else if(name.equalsIgnoreCase("show coordinates"))
		{
			canvas.setShowCoordinates(value);
		}
		else if(name.equalsIgnoreCase("snap to grid"))
		{
			canvas.setSnapToGrid(value);
		}
		else if(name.equalsIgnoreCase("cartesian coordinates"))
		{
			canvas.setCartesianCoordinates(value);
		}
	 }
}

