import java.util.StringTokenizer;

/**
 * The <code>Passport</code> class is a simplified representation of a real passport.
 * It contains information about which countries the owner of the passport has visited, and
 * for how long.<P>
 * 
 * This class should have THREE instance variables (you must <B>not</B> add any other
 * instance variables):<P>
 * <ul>
 * <li>the name of the passport owner (as a <code>String</code>).<P>
 * 
 * <li> the serial number of the passport (as an <code>int</code>).<P>
 * 
 * <li>the countries visited by  the owner of the passport (as a <code>String</code>).<BR>
 * <BR>
 * The <code>String</code> has zero or more items stored
 * in this form (there is <B>one</B> space after the comma):<BR>
 * <BR>
 * <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; countryName, duration</code>
 * <P>
 * where <I>countryName</I> is the name of the country visited by the passport owner, and <I>duration</I> 
 * is an integer (starting from 0) that indicates how many days the passport owner spent in that country.
 * <P>
 * Each item is separated by a semi-colon followed by one space. There should <B>not</B> be a 
 * semi-colon and space at the beginning or end of the <code>String</code>. Here is an example:
 * <P>
 * <code>"Canada, 175; Germany, 1; Russia, 25; Germany, 10"</code>
 * <P>
 * If the passport owner has not visited any countries, then the <code>String</code> is empty ("").
 * </ul>
 */
public class Passport {
  
  /** The name of the passport owner. */
  private String name;
  
  /** The serial number of the passport. */
  private int serialNum;
  
  /** The countries visited by the owner of the passport. */
  private String countriesVisited;
  
  /**
   * Create a new passport with name <I>n</I>, serial number <I>s</I>, and no countries visited.
   */
  public Passport(String n, int s) {
    this.name = n;
    this.serialNum = s;
    this.countriesVisited = "";
  }
  
  /**
   * Return the name of this passport's owner.
   */
  public String getName() {
    return this.name;
  }
  
  /**
   * Return the serial number of this passport.
   */
  public int getSerialNumber() {
    return this.serialNum;
  }
  
  /**
   * Return the <I>countries visited</I> section of this passport. 
   */
  public String getCountriesVisited() {
    return this.countriesVisited;
  }
  
  /**
   * Add a new entry to the <I>countries visited</I> section of this passport, using the
   * information provided by the user (in the 2 arguments); The new information
   * should be appended to the end of the current variable; <BR><BR>
   * Make sure to preserve the format of this variable, as described above; You can assume
   * that the user will not put in negative integers as the <I>duration</I>.<BR>
   * Also, there must be NO consecutive entries with the <B>same country</B>;
   * if the previous entry has the same country, then the two entries must be merged and their
   * durations added together to form one entry (e.g., <code>"Canada, 10; Canada, 10"</code> 
   * should be <code>"Canada, 20"</code>).
   */
  public void addVisited(String country, int duration) {
    if (this.countriesVisited.equals("")) {
      this.countriesVisited = country + ", " + duration;
    } else if (this.lastCountryVisited().equals(country)) {
      String cv = this.countriesVisited;
      int lastDuration = Integer.parseInt(cv.substring(cv.lastIndexOf(",") + 2));
      duration += lastDuration;
      cv = cv.substring(0, cv.lastIndexOf(" ") + 1) + duration;
      this.countriesVisited = cv;
    } else {
      this.countriesVisited += "; " + country + ", " + duration;
    }
  }
  
  /**
   * Clear the history of the <I>countries visited</I> for this passport (i.e., make it empty).
   */
  public void clear() {
    this.countriesVisited = "";
  }
  
  /**
   * Return the total number of entries in this passport's <I>countries visited</I> section; 
   * You <B>must</B> count every entry, including multiple visits to the same country.
   */
  public int numEntries() {
    StringTokenizer st = new StringTokenizer(this.countriesVisited, ";");
    
    return st.countTokens();
  }
  
  /**
   * Return the number of times this passport's owner has visited the country specified by the user.
   */
  public int numVisits(String country) {
    StringTokenizer st = new StringTokenizer(this.countriesVisited, ";, ");
    int count = 0;
    
    while (st.hasMoreTokens()) {
      if (st.nextToken().equals(country)) {
        count++;
      }
      st.nextToken(); // skip over the duration
    }
    
    return count;
  }
  
  /**
   * Return the <B>first</B> country that the owner of this passport has visited, or 
   * empty string ("") if no countries have been visited.
   */
  public String firstCountryVisited() {
    return this.countriesVisited.substring(0, Math.max(0, this.countriesVisited.indexOf(","))); 
  }
  
  /**
   * Return the <B>last</B> country that the owner of this passport has visited, or 
   * empty string ("") if no countries have been visited.
   */
  public String lastCountryVisited() {
    if (this.countriesVisited.indexOf(";") == -1) { // either "" or 1 entry
      return this.firstCountryVisited();
    } else {
      int i = this.countriesVisited.lastIndexOf(";") + 2;
      int j = this.countriesVisited.lastIndexOf(",");
      
      return this.countriesVisited.substring(i, j);
    }
  }
  
  /**
   * Return the country that the owner of this passport visited at the specified <I>index</I> -- which
   * starts at 1 (not zero!); <BR> If the user specified an <B>invalid</B> index 
   * (i.e., less than 1 or greater than the number of entries), then return the 
   * String: <B>"Invalid index!"</B> <BR>(it's important that the String be EXACTLY
   * like this, with the capital I at the beginning and ! at the end).
   * 
   */
  public String whichCountryVisited(int index) {
    if (index < 1 || index > this.numEntries()) {
      return "Invalid index!";
    } else {
      StringTokenizer st = new StringTokenizer(this.countriesVisited, ";");
      
      String c = "";
      for (int i = 0; i < index; i++) {
        c = st.nextToken().trim(); // stops when the right country is stored
      }
      
      return c.substring(0, c.indexOf(","));
    }
  }
  
  /**
   * Return the country that the owner of this passport has visited for the longest duration, or 
   * empty string ("") if no countries have been visited; <BR>
   * If there is a tie between two or more countries, return the <I>most recent</I> of these countries
   * (i.e., the first one from the <B>right</B> of the String variable).
   */
  public String longestVisitedCountry() {
    String country = "";
    int duration = 0;
    
    StringTokenizer st = new StringTokenizer(this.countriesVisited, ";, ");
    
    while (st.hasMoreTokens()) {
      String c = st.nextToken(); // get the country
      int d = Integer.parseInt(st.nextToken()); // get the duration
      
      if (d >= duration) { // check if this duration is at least as big
        country = c; 
        duration = d; // this is the new duration "to beat"
      }
    }
    
    return country;
  }
  
  /**
   * Return the total number of days that the owner of this passport spent in the specified country.
   */
  public int totalDuration(String country) {
    int duration = 0;
    
    StringTokenizer st = new StringTokenizer(this.countriesVisited, ";, ");
    
    while (st.hasMoreTokens()) {
      String c = st.nextToken(); // get the country
      int d = Integer.parseInt(st.nextToken()); // get the duration
      
      if (c.equals(country)) {
        duration += d;
      }
    }
    
    return duration;
  }
  
  /**
   * Return the information about this passport as a <code>String</code> in
   * the following format (3 lines; there <B>must</B> be one space after the first ":" on each line):<BR><BR>
   * Name: <I>n</I><BR>
   * Serial Number: <I>s</I><BR>
   * Countries Visited: <I>cv</I> <BR><BR>
   * where <I>n</I> is the name of this passport's owner, <I>s</I> is the serial
   * number of this passport, and <I>cv</I> is this passport's record of countries visited (along
   * with the durations);<BR>
   * If no countries have been visited, then the value of <I>cv</I> must be the String
   * <B>"none"</B>. 
   */
  public String toString() {
    String cv = "";
    if (this.countriesVisited.equals("")) {
      cv = "none";
    } else {
      cv = this.countriesVisited;
    }
    
    return "Name: " + this.name + '\n'
      + "Serial Number: " + this.serialNum + '\n'
      + "Countries Visited: " + cv;
  }
}