/******************************************************
  FILE: "Thing.java"

  Simple  Game
  
  Thing Class

	@author K.Becker
	@version November 2002
	Simple  Game
 <pre> 
  This is an abstract class.

  All classes derived from this must:

  .... know about a window (uses one) IT'S GIVEN IN THE CONSTRUCTOR

  - have an origin (x,y),
  - have a status (alive/dead)
  - have an orientation:
      indicates which direction the Thing is headed
      can be: N, NW, W, SW, S, SE, E, NE
  - have a size
  - have a radius

  - can tell their location (origin)
  - can tell their status
  - can tell their orientation (which way they're headed
  - can tell their size
  - can tell their radius

  - can be moved
  - can be drawn, 
           erased 
  - can explode

</pre>
*****************************************************/
public abstract class Thing
{
  /** the Window where stuff gets displayed  */
  protected easyCurses display;                   
  /** current origin of shape, X */
  protected int x;           
  /** current origin of shape, Y */
  protected int y;           
  /** 3 = alive; 0 = dead;  */
  protected int   status = GameVal.ALIVE;           
  /** N, NW, W, SW, S, SE, E, NE  */
  protected int   orientation = GameVal.N;    
  /** across, total  */
  protected int   size = 1;           
  /** to the middle */
  protected int   radius = 1;         
  
  // other points and values important to specific things
  // will be defined "locally"
  
  /** make a new Thing
   * the work done in the constructors is left to the
   *   derived classes
   */
  public Thing(easyCurses D){display = D;}
  /** for temporary things 
   */
  public Thing( easyCurses D, int xx, int yy ){ 
	        x = xx; y = yy; display = D;}
  
  // copy a Thing?? - left to the derived class
  // Standard Access Functions
  public  int   X()      { return x; }
  public  int   Y()      { return y; }
  public  int   Status() { return status; }
  public  int   Orient() { return orientation; }
  public  int   Size()   { return size; }
  public  int   Radius() { return radius; }
  
  /** move object to new location */
  /** move to specified point - should override */
  public void move(int x, int y) {} 

  /** move to the next spot for this thing */  
  public abstract void move ();    
  
  /** draw the thing in the given window
   * no params - uses global window
   */
  public abstract void draw();
  
  /** erase the thing from the given window
   * uses global window
   */
  public abstract void erase();
  
  /** make the thing explode
   * uses global window
   */
  public void die() {}       
  
  // Internal Support Routines
  // NEXT values based on origin of this Thing and dimensions of WINDOW
  //     wraps around within the window
  /** get the next X value going right
      // GET NEXT X-value moving EAST
      //
      // Function Type:  INTERNAL: ACCESS
      //
      // Preconditions:  First useable columns and row are 1
      //
      // Postconditions: na
      //  
      // @return        next X (with wrap around specific to Thing)              
  */
  protected int nextX(){   
    if (x+1 >= display.maxX()-radius)
      return radius;
    else
      return x+1;
  } // end nextX
  /** get the next Y value going down
      // GET NEXT Y-value moving SOUTH
      //
      // Function Type:  INTERNAL: ACCESS
      //
      // Preconditions:  First useable columns and row are 1
      //
      // Postconditions: na
      //  
      // @return        next Y (with wrap around specific to Thing)      
  */
  protected int nextY() {  
    if (y+1 >= display.maxY()-radius)
      return radius;
    else
      return y+1;
  } // end nextY
  
  /** get the previous X value going left           
      // GET PREV X-value moving WEST
      //
      // Function Type:  INTERNAL: ACCESS
      //
      // Preconditions: First useable columns and row are 1
      //
      // Postconditions: na
      //  
      // @return        prev X (with wrap around specific to Thing)              
  */
  protected int prevX()  {
    if (x-1 <= radius+1)
      return display.maxX()-radius;
    else
      return x-1;
  } // end prevX
  
  /** get the previous Y value going up
      // GET PREV Y-value moving NORTH
      //
      // Function Type:  INTERNAL: ACCESS
      //
      // Preconditions:  First useable columns and row are 1
      //
      // Postconditions: na
      //  
      // @return:        prev Y (with wrap around specific to Thing)      
  */
  protected int prevY()  {
    if (y-1 <= radius)
      return display.maxY()-radius;
    else
      return y-1;
  } // end prevY
  
}
// end of Thing.java

