
/**
 * Contains information about a person's name.
 * @author Khong Lovan
 * @author Elias Vafiadis
 * @author Anthony Nakaar
 * @author Wanlin Liu
 * version 1.0 of October, 1999
 */

public class Name {
    
    //+--------+----------------------------------------------------------
    //| Fields |
    //+--------+

    /* First name.*/
    String firstName;
    
    /* Last name. */
    String lastName;

    /* Middle name. */
    String middleName;

    /* Suffix.*/
    String suffix;

    //+--------------+--------------------------------------------------------
    //| Constructors |
    //+--------------+

    /**
     * Create a new instance of class Name with the product of the toString
     * method of the Name class.
     * @exception if the string is not convertible.
     */
    public Name(String fromToString) 
        throws Exception{
        // Get the first name.
        // Step 1, get the index of the first comma.
        int comma = fromToString.indexOf(",");
        // Step 2, if the index is invalid, throw an exception.
        if (comma == -1) {
            throw new Exception("Invalid");
        }// if
        // If the index is valid, get the part of the string from the beginning
        // to the first comma. That will be the first name.
        else {
            this.firstName = fromToString.substring(0, comma);
        }// else
        // Get the middle name.
        // Step 1, cut the first name off the string.        
        String str = fromToString.substring(comma+1);
        //step 2, get the index of the first comma.
        comma = str.indexOf(",");
        // Step 3, if the index is invalid, throw an exception.
        if (comma == -1) {
            throw new Exception("Invalid");
        }// if
        // If the index is valid, get the part of the string from the beginning
        // to the first comma. That will be the middle name.
        else {
            this.middleName = str.substring(0, comma);
        }// else
        //Get the last name.
        // Step 1, cut the middle name off the string.
        str = str.substring(comma+1);
        // Step 2, get the index of the first comma.
        comma = str.indexOf(",");
        // Step 3, if the index is invalid, throw an exception.
        if (comma == -1) {
            throw new Exception("Invalid");
        }// if
        // If the index is valid, get the part of the string from the beginngin
        // to the first comma. That will be the last name.
        else {
            this.lastName = str.substring(0, comma);
        }// else
        //Finally, get the suffix.
        try{
            this.suffix = str.substring(comma+1);
        }// try
        catch(StringIndexOutOfBoundsException e) {
        }// catch
    }//Name(String)

    /**
     * Purpose: create a new instance of class Name.
     * Parameter: two strings, last name and first name.
     * Pre: none.
     * Post: the new object has the given last name as the value of lastName
     * and the given first name as the value of firstName.
     * Return: none.
     * throws no exceptions.
     */
    public Name(String firstN, String lastN) {
        firstName = firstN;
        lastName = lastN;
        middleName = "";
        suffix = "";
    }
    
    /** A constructor that takes firstname, middle name, and the last name*/
    public Name(String firstN, String middleN, String lastN) {
        firstName = firstN;
        middleName = middleN;
        lastName = lastN;
        suffix = "";
    }
    
    /** A constructor taking 4 parameters, first anme, middle name,
     * last name and the suffix. */
    public Name(String firstN, String middleN, String lastN, String suf) {
        firstName = firstN;
        middleName = middleN;
        lastName = lastN;
        suffix = suf;
    }

    //+------------+---------------------------------------------------------
    //| Extractors |
    //+------------+

    /**
     * Purpose: get the value of firstName
     * Paramter: none
     * Pre: none.
     * Post: the value of firstName is not changed.
     * Return: the value of the firstName, a string.
     * throws no exceptions
     */      
    public String getFirstName() {
        return this.firstName;
    }//getFirstName()
    
     /**
     * Purpose: get the value of middleName
     * Paramter: none
     * Pre: middleName has been initialized.
     * Post: the value of middleName is not changed.
     * Return: the value of the middleName, a string.
     * @exception nameException
     * if middleName is not initialized.
     */    
    public String getMiddleName()
        throws Exception{
        if(this.middleName != "") {
            return this.middleName;
        }// if
        else {
            throw new Exception("Middle Name not found");
        }// else
    }//getMiddleName()
    
    
    /**
     * Purpose: get the value of lastName
     * Paramter: none
     * Pre: none.
     * Post: the value of lastName is not changed.
     * Return: the value of the lastName, a string.
     * throws no exceptions
     */ 
    public String getLastName() {
        return this.lastName;
    }//getLastName()
    
     
    /**
     * Purpose: get the value of Suffix.
     * Paramter: none
     * Pre: Suffix has been initialized.
     * Post: the value of Suffix is not changed.
     * Return: the value of the Suffix, a string.
     * @exception nameException
     * if Suffix is not initialized.
     */   
    public String getSuffix() 
        throws Exception {
        if(this.suffix != "") {
            return this.suffix;
        }// if
        else {
            throw new Exception("Suffix not Found");
        }// else
    }//getSuffix()
    
    //+-----------+--------------------------------------------------------
    //| Modifiers |
    //+-----------+
    
    
    /**
     * Purpose: change the value of firstName
     * Paramter: the new first name, a string.
     * Pre: none.
     * Post: the value of firstName is  changed into the new value.
     * Return: none
     * throws no exceptions.
     */ 
    public void setFirstName(String firstN) {
        this.firstName = firstN;
    }//setFirstName()
    
    /**
     * Purpose: change the value of middleName
     * Paramter: the new middle name, a string.
     * Pre: none.
     * Post: the value of middleName is  changed into the new value.
     * Return: none
     * throws no exceptions.
     */
    public void setMiddleName(String middleN) {
        this.middleName = middleN;
    }//setMiddleName()

     /**
     * Purpose: change the value of lastName
     * Paramter: the new last name, a string.
     * Pre: none.
     * Post: the value of lastName is  changed into the new value.
     * Return: none
     * throws no exceptions.
     */
    public void setLastName(String lastN) {
        this.lastName = lastN;
    }//setLastName()
    
    /**
     * Purpose: change the value of Suffix.
     * Paramter: the new suffix, a string.
     * Pre: none.
     * Post: the value of suffix is  changed into the new value.
     * Return: none
     * throws no exceptions.
     */
    public void setSuffix(String newSuffix) {
        this.suffix = newSuffix;
    }//setSuffix()
    
    //+--------------+--------------------------------------------------
    //| Capabilities |
    //+--------------+
    /** 
     * Purpose: convert the contents of the object to a displayable string.
     * Paramter: none.
     * Pre: all the fields of the objects are initialized.
     * Post: no value is changed.
     * Return: a string containing all values of fields of this object.
     * Throws no exceptions.
     */
    public String toString() {
        return firstName + "," + middleName + "," + lastName + "," + suffix;    
    }//toString()

    /**
     * Testig.
     */
    public static void main(String[] args) {
        Name liu = new Name("Wanlin", "Liu");
        SimpleOutput out = new SimpleOutput();
        out.println(liu.toString());
        // Add in a middle name.
        liu.setMiddleName("Diana");
        out.println(liu.toString());
        //Build a new object.
        try{
            Name tang = new Name(liu.toString());
            out.println("The new object Tang is: " + tang.toString());
            Name chong = new Name("Tang", "Tony", "Chongzhi","Jr");
            out.println("Chong is: " + chong.toString());
            chong = new Name(chong.toString());
            out.println("Chong is: " + chong.toString());
        }
        catch(Exception e) {
        }
       
    }// main(String[])
}

