/*
 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 */

import java.awt.Graphics;
import java.util.Stack;
import java.util.Vector;
import java.awt.event.*;

/**
 * A (not-yet) Context sensitive L-System Fractal applet class.
 *
 * The rules for the Context L-system are read from the java.applet.Applet's
 * attributes and then the system is iteratively applied for the
 * given number of levels, possibly drawing each generation as it
 * is generated.  Note that the ContextLSystem class does not yet
 * handle the lContext and rContext attributes, although this
 * class is already designed to parse the '[' and ']' characters
 * typically used in Context sensitive L-Systems.
 *
 * @author      Jim Graham
 */
public class CLSFractal
    extends java.applet.Applet
    implements Runnable, MouseListener {
    Thread kicker;
    ContextLSystem cls;
    int fractLevel = 1;
    int repaintDelay = 50;
    boolean incrementalUpdates;
    float startAngle = 0;
    float rotAngle = 45;
    float Xmin;
    float Xmax;
    float Ymin;
    float Ymax;
    int border;
    boolean normalizescaling;

    public void init() {
        String s;
        cls = new ContextLSystem(this);
        s = getParameter("level");
        if (s != null) fractLevel = Integer.parseInt(s);
        s = getParameter("incremental");
        if (s != null) incrementalUpdates = s.equalsIgnoreCase("true");
        s = getParameter("delay");
        if (s != null) repaintDelay = Integer.parseInt(s);
        s = getParameter("startAngle");
        if (s != null) startAngle = Float.valueOf(s).floatValue();
        s = getParameter("rotAngle");
        if (s != null) rotAngle = Float.valueOf(s).floatValue();
        rotAngle = rotAngle / 360 * 2 * 3.14159265358f;
        s = getParameter("border");
        if (s != null) border = Integer.parseInt(s);
        s = getParameter("normalizescale");
        if (s != null) normalizescaling = s.equalsIgnoreCase("true");
        addMouseListener(this);
    }

    public void destroy() {
        removeMouseListener(this);
    }

    public void run() {
        Thread me = Thread.currentThread();
        boolean needsRepaint = false;
        while (kicker == me && cls.getLevel() < fractLevel) {
            cls.generate();
            if (kicker == me && incrementalUpdates) {
                repaint();
                try {Thread.sleep(repaintDelay);} catch (InterruptedException e){}
            } else {
                needsRepaint = true;
            }
        }
        if (kicker == me) {
            kicker = null;
            if (needsRepaint) {
                repaint();
            }
        }
    }

    public void start() {
        kicker = new Thread(this);
        kicker.start();
    }

    public void stop() {
        kicker = null;
    }

      /*1.1 event handling */
    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
        cls = new ContextLSystem(this);
        savedPath = null;
        start();
        e.consume();
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    String savedPath;

    public void paint(Graphics g) {
        String fractalPath = cls.getPath();
        if (fractalPath == null) {
            super.paint(g);
            return;
        }
        if (savedPath == null || !savedPath.equals(fractalPath)) {
            savedPath = fractalPath;
            render(null, fractalPath);
        }

        for (int i = 0; i < border; i++) {
            g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,false);
        }
        render(g, fractalPath);
    }

    void render(Graphics g, String path) {
        Stack turtleStack = new Stack();
        CLSTurtle turtle;

        if (g == null) {
            Xmin = 1E20f;
            Ymin = 1E20f;
            Xmax = -1E20f;
            Ymax = -1E20f;
            turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1);
        } else {
            float frwidth = Xmax - Xmin;
            if (frwidth == 0)
                frwidth = 1;
            float frheight = Ymax - Ymin;
            if (frheight == 0)
                frheight = 1;
            float xscale = (getSize().width - border * 2 - 1) / frwidth;
            float yscale = (getSize().height - border * 2 - 1) / frheight;
            int xoff = border;
            int yoff = border;
            if (normalizescaling) {
                if (xscale < yscale) {
                    yoff += ((getSize().height - border * 2)
                             - ((Ymax - Ymin) * xscale)) / 2;
                    yscale = xscale;
                } else if (yscale < xscale) {
                    xoff += ((getSize().width - border * 2)
                             - ((Xmax - Xmin) * yscale)) / 2;
                    xscale = yscale;
                }
            }
            turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin,
                                   xoff, yoff, xscale, yscale);
        }

        for (int pos = 0; pos < path.length(); pos++) {
            switch (path.charAt(pos)) {
            case '+':
                turtle.rotate(rotAngle);
                break;
            case '-':
                turtle.rotate(-rotAngle);
                break;
            case '[':
                turtleStack.push(turtle);
                turtle = new CLSTurtle(turtle);
                break;
            case ']':
                turtle = (CLSTurtle) turtleStack.pop();
                break;
            case 'f':
                turtle.jump();
                break;
            case 'F':
                if (g == null) {
                    includePt(turtle.X, turtle.Y);
                    turtle.jump();
                    includePt(turtle.X, turtle.Y);
                } else {
                    turtle.draw(g);
                }
                break;
            default:
                break;
            }
        }
    }

    void includePt(float x, float y) {
        if (x < Xmin)
            Xmin = x;
        if (x > Xmax)
            Xmax = x;
        if (y < Ymin)
            Ymin = y;
        if (y > Ymax)
            Ymax = y;
    }

  public String getAppletInfo() {
    return "Title: CLSFractal 1.1f, 27 Mar 1995 \nAuthor: Jim Graham \nA (not yet) Context Sensitive L-System production rule. \nThis class encapsulates a production rule for a Context Sensitive\n L-System \n(pred, succ, lContext, rContext).  The matches() method, however, does not \n(yet) verify the lContext and rContext parts of the rule.";
  }

  public String[][] getParameterInfo() {
    String[][] info = {
      {"level", "int", "Maximum number of recursions.  Default is 1."},
      {"incremental","boolean","Whether or not to repaint between recursions.  Default is true."},
      {"delay","integer","Sets delay between repaints.  Default is 50."},
      {"startAngle","float","Sets the starting angle.  Default is 0."},
      {"rotAngle","float","Sets the rotation angle.  Default is 45."},
      {"border","integer","Width of border.  Default is 2."},
      {"normalizeScale","boolean","Whether or not to normalize the scaling.  Default is true."},
      {"pred","String","Initializes the rules for Context Sensitive L-Systems."},
      {"succ","String","Initializes the rules for Context Sensitive L-Systems."},
      {"lContext","String","Initializes the rules for Context Sensitive L-Systems."},
      {"rContext","String","Initializes the rules for Context Sensitive L-Systems."}
    };
    return info;
  }
}

/**
 * A Logo turtle class designed to support Context sensitive L-Systems.
 *
 * This turtle performs a few basic maneuvers needed to support the
 * set of characters used in Context sensitive L-Systems "+-fF[]".
 *
 * @author      Jim Graham
 */
class CLSTurtle {
    float angle;
    float X;
    float Y;
    float scaleX;
    float scaleY;
    int xoff;
    int yoff;

    public CLSTurtle(float ang, float x, float y,
                     int xorg, int yorg, float sx, float sy) {
        angle = ang;
        scaleX = sx;
        scaleY = sy;
        X = x * sx;
        Y = y * sy;
        xoff = xorg;
        yoff = yorg;
    }

    public CLSTurtle(CLSTurtle turtle) {
        angle = turtle.angle;
        X = turtle.X;
        Y = turtle.Y;
        scaleX = turtle.scaleX;
        scaleY = turtle.scaleY;
        xoff = turtle.xoff;
        yoff = turtle.yoff;
    }

    public void rotate(float theta) {
        angle += theta;
    }

    public void jump() {
        X += (float) Math.cos(angle) * scaleX;
        Y += (float) Math.sin(angle) * scaleY;
    }

    public void draw(Graphics g) {
        float x = X + (float) Math.cos(angle) * scaleX;
        float y = Y + (float) Math.sin(angle) * scaleY;
        g.drawLine((int) X + xoff, (int) Y + yoff,
                   (int) x + xoff, (int) y + yoff);
        X = x;
        Y = y;
    }
}

/**
 * A (non-)Context sensitive L-System class.
 *
 * This class initializes the rules for Context sensitive L-Systems
 * (pred, succ, lContext, rContext) from the given java.applet.Applet's attributes.
 * The generate() method, however, does not (yet) apply the lContext
 * and rContext parts of the rules.
 *
 * @author      Jim Graham
 */
class ContextLSystem {
    String axiom;
    Vector rules = new Vector();
    int level;

    public ContextLSystem(java.applet.Applet app) {
        axiom = app.getParameter("axiom");
        int num = 1;
        while (true) {
            String pred = app.getParameter("pred"+num);
            String succ = app.getParameter("succ"+num);
            if (pred == null || succ == null) {
                break;
            }
            rules.addElement(new CLSRule(pred, succ,
                                         app.getParameter("lContext"+num),
                                         app.getParameter("rContext"+num)));
            num++;
        }
        currentPath = new StringBuffer(axiom);
        level = 0;
    }

    public int getLevel() {
        return level;
    }

    StringBuffer currentPath;

    public synchronized String getPath() {
        return ((currentPath == null) ? null : currentPath.toString());
    }

    private synchronized void setPath(StringBuffer path) {
        currentPath = path;
        level++;
    }

    public void generate() {
        StringBuffer newPath = new StringBuffer();
        int pos = 0;
        while (pos < currentPath.length()) {
            CLSRule rule = findRule(pos);
            if (rule == null) {
                newPath.append(currentPath.charAt(pos));
                pos++;
            } else {
                newPath.append(rule.succ);
                pos += rule.pred.length();
            }
        }
        setPath(newPath);
    }

    public CLSRule findRule(int pos) {
        for (int i = 0; i < rules.size(); i++) {
            CLSRule rule = (CLSRule) rules.elementAt(i);
            if (rule.matches(currentPath, pos)) {
                return rule;
            }
        }
        return null;
    }
}

/**
 * A Context sensitive L-System production rule.
 *
 * This class encapsulates a production rule for a Context sensitive
 * L-System (pred, succ, lContext, rContext).
 * The matches() method, however, does not (yet) verify the lContext
 * and rContext parts of the rule.
 *
 * @author      Jim Graham
 */
class CLSRule {
    String pred;
    String succ;
    String lContext;
    String rContext;

    public CLSRule(String p, String d, String l, String r) {
        pred = p;
        succ = d;
        lContext = l;
        rContext = r;
    }

    public boolean matches(StringBuffer sb, int pos) {
        if (pos + pred.length() > sb.length()) {
            return false;
        }
        char cb[] = new char[pred.length()];
        sb.getChars(pos, pos + pred.length(), cb, 0);
        return pred.equals(new String(cb));
    }
}
