//Title:       The Serpinsky Triangle
//Version:
//Copyright:   Copyright (c) 1999
//Author:      John Taylor
//Company:
//Description: Draws and allows the user to
//zoom on the Serpinsky Triangle

package sierp;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
//import com.sun.java.swing.*;
import zoomPanelBean.*;
//import jclass.bwt.*;
import java.beans.*;

//import com.sun.java.swing.UIManager;
public class Sierp extends Applet implements Runnable {
    boolean isStandalone = false;
    BorderLayout borderLayout1 = new BorderLayout();
    Label label1 = new Label();
    zoomPanelBean.ZoomPanelBean zoomPanelBean1 = new zoomPanelBean.ZoomPanelBean();

    //Get a parameter value
    public String getParameter(String key, String def) {
        return isStandalone ? System.getProperty(key, def) : (getParameter(key) != null ? getParameter(key) : def);
    }

    // Variables added by JT
    private Image currentView, aboutView;
    static private Thread calculationThread;
    public double x0 = 0, y0 = 0;
    public double x1 = 1, y1 = 0;
    public double x2 = 0.5, y2 = 1.0;
    private boolean showingAboutBox = false;
    Panel panel1 = new Panel();
    Button buttonReset = new Button();
    Button buttonAbout = new Button();

    //Initialize the applet
    public void init() {
        try {
            jbInit();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    //static {
    //  try {
    //    //UIManager.setLookAndFeel(new com.sun.java.swing.plaf.metal.MetalLookAndFeel());
    //    //UIManager.setLookAndFeel(new com.sun.java.swing.plaf.motif.MotifLookAndFeel());
    //    UIManager.setLookAndFeel(new com.sun.java.swing.plaf.windows.WindowsLookAndFeel());
    //  }
    //  catch (Exception e) {}
    //}
    //Component initialization
    private void jbInit() throws Exception {
        this.setBackground(Color.black);
        label1.setForeground(Color.red);
        label1.setBackground(Color.black);
        label1.setAlignment(1);
        label1.setText("The Sierpinsky Triangle");
        buttonReset.setLabel("Reset");
        buttonAbout.setLabel("About");
        buttonAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                buttonAbout_actionPerformed(e);
            }
        });
        buttonReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                buttonReset_actionPerformed(e);
            }
        });
        zoomPanelBean1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent e) {
                zoomPanelBean1_propertyChange(e);
            }
        });
        this.setLayout(borderLayout1);
        this.setSize(400, 300);
        this.add(label1, BorderLayout.NORTH);
        this.add(zoomPanelBean1, BorderLayout.CENTER);
        this.add(panel1, BorderLayout.SOUTH);
        panel1.add(buttonReset, null);
        panel1.add(buttonAbout, null);
    }

    //Get Applet information
    public String getAppletInfo() {
        return "The sierpinsky triangle";
    }

    // Methods added by JT
    public void paint(Graphics appletg) {
        if (currentView == null) {
            appletg.drawString("Help!", 100, 100);
            repaint(10);
        }
    }

    public void start() {
        calculationThread = new Thread(this, "Calculation Thread");
        calculationThread.start();
    }

    public void stop() {
        calculationThread = null; //save resources!
    }

    public void run() {
        currentView = createImage(zoomPanelBean1.getSize().width, zoomPanelBean1.getSize().height);
        Graphics g = currentView.getGraphics();
        double x, y;
        double xmin, xmax, ymin, ymax;
        int corner;
        int numPlottedPoints = 0;
        int xSize, ySize, xAct, yAct;
        xmin = zoomPanelBean1.getLogicalXstart();
        xmax = zoomPanelBean1.getLogicalXend();
        ymin = zoomPanelBean1.getLogicalYstart();
        ymax = zoomPanelBean1.getLogicalYend();
        xSize = zoomPanelBean1.getSize().width;
        ySize = zoomPanelBean1.getSize().height;
        x = Math.random() * (xmax - xmin) + xmin;
        y = Math.random() * (ymax - ymin) + ymin;
        Thread thisThread = Thread.currentThread();
        while ((calculationThread == thisThread) && (numPlottedPoints < 1000000)) {
            // draw some points, then update
            for (int iCount = 0; iCount < 10000; iCount++) {
                xAct = (int)((x - xmin) * xSize / (xmax - xmin));
                yAct = (int)((y - ymin) * ySize / (ymax - ymin));
                if ((xAct > 0) && (xAct < xSize) && (yAct > 0) && (yAct < ySize)) {
                    g.drawLine(xAct, yAct, xAct, yAct);
                    numPlottedPoints++;
                }
                corner = (int)(Math.random() * 3.0);
                switch (corner) {
                    case 0:
                        g.setColor(Color.blue);
                        x += x0; y += y0; x /= 2; y /= 2;
                        break;
                    case 1:
                        g.setColor(Color.yellow);
                        x += x1; y += y1; x /= 2; y /= 2;
                        break;
                    case 2:
                        g.setColor(Color.red);
                        x += x2; y += y2; x /= 2; y /= 2;
                        break;
                }
            }
            zoomPanelBean1.setCurrentImage(currentView);
        }
    }

    void zoomPanelBean1_propertyChange(PropertyChangeEvent e) {
        // Someone's done something to the panel - start a new thread
        //      labelCoords.setText("("+Double.toString(zoomPanelBean1.getLogicalXstart())+","+
        //          Double.toString(zoomPanelBean1.getLogicalYstart())+")-("
        //          +Double.toString(zoomPanelBean1.getLogicalXend())+","+
        //          Double.toString(zoomPanelBean1.getLogicalYend())+")");
        if (!showingAboutBox) {
            if (e.getPropertyName() == "zoom" || e.getPropertyName() == "reset") {
                calculationThread = new Thread(this, "Calculation Thread");
                if (calculationThread != null) {
                    calculationThread.start();
                    calculationThread.setPriority(Thread.MIN_PRIORITY);
                }
            }
        }
    }

    void buttonReset_actionPerformed(ActionEvent e) {
        zoomPanelBean1.reset();
    }

    void buttonAbout_actionPerformed(ActionEvent e) {
        if (showingAboutBox) {
            buttonReset.enable();
            calculationThread.resume();
            showingAboutBox = false;
            buttonAbout.setLabel("About"); buttonAbout.invalidate(); panel1.validate();
            zoomPanelBean1.setCurrentImage(currentView);
        }
        else {
            buttonReset.disable();
            calculationThread.suspend();
            showingAboutBox = true;
            buttonAbout.setLabel("OK"); buttonAbout.invalidate(); panel1.validate();
            aboutView = createImage(zoomPanelBean1.getSize().width, zoomPanelBean1.getSize().height);
            Graphics g = aboutView.getGraphics();
            g.setColor(Color.white);
            g.drawString("Written by JDT.", 0, 20);
            g.setColor(Color.green);
            g.drawString("Click Left button to zoom in", 0, 35);
            g.drawString("Click Right button to zoom out", 0, 50);
            g.drawString("Drag Left button to capture an area", 0, 65);
            zoomPanelBean1.setCurrentImage(aboutView);
        }
    }
}
