/*
 * Queue - the queue of pipe pieces
 *
 * by Adam Doppelt
 * http://www.cs.brown.edu/people/amd/
 */
import java.awt.*;

public class Queue extends MirrorCanvas {
    final static int SIZE = 6;
    final static int PIXELS_X = (Piece.SIZE + 1) + 1;    
    final static int PIXELS_Y = SIZE * (Piece.SIZE + 1) + 1;

    final static int ARROW_WIDTH = 13;
    final static int ARROW_BUFFER = 5;
    final static int ARROW_HEAD_X = 3;
    final static int ARROW_HEAD_Y = 10;
    
    final static int MESSAGE_HEIGHT = 20;
    final static Color MESSAGE_FOREGROUND = Color.white;    
    final static Color MESSAGE_BACKGROUND = Color.black;
    final static String MESSAGE = "Pieces";

    int first_;
    Piece pieces_[];

    public Queue(Container container) {
        super(PIXELS_X + ARROW_WIDTH, PIXELS_Y + MESSAGE_HEIGHT);
        container.add("East", this);
	pieces_ = new Piece[SIZE];
    }

    public void paint (Graphics g) {
	if (offscreen_ == null) {
	    super.paint(g);
	    offscreen_.setColor(Color.black);
	    offscreen_.fillRect(PIXELS_X, MESSAGE_HEIGHT, ARROW_WIDTH, PIXELS_Y);
	    offscreen_.setColor(Color.yellow);	
	    offscreen_.fillRect(PIXELS_X + ARROW_WIDTH / 2,
				MESSAGE_HEIGHT + ARROW_BUFFER,
				2, PIXELS_Y - 2 * ARROW_BUFFER);

	    int eX = PIXELS_X + ARROW_WIDTH / 2;
	    int eY = MESSAGE_HEIGHT + PIXELS_Y - ARROW_BUFFER;

	    int x[] = new int[4];
	    int y[] = new int[4];	

	    x[0] = eX; y[0] = eY;
	    x[1] = eX - ARROW_HEAD_X; y[1] = eY - ARROW_HEAD_Y;
	    x[2] = eX + ARROW_HEAD_X + 2; y[2] = y[1];
	    x[3] = eX + 1; y[3] = eY;	
	    offscreen_.fillPolygon(x, y, 4);

	    Clear();
	}
	else
	    super.paint(g);
    }

    public void Clear() {
        offscreen_.setColor(Board.BACKGROUND);
        offscreen_.fillRect(0, MESSAGE_HEIGHT, PIXELS_X, PIXELS_Y);

	SetMessage(MESSAGE);
	
        offscreen_.setColor(Board.LINES);      
        pieces_ = new Piece[SIZE];
	
	offscreen_.drawLine(0, MESSAGE_HEIGHT,
			    PIXELS_X + ARROW_WIDTH, MESSAGE_HEIGHT);
        for(int loop = 1; loop < SIZE; ++loop) {
	    int y = loop * (Piece.SIZE + 1) + MESSAGE_HEIGHT;
            offscreen_.drawLine(0, y, PIXELS_X - 1, y);
	}
	offscreen_.drawLine(0, MESSAGE_HEIGHT, 0, MESSAGE_HEIGHT + PIXELS_Y);
	Flip();
    }
    
    public void SetMessage(String message) {
	Font font = new Font("TimesRoman", Font.PLAIN, 14);

	offscreen_.setFont(font);
	FontMetrics metrics = getFontMetrics(font);
	int x = (int)((size().width - metrics.stringWidth(message)) / 2.0);
	int y = (int)((MESSAGE_HEIGHT + metrics.getMaxDescent()) / 2.0);
	offscreen_.setColor(MESSAGE_BACKGROUND);
	offscreen_.fillRect(0, 0, PIXELS_X + ARROW_WIDTH, MESSAGE_HEIGHT);
	offscreen_.setColor(MESSAGE_FOREGROUND);
	offscreen_.drawString(message, x, y + 3);
	Flip();
    }

    public void ResetQueue() {
	first_ = SIZE - 1;
	for (int loop = 0; loop < SIZE; ++loop) {
	    int y = loop * (Piece.SIZE + 1) + MESSAGE_HEIGHT + 1;
	    pieces_[loop] = GetRandomPiece();
	    pieces_[loop].StampAt(offscreen_, 1, y);
	}
	Flip();
    }

    public Piece GetNextPiece() {
	Piece toReturn = pieces_[first_];
	pieces_[first_] = GetRandomPiece();
	first_ = (first_ - 1 + SIZE) % SIZE;
	for (int loop = 0; loop < SIZE; ++loop) {
	    pieces_[loop].StampAt(
		offscreen_, 1,
		PIXELS_Y - ((((first_ - loop + SIZE) % SIZE) + 1) *
			    (Piece.SIZE + 1)) + MESSAGE_HEIGHT);
	}
	Flip();
	return toReturn;
    }

    private Piece GetRandomPiece() {
        int kind = (int)(Math.random() * 7);
	switch (kind) {
	case 0: return new WEPiece();
	case 1: return new NSPiece();	    
	case 2: return new NSEWPiece();
	case 3: return new NWPiece();
	case 4: return new NEPiece();
	case 5: return new SEPiece();	    	    	    
	case 6: return new SWPiece();	    	    	    
	}
	return null;
    }
}
