/*
 * Piece - a single piece of pipe
 *
 * by Adam Doppelt
 * http://www.cs.brown.edu/people/amd/
 */
import java.awt.*;

abstract public class Piece {
    final static int SIZE = 50;
    final static Color PIPE_COLOR = Color.black;
    final static int SLICES = 500;
    
    final static double PIPE_WIDTH = 0.2;
    final static double CENTER = 0.5;
    final static double POS_EDGE = CENTER + PIPE_WIDTH / 2;
    final static double NEG_EDGE = CENTER - PIPE_WIDTH / 2;    

    final static double FIRST_LINE  = NEG_EDGE + PIPE_WIDTH * 1.5;
    final static double CIRCLE_LINE = Math.PI * PIPE_WIDTH * 1.5;
    final static double SECOND_LINE = FIRST_LINE;
    final static double TOTAL = FIRST_LINE + CIRCLE_LINE + SECOND_LINE;
    
    final static double FIRST_PERCENT  = FIRST_LINE / TOTAL;
    final static double CIRCLE_PERCENT = CIRCLE_LINE / TOTAL;
    final static double SECOND_PERCENT = SECOND_LINE / TOTAL;    

    final static int GOOD_PIXELS_A = (int)Math.round(NEG_EDGE * (double)SIZE);
    final static int GOOD_PIXELS_B = (int)Math.round(POS_EDGE * (double)SIZE);
    
    final static int DIV_SLICES = SLICES - 1;
    
    final static int NONE = 0;
    final static int NORTH = 1;
    final static int SOUTH = 2;
    final static int EAST = 4;
    final static int WEST = 8;

    int oldDirection_;
    boolean contains_, flip_;
    PieceType type_;
    
    public Piece(PieceType type) {
	contains_ = false;
	oldDirection_ = NONE;
	type_ = type;
    }

    public void StampAt(Graphics g, int x, int y) {
        g.drawImage(type_.stamp_, x, y, null);
    }

    public boolean ContainsWater() {
	return contains_;
    }

    public void WaterEnters(Water water) {
	contains_ = true;
	oldDirection_ = water.GetDirection();
	flip_ = (oldDirection_ & type_.flipDirections_) != 0;
	water.SetDirection(Twist(oldDirection_));
    }
    
    public void AdjustWater(Water water, int slice) {
	water.SetColor(type_.red_, type_.green_, type_.blue_,
		       (double)slice / (double)DIV_SLICES);
	if (flip_)
	    slice = DIV_SLICES - slice;
	if (type_.visible_[slice]) {
	    water.SetTileOffset(type_.x1_[slice], type_.y1_[slice],
				type_.x2_[slice], type_.y2_[slice]);
	    water.SetVisible(true);	    
	}
	else
	    water.SetVisible(false);
    }

    public boolean IsDirectionLegal(int direction) {
	return (direction & type_.legalDirections_) != 0;
    }

    static int PercentPixel(double percent) {
	return (int)Math.round(SIZE * percent);
    }

    public int Twist(int direction) {
	return direction;
    }
}
