package com.oreilly.jent.people;

/**
 * In general, you may use the code in this book in your programs and 
 * documentation. You do not need to contact us for permission unless 
 * you're reproducing a significant portion of the code. For example, 
 * writing a program that uses several chunks of code from this book does 
 * not require permission. Selling or distributing a CD-ROM of examples 
 * from O'Reilly books does require permission. Answering a question by 
 * citing this book and quoting example code does not require permission. 
 * Incorporating a significant amount of example code from this book into 
 * your product's documentation does require permission.
 * 
 * We appreciate, but do not require, attribution. An attribution usually 
 * includes the title, author, publisher, and ISBN. For example: 
 * 
 *   "Java Enterprise in a Nutshell, Third Edition, 
 *    by Jim Farley and William Crawford 
 *    with Prakash Malani, John G. Norman, and Justin Gehtland. 
 *    Copyright 2006 O'Reilly Media, Inc., 0-596-10142-2."
 *  
 *  If you feel your use of code examples falls outside fair use or the 
 *  permission given above, feel free to contact us at 
 *  permissions@oreilly.com.
 */

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

/**
 * A JavaBean containing basic information about a person.
 */
public class Person implements Serializable {

    // Data members
    private String mFirstName;
    private String mLastName;
    private Collection mEmailAddresses = new ArrayList();
    private String mID = null;
    
    public Person() {
        mID = null;
        mFirstName = null;
        mLastName = null;
    }

    /** Create a person with just name information */
    public Person(String fname, String lname) {
        setFirstName(fname);
        setLastName(lname);
        mID = getFirstName() + " " + getLastName();
    }
    
    /** Create a person with name and a unique identifier. */
    public Person(String fname, String lname, String id) {
        mID = id;
        setFirstName(fname);
        setLastName(lname);
    }
    
    /** Constructor with all data defined */
    public Person(String fname, String lname, String[] eAddrs) {
        setFirstName(fname);
        setLastName(lname);
        setEmailAddresses(eAddrs);
    }

    //------
    // Accessors for the data associated with a person
    //------
    
    public String getFirstName() {
        return mFirstName;
    }

    public void setFirstName(String fName) {
        mFirstName = fName;
    }

    public String getLastName() {
        return mLastName;
    }

    public void setLastName(String lName) {
        mLastName = lName;
    }

    public String[] getEmailAddresses() {
        String[] addrs = new String[mEmailAddresses.size()];
        Object[] origAddrs = mEmailAddresses.toArray();
        for (int i = 0; i < addrs.length; i++) {
            addrs[i] = (String)origAddrs[i];
        }
        return addrs;
    }

    public void setEmailAddresses(String[] addresses) {
        mEmailAddresses = new ArrayList();
        for (int i = 0; i < addresses.length; i++) {
            mEmailAddresses.add(addresses[i]);
        }
    }
    
    public void addEmailAddress(String address) {
        // Make sure the address isn't there already
        if (!mEmailAddresses.contains(address)) {
            mEmailAddresses.add(address);
        }
    }
    /**
     * @return Returns the id for this person.
     */
    public String getId() {
        return mID;
    }
    
    public boolean equals(Object other) {
        boolean eq = false;
        if (other instanceof Person) {
            Person p2 = (Person)other;
            // If both references point to the same object, then 
            // shortcut the equality check below
            if (p2 == this) {
                return true;
            }
            // The id and name attributes should either be both null, or
            // both non-null and equal to each other
            eq = ((p2.getId() == null && this.getId() == null) ||
                  (p2.getId() != null && this.getId() != null &&
                   p2.getId().equals(this.getId())));
            eq = eq &&
                 ((p2.getFirstName() == null && this.getFirstName() == null) ||
                  (p2.getFirstName() != null && this.getFirstName() != null &&
                   p2.getFirstName().equals(this.getFirstName())));
            eq = eq && 
                 ((p2.getLastName() == null && this.getFirstName() == null) ||
                  (p2.getLastName() != null && this.getLastName() != null &&
                   p2.getLastName().equals(this.getLastName())));
            // Both should have the same number of email addresses
            eq = eq && 
                 (p2.getEmailAddresses().length ==
                  this.getEmailAddresses().length);
            if (eq) {
                // For each of our email addresses, confirm that the 
                // other has the address on its list
                // We do this by putting one set of addresses in a collection
                // and iterating through the other using contains() to check
                // for its presence on the other list. 
                // This isn't the most efficient approach, but it's easy to
                // implement.
                ArrayList tmpList = new ArrayList();
                for (int i = 0; i < p2.getEmailAddresses().length; i++) {
                    tmpList.add(p2.getEmailAddresses()[i]);
                }
                for (int i = 0; i < this.getEmailAddresses().length; i++) {
                    eq = eq && tmpList.contains(this.getEmailAddresses()[i]);
                }
            }
        }
        return eq;
    }
}
