import java.awt.*;

public class GeometryWindow extends Canvas
{
     Graphics g, bg;
     double centerX, centerY, width, height;
     double xll, yll, xur, yur;
     int iwidth = -1, iheight = -1;
     double aspectRatio;  // width / height
     boolean scaleOnSize = false;
     
     int pointRadius = 4;

     Image backBuffer;

     public GeometryWindow()
     {
	  setBackground(Color.white);
	  Setup(0, 0, 2.0);
     }

     private void Setup(double CenterX, double CenterY, double Width)
     {
	  centerX = CenterX;
	  centerY = CenterY;
	  width = Width;

	  setBackground(Color.white);
     }

     public void setScaleOnSize(boolean flag)
     {
	  scaleOnSize = flag;
     }
     
     public void setView(double CenterX, double CenterY, double Width)
     {
	  centerX = CenterX;
	  centerY = CenterY;
	  width = Width;
     }

     public void setBackgroundColor(Color col)
     {
	  setBackground(col);
     }

     public void setBackgroundColor(double r, double g, double b)
     {
	  Color col = new Color((float)r, (float)g, (float)b);
	  setBackgroundColor(col);
     }

     public void setBackgroundColor(int r, int g, int b)
     {
	  Color col = new Color(r, g, b);
	  setBackgroundColor(r, g, b);
     }
     
     public void setColor(Color col)
     {
	  bg.setColor(col);
	  g.setColor(col);
     }

     public void setColor(double r, double g, double b)
     {
	  Color col = new Color((float)r, (float)g, (float)b);
	  setColor(col);
     }

     public void setColor(int r, int g, int b)
     {
	  Color col = new Color(r, g, b);
	  setColor(col);
     }

     public void setPointRadius(int r)
     {
	  pointRadius = r;
     }

     public void drawPixel(double x, double y)
     {
	  int ix = xmap(x);
	  int iy = ymap(y);
	  
	  bg.drawLine(ix, iy, ix+1, iy);
     }

     public void drawPoint(double x, double y)
     {
	  int ix = xmap(x);
	  int iy = ymap(y);

	  bg.fillOval(ix - pointRadius, iy - pointRadius,
		      2*pointRadius, 2*pointRadius);
     }

     public void drawSegment(double x1, double y1, double x2, double y2)
     {
	  bg.drawLine(xmap(x1), ymap(y1), xmap(x2), ymap(y2));
     }

     public void drawCircle(double cx, double cy, double radius)
     {
	  int icx = xmap(cx);
	  int icy = ymap(cy);
	  int irx = widthmap(radius);
	  int iry = heightmap(radius);

	  bg.drawOval(icx - irx, icy - iry, 2*irx, 2*iry);
     }

     public void fillCircle(double cx, double cy, double radius)
     {
	  int icx = xmap(cx);
	  int icy = ymap(cy);
	  int irx = widthmap(radius);
	  int iry = heightmap(radius);

	  bg.fillOval(icx - irx, icy - iry, 2*irx, 2*iry);
     }

     public void print(String s, double x, double y)
     {
	  int ix = xmap(x);
	  int iy = ymap(y);

	  bg.drawString(s, ix, iy);
     }

     public void eraseWindow()
     {
	  bg.clearRect(0, 0, iwidth, iheight);
     }
	 
     public void displayScene()
     {
	  g.drawImage(backBuffer, 0, 0, this);
     }

     int xmap(double x)
     {
	  return( (int)((x - xll) / width * iwidth) );
     }

     int ymap(double y)
     {
	  return( (int)((yur - y) / height * iheight) );
     }

     int widthmap(double w)
     {
	  return( (int)(w / width * iwidth) );
     }

     int heightmap(double h)
     {
	  return( (int)(h / height * iheight) );
     }

     double xCoordinate(int x)
     {
	  return(x * width / iwidth + xll);
     }

     double yCoordinate(int y)
     {
	  return(yur - y * height / iheight);
     }

     public void paint(Graphics G)
     {
	  Dimension size = size();

	  if ((size.width != iwidth) || (size.height != iheight))
	  {
	       double oldWidth = iwidth;
//	       double oldHeight = iheight;
	       iwidth = size.width;
	       iheight = size.height;

	       aspectRatio = (double)iwidth / (double)iheight;

	       if ((!scaleOnSize) && (oldWidth > 0))
		    width = width * (iwidth / oldWidth);

	       height = width / aspectRatio;
	       xll = centerX - width / 2;
	       yll = centerY - height / 2;
	       xur = centerX + width / 2;
	       yur = centerY + height / 2;

	       backBuffer = createImage(iwidth, iheight);
	       bg = backBuffer.getGraphics();
	       g = getGraphics();
	       getParent().repaint();
	  }
	  g.drawImage(backBuffer, 0, 0, this);
     }
};

