/*
 *  ==================================================================
 *  DemoLine.java : This applet demonstrates line drawing for a house,
 *  and includes a number of sliders for manipulation of the house
 *  position and geometry/shape. Take a look at this applet if you
 *  want to create a drawing canvas.
 * 
 *  Adapted from : Pantham S., Pure JFC Swing, 1999.
 *  Modified by : Mark Austin                              March, 2001
 *  ==================================================================
 */

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

public class DemoLine extends JApplet {
    DrawingCanvas canvas;
    JSlider slider, slider1, slider2, slider3,
            slider4, slider5, slider6, slider7,
            slider8;

    // Translation distances in x- and y- directions

    double transX = 0.0;
    double transY = 0.0;

    // Rotation parameters: Theta and center of rotation.

    double rotateTheta = 0.0;
    double rotateX = 150.0;
    double rotateY = 150.0;

    // Scaling factors in the x- and y- directions

    double scaleX = 1.0;
    double scaleY = 1.0;

    // Parameters to control the width

    float width = 1.0f;

    public void init() {

        // 1. Get the content pane and assign layout

        Container container = getContentPane();

        // 2. Add a control panel to the applet

        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new GridLayout(3, 3));
        container.add(controlPanel, BorderLayout.NORTH);

        // 3. Add a border

        TitledBorder border = new TitledBorder("Control Panel"); 
        controlPanel.setBorder(border);                         

        // 4. Add controls to the panel

        JLabel label1 = new JLabel("Translate(dx,dy): ");
        JLabel label2 = new JLabel("Rotate(Theta,ox,oy): ");
        JLabel label3 = new JLabel("Scale(sx,sy)x10E-2:");

        // To control translation 

        controlPanel.add(label1);
        setSlider(controlPanel, JSlider.HORIZONTAL,
                  0, 300, 150, 100, 50);
        slider1 = slider;
        setSlider(controlPanel, JSlider.HORIZONTAL,
                  0, 300, 150, 100, 50);
        slider2 = slider;

        // To control rotation

        controlPanel.add(label2);
        setSlider(controlPanel, JSlider.HORIZONTAL,
                  0, 360, 0, 90, 45);
        slider3 = slider;

        JPanel subPanel = new JPanel();
        subPanel.setLayout(new GridLayout(1, 2));

        setSlider(subPanel, JSlider.HORIZONTAL,
                  0, 300, 150, 150, 50);
        slider4 = slider;
        setSlider(subPanel, JSlider.HORIZONTAL,
                  0, 300, 150, 150, 50);
        slider5 = slider;
        controlPanel.add(subPanel);

        // To control scaling

        controlPanel.add(label3);
        setSlider(controlPanel, JSlider.HORIZONTAL,
                  0, 200, 100, 100, 10);
        slider6 = slider;
        setSlider(controlPanel, JSlider.HORIZONTAL,
                  0, 200, 100, 100, 10);
        slider7 = slider;

        // To control width of line segments

        JLabel label4 = new JLabel("Width Control:", JLabel.RIGHT);
        slider8 = new JSlider(JSlider.HORIZONTAL, 0, 20, 1);
        slider8.setPaintTicks(true);
        slider8.setMajorTickSpacing(5);
        slider8.setMinorTickSpacing(1);
        slider8.setPaintLabels(true);
        slider8.addChangeListener(new SliderListener());

        JPanel widthPanel = new JPanel();
        widthPanel.setLayout(new GridLayout(1,2));
        widthPanel.add(label4);
        widthPanel.add(slider8);

        container.add(widthPanel, BorderLayout.SOUTH);

        // 5. Add the drawing canvas to the applet

        canvas = new DrawingCanvas();
        container.add(canvas);
    }

    // 6. Creates a slider object with the required tick marks

    public void setSlider(JPanel panel, int orientation,
                          int minimumValue, int maximumValue,
                          int initValue,
                          int majorTickSpacing,
                          int minorTickSpacing) {
        slider = new JSlider(orientation,
                             minimumValue, maximumValue,
                             initValue);
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(majorTickSpacing);
        slider.setMinorTickSpacing(minorTickSpacing);
        slider.setPaintLabels(true);
        slider.addChangeListener(new SliderListener());
        panel.add(slider);
    }

    // 7. Slider listener class; Methods retrive the values from
    // the sliders and assign them to the respective parameters.
    // These parameters are used to set up the graphics context.
    // Next call the repaint() method on canvas.

    class SliderListener implements ChangeListener {
        public void stateChanged(ChangeEvent e) {
            JSlider tempSlider = (JSlider) e.getSource();

            if (tempSlider.equals(slider1)) {
                transX = slider1.getValue()-150.0;
                canvas.repaint();
            }
            else if (tempSlider.equals(slider2)) {
                transY = slider2.getValue()-150.0;
                canvas.repaint();
            }
            else if (tempSlider.equals(slider3)) {
                rotateTheta = slider3.getValue()*Math.PI/180;
                canvas.repaint();
            }
            else if (tempSlider.equals(slider4)) {
                rotateX = slider4.getValue();
                canvas.repaint();
            }
            else if (tempSlider.equals(slider5)) {
                rotateY = slider5.getValue();
                canvas.repaint();
            }
            else if (tempSlider.equals(slider6)) {
                if (slider6.getValue() != 0.0) {
                    scaleX = slider6.getValue()/100.0;
                    canvas.repaint();
                }
            }
            else if (tempSlider.equals(slider7)) {
                if (slider7.getValue() != 0.0) {
                    scaleY = slider7.getValue()/100.0;
                    canvas.repaint();
                }
            }
            else if (tempSlider.equals(slider8)) {
                width = slider8.getValue();
                canvas.repaint();
            }
        }
    }

    // 8. Drawing canvas to draw the line segments

    class DrawingCanvas extends Canvas {
        public DrawingCanvas() {
            setBackground(Color.white);
            setSize(300, 300);
        }

        public void paint(Graphics g) {
            Graphics2D g2D = (Graphics2D) g;

            // 9. Assign the translation, rotation and scaling
            // parameters to the graphics context.

            g2D.translate(transX, transY);
            g2D.rotate(rotateTheta, rotateX, rotateY);
            g2D.scale(scaleX, scaleY);

            // 10. Assign the stroke object that contains the new
            // width for line segments

            BasicStroke stroke = new BasicStroke(width);
            g2D.setStroke(stroke);

            // 11. Now draw the line segments that build a home view.

            drawHome(g2D);
        }

        public void drawHome(Graphics2D g2D) {

            // 12. Create line segments for home

            Line2D line1 = new Line2D.Float(100f, 200f, 200f, 200f);
            Line2D line2 = new Line2D.Float(100f, 200f, 100f, 100f);
            Line2D line3 = new Line2D.Float(100f, 100f, 150f, 50f);
            Line2D line4 = new Line2D.Float(150f, 50f,  200f, 100f);
            Line2D line5 = new Line2D.Float(200f, 100f, 200f, 200f);
            Line2D line6 = new Line2D.Float(140f, 200f, 140f, 150f);
            Line2D line7 = new Line2D.Float(140f, 150f, 160f, 150f);
            Line2D line8 = new Line2D.Float(160f, 150f, 160f, 200f);

            // 13. Now draw the line segments

            g2D.draw(line1);
            g2D.draw(line2);
            g2D.draw(line3);
            g2D.draw(line4);
            g2D.draw(line5);
            g2D.draw(line6);
            g2D.draw(line7);
            g2D.draw(line8);
        }
    }
}
