/**
 * Models a small, safe, blob-like entity that grows when you feed it.
 * Fun for the whole family!  Now comes in cool designer colors.
 *
 * This class demonstrates instance variables, constructors, instance methods,
 * and encapsulation.  By encapsulation, I mean that all a SafePetBlob's
 * instance variables are private, and so they can only be affected through
 * public methods.  Through these methods and what changes they allow, I can
 * then enforce the following SafePetBlob behavior:
 * <ul>
 * <li> All new SafePetBlobs will have values for name, size, and color.
 * <li> A SafePetBlob may be renamed after creation.
 * <li> A SafePetBlob's size may only be affected through feeding or secreting
 *      mucus.  If a SafePetBlob's size ever drops to 0, it is considered dead
 *      and feeding it after that will do nothing.
 * <li> A SafePetBlob's color cannot be changed once a SafePetBlob is created.
 * </ul>
 *
 * @author Zach Tomaszewski
 * @version 17 Mar 2009
 */
public class SafePetBlob {

  //Instance variables: every PetBlob instance gets its own copy of these
  //However, because they are private now, no other class can access them
  private String name;
  private int size;
  private String color;


  //constructors

  /**
   * Creates a new SafePetBlob with the given name, size, and color.
   *
   * Any size (in cubic centimeters?) of less than 1 will be treated as 1.
   */
  public SafePetBlob(String name, int size, String color) {
    //Since we used the same name for the parameters as for the instance
    //variables, we MUST use this. here to differentiate the two
    this.name = name;
    if (size < 1) {
      this.size = 1;
    }else {
      this.size = size;
    }
    this.color = color;
  }

  /**
   * Creates a new SafePetBlob with the given name, size of 1, and purple color.
   */
  public SafePetBlob(String name) {
    //we can actually reuse the constructor above to do the initializing work
    this(name, 1, "purple");
  }

  /*
   * Note: no more default constructor
   */


  //Instance methods: accessors and mutators.
  //These methods just check or explicitly set a single blob value or state.

  /**
   * Returns this blob's color.
   * This cannot be changed after the blob has been created.
   */
  public String getColor() {
    return this.color;
  }

  /**
   * Returns this blob's current name.
   */
  public String getName() {
    return this.name;
  }

  /**
   * Returns this blob's current size.
   */
  public int getSize() {
    //A blob's size can actually reach negative numbers if it is overfed.
    //In that case, we should still return 0.
    if (this.size < 0) {
      return 0;
    }else {
      return this.size;
    }
  }

  /**
   * Whether or not this blob is currently dead.
   * A blob dies if its size ever drops below 1.
   */
  public boolean isDead() {
    return (this.size < 1);
  }

  /**
   * Sets this blob's name to be the given value (n).
   */
  public void setName(String n) {
    this.name = n;
  }


  //other instance (non-static) methods

  /**
   * Feeding a SafePetBlob causes it to grow in size by the amount it is fed.
   * Feeding it 0 or less food has no effect at all on its size.  This method
   * does nothing if this blob is has died.
   */
  public void feed(int amountOfFood) {
    if (amountOfFood < 1) {
      //Since it doesn't really make sense, we don't want people shrinking
      //their blobs by giving them negative food.
      return;
    }else if (this.isDead()) {
      //This blob already shrunk and died, so feeding it now does nothing.
      return;
    }else {
      this.size = this.size + amountOfFood;
    }
  }

  /**
   * Feeds this SafePetBlob a small snack of a single unit of food, causing it
   * to increase in size by 1.
   */
  public void feed() {
    //This is an example of method overloading: two methods with the same name.
    //Again, we can reuse the other form of the method to do the work if we want
    this.feed(1);
  }

  /**
   * SafePetBlobs, like slugs, often leave behind a trail of mucus.
   * The production of this mucus can be rather exhausting for them, however,
   * causing them to decrease in size by 1 each time they do it.  If a blob's
   * size ever drops to 0, it will die.  Once a blob is dead, calling this
   * method has no effect.
   */
  public void secreteMucus() {
    if (!this.isDead()) {
      this.size -= 1;
    }
  }

  /**
   * Returns a String that represents the state of this SafePetBlob.
   */
  public String toString() {
     //Returning a String, rather than printing it out directly, means that
     //the class that creates/uses SafePetBlobs can use this method in a wider
     //variety of contexts.  It can choose to print the returned string to
     //System.out, display it in a GUI window, write it to a file, etc.

    String status = '"' + this.name + "\", a ";
    if (this.isDead()) {
      status += "tiny dead ";
    }
    status += this.color + " PetBlob";
    if (!this.isDead()) {
      status += " of size " + this.size;
    }
    return status;
  }

}
