import java.util.*;
/** a student at a university */
public class Student {

  /** The student name. */
  private String name;
  
  /** The student number. */
  private String studentNumber;

  /** The current academic year of study. */
  private int yearOfStudy;

  /** The university that the student attends. */
  private University school;

  /** The books that the student currently owns
   *   stored in a "#" -delimited list. */
  private String booksOwned;

  /** The cumulative costs of books while attending school. */
  private double bookCosts;

  /** The constant used to separate book entries in book lists */
  private static final String DELIMITOR = "#";
  
  /** 
   * Create a new student using the student name, 
   * student number, year of study, and the University
   * which the student attends.
   * @param nme The name of the student.
   * @param nbr The student number.
   * @param yr The current year of study for the student.
   * @param univ The University that the student attends.
   */
  public Student(String nme, 
                 String nbr,
                 int yr,
                 University univ) {
    this.name = nme;
    this.studentNumber = nbr;
    this.yearOfStudy = yr;
    this.school = univ;
    this.booksOwned = "";
    this.bookCosts = 0.0;
  }

  /**
   * Change the school for the student to the new university.
   * @param newSchool The University that the student is now attending.
   */
  public void changeSchools(University newSchool) {
    this.school = newSchool;
  }
  
  /** 
   * The student has moved forward a year and the yearOfStudy is 
   * incremented .  This happens only up to year four.  The year 
   * of study must not be incremented past four since this is the
   * last year taught at the universities.
   */
  public void changeYear() {
    if (this.yearOfStudy  < 4) {
      this.yearOfStudy++;
    }
  }
  
  /** 
   * Buy the books for the academic year.  In order to 
   * conserve money, the student first sells books 
   * that she doesn't require for the year, back
   * to the book store, and reduces her costs
   * by the amount that they make.  She then buys the
   * books she still needs from the bookstore which 
   * is usually the most expensive.
   * @return The list of books that are still needed.
   */
  public String buyBooks() {

    // first sell whatever books you can
    this.sellBooks();

    // now remove the books already owned from the books needed.
    String needed = 
      BookReference.removeBooks 
      (this.booksOwned, 
       this.school.getBookLists().getBookList(yearOfStudy)); 
    String stillneed = null;
    
    // now buy all the books still needed one at a time
    StringTokenizer books = new StringTokenizer(needed, DELIMITOR);
    while (books.hasMoreTokens() ) {
      String book = (String) books.nextToken();
      double cost = this.school.getBookStore().sellBook(book);
      if (cost == 0.0) { // book was not available and is still needed.
        if (stillneed == null) {
          stillneed = book;
        } else {
          stillneed += DELIMITOR + book;
        }
      } else { // add it to your books and your costs
        if ( booksOwned == null ) {
          booksOwned = book;
        } else {
          booksOwned += DELIMITOR + book;
        }
        this.bookCosts += cost; 
      }
    }
    return stillneed;
  }
  
  /** 
   * Sell all books not required for the current academic
   * year, to the used book store, if they will accept them.
   * If the book is no longer on any book lists, the bookstore
   * will not purchase it. Update the costs to show the money saved.  
   * Update the books owned to reflect any books no longer owned.
    */
  public void sellBooks() {

    // sell a book only if it is not on the booklist for the current year.
    String booksForSale = BookReference.removeBooks
      (this.school.getBookLists().getBookList(yearOfStudy), this.booksOwned); 

    // after you've removed the books for sale, determine what is remaining
    this.booksOwned =  BookReference.removeBooks(booksForSale, this.booksOwned);

    // now sell the books - one at a time.
    StringTokenizer sellBook = new StringTokenizer(booksForSale, DELIMITOR);
    while (sellBook.hasMoreTokens() ) {
      String book = sellBook.nextToken();
      double money = this.school.getBookStore().buyBook(book);
      if (money > 0.0) { //book was sold for some money
        this.bookCosts -= money; // reduce costs by the money gained.
      } else { // used bookstore would not buy the book 
        if (this.booksOwned == null) {
          this.booksOwned = book;
        } else {
          this.booksOwned += DELIMITOR + book;
        }
      }
    }
  }

  /**
   * Get the cumulative costs for books.
   * @return The book costs.
   */
  public double getBookCosts() {
    return this.bookCosts;
  }

  /** 
   * Return a list of books currently in the student's possession.
   * Each book on the list must be delimited by a "\n"
   * carriage return.
   * @return The list of books currently in the student's possession.
   */
  public String getBooks() {
    String bookList = "";
    StringTokenizer books = new StringTokenizer(this.booksOwned, DELIMITOR);
    while (books.hasMoreTokens()) {
      bookList +=  books.nextToken() + "\n";
    }
    return bookList;   
  }
}

