/*
 * @file 	ApplicationFrame.java
 * @author 	Chee Yap (yap@cs.nyu.edu)
 * @source 	Adapted from Knudsen's book (p.8)
 * @date 	July 29, 2001
 *
 * @purpose	
 *	An utility class is defined here:
 *		ApplicationFrame extends Frame.
 *
 *	Users often have some Graphics2D object (perhaps an example from
 *	a book) which they want to display it.
 *	The class gives a simple way to display such an object.
 *
 *	A main method is provided to illustrate the use of this class.
 *	It is an interesting application of "bufferedImage".
 *
 * @notes 	Used for Webbased Visualization Class, Fall'01
 *
 * $Id: ApplicationFrame.java,v 1.1 2003/01/27 14:58:59 yap Exp $
 ************************************************************/

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;

public class ApplicationFrame
    extends Frame {

  ////////////////////////////////////////////////////////////
  // CONSTRUCTORS
  ////////////////////////////////////////////////////////////

  // Default Constructor
  public ApplicationFrame() { this("ApplicationFrame v1.0"); }
  
  // Constructor with Title
  public ApplicationFrame(String title) {
    super(title);
    createUI();
  }
  
  ////////////////////////////////////////////////////////////
  // METHODS
  ////////////////////////////////////////////////////////////

  protected void createUI() {
    setSize(500, 400);
    center();
    setVisible(true);

    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        dispose();
        System.exit(0);
      }
    });
  }//createUI
  
  // Center current frame in the center of screen
  public void center() {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = getSize();
    int x = (screenSize.width - frameSize.width) / 2;
    int y = (screenSize.height - frameSize.height) / 2;
    setLocation(x, y);	// set location of frame in center of screen
  }//center

  ////////////////////////////////////////////////////////////
  // helper function for demo
  ////////////////////////////////////////////////////////////

    // fx(x) computes the sine of x, scaled
    static int fx (int x) {
	double xx = x;
	final int ht = 80;	// to scale height to screen size
	return (2 * ht) +(int)(ht * Math.sin(xx));
    }//fx 

  ////////////////////////////////////////////////////////////
  // MAIN METHOD
  // 	illustrates how to use ApplicationFrames
  ////////////////////////////////////////////////////////////

  public static
    void main(String[] args) {
    
    // (1) construct BufferedImage
    //		N.B. Note the essential use of "final" (try to compile
    //		     without this attribute and see).
    final BufferedImage 
	bImage = new BufferedImage(500, 300,
			BufferedImage.TYPE_INT_RGB);

    // (2) construct Graphics2D object g2 for BufferedImage
    Graphics2D g2 = bImage.createGraphics();
    
    // (3) create image in g2 (plotting a function fx)

    int numPoints = 500; 
    int del = 5;	// try with del=4 and del=8 to see!
    Line2D.Double line;
    Point p0 = new Point(0, fx(0));
    Point p1 = new Point(del, fx(del));
    
    g2.setBackground(Color.blue);
    g2.setPaint(Color.yellow);

    // plot the function fx:
    for (int i=2; i < numPoints; i++) {
	line = new Line2D.Double(p0, p1);
	g2.draw(line);
	p0 = p1; p1 = new Point(i*del, fx(i*del));
    }	// NOTE: a better solution is to use a "general shape"

    // caption for the plot
    g2.setPaint(Color.green);
    g2.drawString("Aliased Sine Curve", 20, 20);  // notice the aliasing

    // (4) get an ApplicationFrame to display g2

    final int border = 100;	// the image g2 will be centered
		 		// in this ApplicationFrame, with
				// a margin of (border/2) all around
    ApplicationFrame f = new ApplicationFrame("myFrame"){

	public void paint(Graphics g){
	  Graphics2D g2 = (Graphics2D)g;
	  g2.drawImage(bImage, border/2, border/2, null);
		// NOTE: border can be accessed here from inner class
		// because it is declared "final".
	}//paint

    };// new ApplicationFrame
    
    // (5) Display the frame!

    f.setSize(500+border,300+border);	// buffered image size is 500x300
    f.center();
    f.setVisible(true);
    
  }//main

}//class ApplicationFrame

