import java.awt.*;
import java.applet.Applet;
import java.lang.Math;

public class Asst7 extends Applet {
    DrawingCanvas canvas;

    public void init() {
        GridLayout grid = new GridLayout(1,0);
        setLayout(grid);

	add (new DrawingCanvas());
	
        validate();
    }

}


class DrawingCanvas extends Canvas {
  // Shapes
  private static final int MAX_SHAPES=7;
  private static final int OVAL=0;
  private static final int SOLID_OVAL=1;
  private static final int SPINNING_OVAL=2;
  private static final int RECTANGLE=3;
  private static final int SOLID_RECT=4;
  private static final int SPINNING_RECT=5;
  private static final int LINE=6;

  // Colors
  private static final int MAX_COLORS=4;
  private static final int RED=0;
  private static final int BLUE=1;
  private static final int GREEN=2;
  private static final int YELLOW=3;

  // States
  private static final int DRAWING=0;
  private static final int CHANGING_POSITION=1;

//  private Dimension shapeSize;
  private int pressedX;
  private int pressedY;
  private int color=BLUE;
  private int shape=OVAL;
  private int state=CHANGING_POSITION;

  private Oval[] ovals = new Oval[20];
  private int novals=0;
  
  // constructor
  public DrawingCanvas() {
    super();
    pressedX = pressedY =-1;
  }
  
  // called when mouse button is pressed
  // (x,y) is position of mouse press
  //   ignore the event parameter
  public boolean mouseDown(Event event, int x, int y) {
    
    // (for debugging purposes?)
//    System.out.println ("mouse pressed at (" + x + ", " + y + ")");
    
    if (y<20 && x<40) {
      if (x <40) {
	if (x<20){
	  shape=(shape+1)%MAX_SHAPES;
//	  System.out.println ("Changing shape to " + shape);
	}
	else {
	  color=(color+1)%MAX_COLORS;
//	  System.out.println ("Changing color to " + color);
	}
	repaint();
      }
      return false;
    }
    pressedX = x;
    pressedY = y;
    Dimension d = new Dimension(0,0);
    novals++;
    ovals[novals-1]= new Oval(pressedX, pressedY,d);
    return false;
  }
  
  
  // called when mouse is moved without holding down any button
  public boolean mouseMove(Event event, int x, int y) {
    repaint();
    return false;
  }

  // called when mouse is moved while holding down the button
  public boolean mouseDrag(Event event, int x, int y) {
    if ((x>=40) || (y>=20)) {
      Dimension d = new Dimension(x-pressedX, y-pressedY);
      if (novals < 20) {
	ovals[novals-1] = new Oval(pressedX, pressedY, d);
	repaint();
      }
      state=DRAWING;
    }
    return false;
  }

  // called when mouse button is released
  public boolean mouseUp(Event event, int x, int y) {
    if (state==DRAWING) {
      Dimension d= new Dimension(x-pressedX, y-pressedY);
      if (novals < 20){
	ovals[novals-1]= new Oval(pressedX, pressedY,d);
	repaint();
      }
      state=CHANGING_POSITION;
    }
    return false;
  }

  public void drawShape(Graphics g, int x, int y, int color, 
                        int shape, Dimension d, int thick) 
  {
     setColor(g, color);
     
     int ulX=d.width>0 ? x : x+d.width;
     int ulY=d.height>0 ? y : y+d.height;
     int w=d.width<0 ? -d.width:d.width;
     int h=d.height<0 ? -d.height:d.height;

     switch (shape) {
       case OVAL:
       case SPINNING_OVAL:
           for (int i=-thick/2; i <= thick/2; i++) {
//      System.out.println ("drawing oval thick= " + thick +" i = "+ i + " w =" + w);
//      System.out.println ("drawing oval ulX= " + ulX +" ilY= "+ ulY);
             g.drawOval(ulX+i/2,ulY,w-i,h);
}
           break;
       case SOLID_OVAL:
           for (int i=-thick/2; i <= thick/2; i++)
             g.fillOval(ulX+i/2,ulY,w-i,h);
           break;
       case RECTANGLE:
           for (int i=-thick/2; i <= thick/2; i++)
    	       g.drawRect(ulX+i/2,ulY,w-i,h);
           break;
       case SOLID_RECT:
           for (int i=-thick/2; i <= thick/2; i++)
             g.fillRect(ulX+i/2,ulY,w-i,h);
           break;
       case LINE:
           for (int i=-thick/2; i <= thick/2; i++)
             g.drawLine(x+i/2, y , (x+d.width)-i, y+d.height);
           break;
     }
  }
  
  public void setColor(Graphics g, int color) {
    switch(color) {
    case RED:
      g.setColor(Color.red);
      break;
    case GREEN:
      g.setColor(Color.green);
      break;
    case BLUE:
      g.setColor(Color.blue);
      break;
    case YELLOW:
      g.setColor(Color.yellow);
      break;
    }
  }
  

  public void drawMenu(Graphics g) {
    Dimension d = new Dimension(20,20);

    g.clearRect(0,0,40,20);
    Dimension shape_d = new Dimension(16,16);
    drawShape(g,2,2, color,shape,shape_d,0);
    if (shape == SPINNING_OVAL) {
	shape_d.width=8;
        drawShape(g, 6, 2, color, shape, shape_d, 0);
    }
    drawShape(g,0,0,BLUE,RECTANGLE,d,0);
    drawShape(g,20,0,color,SOLID_RECT,d,0);
    drawShape(g,20,0,BLUE,RECTANGLE,d,0);
  }

  public void drawXOR(Graphics g,int x, int y, int color, int shape, 
		      Dimension d, int thick) 
  {
    g.setXORMode(getBackground());
    drawShape(g, x, y, color, shape, d, thick);
  }
  public void paint(Graphics g) {
    for (int i=0; i< novals; i++) 
      ovals[i].DrawOval(g);
//    drawMenu(g);
  }

  class Oval
  {
    private int x, y;
    private float phase;
    private Dimension d;
    private int Ccolor;
    public Oval(int _x, int _y, Dimension _d)
    {
     x = _x + _d.width/2;      // center coordenate
     y = _y + _d.height/2;     // center coordanate
     // x "radius" and y "radius"
     d = new Dimension(Math.abs(_d.width), Math.abs(_d.height));
     phase = (float)0.0;
     Ccolor=color;
    }
    
    public void DrawOval(Graphics g)
    {
      
      Dimension currd= new Dimension((int)(d.width*Math.cos(phase)), d.height);
      int currx = x-currd.width/2;
      int curry = y-currd.height/2;
      int thick = (int)Math.abs((d.width/5*Math.sin(phase)));
//      g.setXORMode(getBackground());
      drawShape(g, currx, curry, Ccolor, OVAL, currd, thick);
      phase+= 3.1416/32;
//      System.out.println ("drawing oval (" + currx + ", " + curry + " widht "+ currd.width+")");
    }
  }
}

