//File: DrawingObjectList.java
//Uses: FlipBook.java

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.applet.*;
import FlipBook;

public class DrawingObjectList{

//Data Structures

private int [] [] dol;
private FlipBook fb;
private Graphics g;
public int curWidth=0, curHeight=0, curFrames=0;
public int curFrame = 0;

private static final int DOL_InitialSize = 100;
private static final int DOL_SetColor = 1;
private static final int DOL_DrawLine = 2;
private static final int DOL_DrawOval = 3;
private static final int DOL_FillOval = 4;
private static final int DOL_DrawArc  = 5;
private static final int DOL_FillArc  = 6;
private static final int DOL_DrawRect = 7;
private static final int DOL_FillRect = 8;



// Constructor
public DrawingObjectList( Graphics g_real, 
                        int width, int height, 
                        Applet a, int frames) {
  int i;
  
  fb = new FlipBook(g_real, width ,height, a, 1);
  dol = new int[frames][DOL_InitialSize];
  for (i=0; i<frames; i++) {
    dol[i][0] = 0;
  }
  curWidth = width;
  curHeight = height;
  curFrames = frames;
}

//Add an object to a frame

private void addDO(int[] obj, int fr) {
  int i, j;

  if ( dol[fr][0] + obj.length > dol[fr].length -1 ) {
    int old [];
    
    j = dol[fr].length;
    old = dol[fr];
    dol[fr] = new int[2*j];
    for (i=0; i <= old[0]; i++) {
      dol[fr][i] = old[i];
    }
  }
  
  j = dol[fr][0];
  for (i = 0; i < obj.length; i ++ ) {
    dol[fr][++j] = obj[i];
  }
  dol[fr][0] = j;
  
}

// Set a frame

public void setFrame( int frame ) {
  curFrame = frame;
}

// Set a color in the current frame
public void setColor( Color c ) {
  int [] cobj;
  cobj = new int [5];
  cobj[0] = DOL_SetColor;
  cobj[1] = c.getRed();
  cobj[2] = c.getGreen();
  cobj[3] = c.getBlue();
  /* cobj[4] = c.getAlpha(); */
  addDO(cobj,curFrame);
}

// Set a color in a particular frame
// and update the current frame to that frame
public void setColor( Color c, int frame ) {
  setFrame(frame);
  setColor( c);
}

// Set a color in a range of frames
// and update the current frame to the last frame
public void setColor( Color c, int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    setColor( c);
  }
}

// Draw a line in the current frame
public void drawLine( int x1, int y1, int x2, int y2 ) {
  int [] lobj;
  lobj = new int [5];
  lobj[0] = DOL_DrawLine;
  lobj[1] = x1;
  lobj[2] = y1;
  lobj[3] = x2;
  lobj[4] = y2;
  addDO(lobj,curFrame);
}

// Draw a line in a particular frame
// and update the current frame to that frame
public void drawLine( int x1, int y1, int x2, int y2,
                      int frame ) {
  setFrame(frame);
  drawLine(x1, y1, x2, y2);
}

// Draw a line in a range of frames
// and update the current frame to the last frame
public void drawLine( int x1, int y1, int x2, int y2, 
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    drawLine(x1, y1, x2, y2);
  }
}

// Draw an oval in the current frame
public void drawOval( int x, int y, int xw, int yw ) {
  int [] oobj;
  oobj = new int [5];
  oobj[0] = DOL_DrawOval;
  oobj[1] = x;
  oobj[2] = y;
  oobj[3] = xw;
  oobj[4] = yw;
  addDO(oobj,curFrame);
}

// Draw an oval in a particular frame
// and update the current frame to that frame
public void drawOval( int x, int y, int xw, int yw, 
                      int frame ) {
  setFrame(frame);
  drawOval(x, y, xw, yw);
}

// Draw an oval in a range of frames
// and update the current frame to the last frame
public void drawOval( int x, int y, int xw, int yw, 
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    drawOval(x, y, xw, yw);
  }
}

// Fill an oval in the current frame
public void fillOval( int x, int y, int xw, int yw ) {
  int [] oobj;
  oobj = new int [5];
  oobj[0] = DOL_FillOval;
  oobj[1] = x;
  oobj[2] = y;
  oobj[3] = xw;
  oobj[4] = yw;
  addDO(oobj,curFrame);
}

// Fill an oval in a particular frame
// and update the current frame to that frame
public void fillOval( int x, int y, int xw, int yw,
                      int frame ) {
  setFrame(frame);
  fillOval(x, y, xw, yw);
}

// Fill an oval in a range of frames
// and update the current frame to the last frame
public void fillOval( int x, int y, int xw, int yw, 
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    fillOval(x, y, xw, yw);
  }
}


// Draw an arc in the current frame
public void drawArc( int x, int y, int xw, int yw,
                     int alo, int deg ) {
  int [] aobj;
  aobj = new int [7];
  aobj[0] = DOL_DrawArc;
  aobj[1] = x;
  aobj[2] = y;
  aobj[3] = xw;
  aobj[4] = yw;
  aobj[5] = alo;
  aobj[6] = deg;
  addDO(aobj,curFrame);
}

// Draw an arc in a particular frame
// and update the current frame to that frame
public void drawArc( int x, int y, int xw, int yw, 
                     int alo, int deg, int frame ) {
  setFrame(frame);
  drawArc(x, y, xw, yw, alo, deg);
}

// Draw an arc in a range of frames
// and update the current frame to the last frame
public void drawArc( int x, int y, int xw, int yw, 
                      int alo, int deg,  
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <= framehi; i++) {
    setFrame( i);
    drawArc(x, y, xw, yw, alo, deg);
  }
}


// Fill an arc in the current frame
public void fillArc( int x, int y, int xw, int yw,
                     int alo, int deg ) {
  int [] aobj;
  aobj = new int [7];
  aobj[0] = DOL_FillArc;
  aobj[1] = x;
  aobj[2] = y;
  aobj[3] = xw;
  aobj[4] = yw;
  aobj[5] = alo;
  aobj[6] = deg;
  addDO(aobj,curFrame);
}

// Fill an arc in a particular frame
// and update the current frame to that frame
public void fillArc( int x, int y, int xw, int yw, 
                     int alo, int deg, int frame ) {
  setFrame(frame);
  fillArc(x, y, xw, yw, alo, deg);
}

// Fill an arc in a range of frames
// and update the current frame to the last frame
public void fillArc( int x, int y, int xw, int yw, 
                      int alo, int deg,  
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <= framehi; i++) {
    setFrame( i);
    fillArc(x, y, xw, yw, alo, deg);
  }
}

// Draw a rectangle in the current frame
public void drawRect( int x, int y, int xw, int yw ) {
  int [] robj;
  robj = new int [5];
  robj[0] = DOL_DrawRect;
  robj[1] = x;
  robj[2] = y;
  robj[3] = xw;
  robj[4] = yw;
  addDO(robj,curFrame);
}

// Draw a rectangle in a particular frame
// and update the current frame to that frame
public void drawRect( int x, int y, int xw, int yw,
                      int frame ) {
  setFrame(frame);
  drawRect(x, y, xw, yw);
}

// Draw a rectangle in a range of frames
// and update the current frame to the last frame
public void drawRect( int x, int y, int xw, int yw, 
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    drawRect(x, y, xw, yw);
  }
}


// Fill a rectangle in the current frame
public void fillRect( int x, int y, int xw, int yw ) {
  int [] robj;
  robj = new int [5];
  robj[0] = DOL_FillRect;
  robj[1] = x;
  robj[2] = y;
  robj[3] = xw;
  robj[4] = yw;
  addDO(robj,curFrame);
}

// Fill a rectangle in a particular frame
// and update the current frame to that frame
public void fillRect( int x, int y, int xw, int yw,
                      int frame ) {
  setFrame(frame);
  fillRect(x, y, xw, yw);
}

// Fill a rectangle in a range of frames
// and update the current frame to the last frame
public void fillRect( int x, int y, int xw, int yw, 
                      int framelo, int framehi ) {
  int i;
  for (i = framelo; i <=framehi; i++) {
    setFrame( i);
    fillRect(x, y, xw, yw);
  }
}


// Put out the buffered image
public void ShowPage(ImageObserver observer, int frame) {
  int i=1;
  g = fb.g[0];
  g.setColor(Color.white);
  g.fillRect(0,0,curWidth-1,curHeight-1);
  while (i <= dol[frame][0] ) {
    switch (dol[frame][i]) {

      case DOL_SetColor:
        g.setColor(new Color(dol[frame][i+1],
                             dol[frame][i+2],
                             dol[frame][i+3] 
                         /* ,dol[frame][i+4] */));
        i += 5;        
        break;

      case DOL_DrawLine:
        g.drawLine(dol[frame][i+1], dol[frame][i+2],
                   dol[frame][i+3], dol[frame][i+4]);
        i += 5;        
        break;


      case DOL_DrawOval:
        g.drawOval(dol[frame][i+1], dol[frame][i+2],
                   dol[frame][i+3], dol[frame][i+4]);
        i += 5;        
        break;

      case DOL_FillOval:
        g.fillOval(dol[frame][i+1], dol[frame][i+2],
                   dol[frame][i+3], dol[frame][i+4]);
        i += 5;        
        break;


      case DOL_DrawArc:
        g.drawArc(dol[frame][i+1], dol[frame][i+2],
                  dol[frame][i+3], dol[frame][i+4],
                  dol[frame][i+5], dol[frame][i+6]);
        i += 7;        
        break;

      case DOL_FillArc:
        g.fillArc(dol[frame][i+1], dol[frame][i+2],
                  dol[frame][i+3], dol[frame][i+4],
                  dol[frame][i+5], dol[frame][i+6]);
        i += 7;        
        break;

      case DOL_DrawRect:
        g.drawRect(dol[frame][i+1], dol[frame][i+2],
                   dol[frame][i+3], dol[frame][i+4]);
        i += 5;        
        break;

      case DOL_FillRect:
        g.fillRect(dol[frame][i+1], dol[frame][i+2],
                   dol[frame][i+3], dol[frame][i+4]);
        i += 5;        
        break;



    }
  }

  fb.ShowPage(observer, 0);
}

}
