/*
 * ModelDraw - Basic Hierarchical Model Drawer
 *
 * Uses the GrInstance and GrObject classes
 * 
 * Don Fussell
 * October 2002
 */

import java.awt.*;
import java.awt.geom.*;

public class ModelDraw extends AnimationFrame {

    private Color deepBlue = new Color(0,50,100);

    private GrModel model;

    // I put this here so I wouldn't have to pass it as a parameter
    // through my recursive painting code.
    private Graphics2D g2;

    // Constructor
    public ModelDraw() {   

	super("Hierarchical Modeling");
	
	model = new GrModel();
	setVisible(true); 
    }

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

	AffineTransform curTrans = new AffineTransform();

	// Anti-aliasing 
	g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			    RenderingHints.VALUE_ANTIALIAS_ON);
    

	// Everything is one color, this really ought to be in the
	// hierarchical  structure.
	g2.setColor(deepBlue);

	// Start the recursive painting process
	doPaint(model.getRoot(), curTrans);
    }

    public void doPaint(GrInstance inst, AffineTransform cT) {

	// Copy the current transformation before we modify it.
	// Otherwise the transformation stack isn't maintained
	// properly in the recursion.
	AffineTransform curTrans = new AffineTransform(cT);

	// Concatenate the instance transform with the current transform.
	curTrans.concatenate(inst.transform);

	// Draw all the shapes in the current instance.
	while (inst.moreShapes()) {
	    Shape s = inst.nextShape();

	    // I really wish we didn't have to create the actual transformed
	    // object to draw it, but it's too ugly to avoid doing this, even
	    // though it is possible, in Java2D.
	    Shape ts = curTrans.createTransformedShape(s);
	    g2.fill(ts);	    
	}

	// Process all the subinstances in a depth-first manner.
	while (inst.moreInstances()) {
	    GrInstance i = inst.nextInstance();
	    doPaint(i, curTrans);
	}
    }

    // All the animation work is in moveStuff.
    public void timeStep() {
	model.moveModel();
    }


    public static void main(String[] args) {
	ModelDraw hierarchy = new ModelDraw();

	// Create the Thread object from the Hierarchy object.
	Thread t = new Thread(hierarchy); 
	t.start();  // Call the run method.
    }

}
