/**
 * Repesent a high score, such as in an arcade game.
 * Includes the player's name and their score (which must be
 * positive).  Once a HighScore object is created, the player's
 * name cannot be changed.
 *
 * @author Zach Tomaszewski
 */
public class HighScore {

  // These are the instance variables.  They are defined in the class, but
  // outside of any method.  Every HighScore object created will have its
  // own copy of these.  They are private in accordance with the principles
  // of encapsulation: no other class should be able to access or change
  // these directly.
  //
  private String name;
  private int score;


  /**
   * Constructs a HighScore with the given name and score.  If the given
   * score is < 0, it will be treated as 0.
   */
  public HighScore(String name, int score) {
    //
    // This is a constructor.  Note how it has 1) no return type and 2) the
    // same name as the class.
    //
    // Constructor are useful to:
    // 1) Make it faster/more convenient to build an object
    // 2) Enforce rules about the newly constructed object
    // 3) Provide default values for instance variables
    // This particular constructor is doing only job 1 and 2 (specifically,
    // score must be >= 0).
    //
    // I am copying the values from the constructor parameters into the
    // instance variables.  However, note that my parameters and instance
    // variables have the same names!  Therefore, I must use this. as a
    // prefix to refer to the instance variables.  This is always a good
    // practice to follow, even when there is not a name conflict.
    //
    this.name = name;
    this.setScore(score);
    //
    // Rather than repeat the code in setScore here, I'll just call the
    // method.
    //
  }

  /**
   * Constructs a new HighScore with the given name and a score of 0.
   */
  public HighScore(String n) {
    //
    // You can overload the construtor to provide more than one way to create
    // the object. This version of the constructor just means the user of the
    // HighScore class does not always have to provide the score when building
    // a new object.  This is just a convenience for the user of this class.
    // It is also an example of job 3 of a constructor, as mentioned above:
    // providing default values.  Here I'm providing 0 as the default score if
    // one is not given.
    //
    // It is possible to call one constructor from another.  Here, I am calling
    // the constructor defined above to do the actual work of initializing
    // the object.
    //
    this(n, 0);
  }


  // The next two method are accessors ("getters").  They let another class
  // get the name and score value stored in a particular HighScore object.

  public String getName() {
    return this.name;
  }

  public int getScore() {
    return this.score;
  }

  // The next method is a mutator ("setter").  Because I did not provide a
  // mutator method for name, it is impossible to change it once the object
  // has been created.  This control is an example/benefit of encapsulation.

  /**
   * Changes this HighScore's score to the given value.  If this value is
   * less than 0, it is treated as 0.
   */
  public void setScore(int s) {
    //
    // Here, I enforce the rules that any score value must be >= 0.
    // This sort of control/security is only possible because of
    // encapsulation.  If the class that uses a HighScore object instead
    // had direct access to the score instance variable, it would be able
    // to set it to any int value.
    //
    if (s < 0) {
      this.score = 0;
    }else {
      this.score = s;
    }
  }


  /**
   * Returns this HighScore's name and score separated by a tab.
   */
  public String toString() {
    //
    // This method just makes it easier to print out a HighScore.
    // It doesn't print directly to the screen so that the class that uses
    // this one can decide how to display the String: print it to the screen,
    // put it in a GUI pop-up window, print it to a file, etc.
    //
    return this.name + "\t" + this.score;
  }

}
