/**
 * A Java class that represents a Chicken. The state of the chicken is
 * its name, height and weight.
 * 
 * @author Sara Sprenkle
 */
public class Chicken {

    // ------------ INSTANCE VARIABLES -------------------

    /** the name of the chicken */
    private String name;

    /** the height of the chicken in centimeters */
    private int height;

    /** the weight of the chicken in pounds */
    private double weight;

    /**
     * Create a new Chicken object with the charactistics as specified by the
     * parameters.
     * @param name the name of the chicken
     * @param h the height of the chicken in centimeters
     * @param weight the weight of the chicken in pounds
     */
    public Chicken(String name, int h, double weight) {
        this.name = name;
        height = h;
        this.weight = weight;
    }

    //
    // ----------- GETTER METHODS ------------
    // (also Accessor methods)

    /**
     * Returns the chicken's height, in centimeters
     * 
     * @return the height of the chicken, in centimeters
     */
    public int getHeight() {
        return this.height;
    }

    /**
     * Returns the chicken's weight, in pounds
     * 
     * @return the weight of the chicken, in pounds
     */
    public double getWeight() {
        return weight;
    }

    /**
     * Returns the chicken's name
     *
     * @return the name of the chicken
     */
    public String getName() {
        return name;
    }
    
    //
    // ------------- MUTATORS -----------
    //

    /**
     * Feeds the chicken, increasing the chicken's weight and height
     */
    public void feed() {
        weight += .3;
        height += 1;
    }

    //
    // ------------- SETTERS ----------
    //

    /**
     * Sets the name of the chicken
     * 
     * @param n the name of the chicken
     */
    public void setName(String n) {
        name = n;
    }

    /**
     * Sets the height of the chicken, in cm
     * 
     * @param h the height of the chicken, in cm
     */
    public void setHeight(int h) {
        height = h;
    }

    /**
     * Sets the weight of the chicken, in pounds
     * 
     * @param w the weight of the chicken, in pounds
     */
    public void setWeight(double w) {
        weight = w;
    }

    /**
     * This method is private.  It is accessible by objects of 
     * the Chicken class but NOT by other classes.
     */
    private void privateMethod() {
        System.out.println("I am private!");
    }

    /**
     * Tests the Chicken class
     * @param args the command-line arguments
     */
    public static void main(String[] args) {
        
        // ---- Step 1: Start with some basic exercising of the 
        // class and use print statements to make sure 
        // class is working to some extent. ----
        
        // "Fred", weight: 2.0, height: 38
        int fredHeight = 38;
        Chicken chicken = new Chicken("Fred", fredHeight, 2.0);

        // Note: this will look like gibberish to us at this point
        System.out.println(chicken);

        chicken.feed();

        int newFredHeight = chicken.getHeight();
        System.out.println(chicken.getName() + " is now " + newFredHeight +
                           " cm tall.");

        chicken.feed();

        System.out.println("He's a growing boy at " + chicken.getHeight() + " cm tall.");

        // ---- Step 2: create automated tests of Chicken class ----

        String[] names = {"Rocky", "Baby Chicken"};
        double[] weights = {4.0, .8};
        int[] heights = {50, 4};
        String[] newNames = {"Rocky II", "Chicken"};

        for( int i=0; i < names.length; i++ ) {
            Chicken thisChicken = new Chicken( names[i], heights[i], weights[i] );

            if( !thisChicken.getName().equals(names[i]) ) {
                System.err.println("Problem likely in constructor setting name");
                System.err.println("\tActual: " + thisChicken.getName());
                System.err.println("\tExpected: " + names[i]);
            }

            if( thisChicken.getWeight() != weights[i] ) {
                System.err.println("\tError in getWeight for Chicken " + i );
                System.err.println("\tActual: " + thisChicken.getWeight());
                System.err.println("\tExpected: " + weights[i] );
            }

            // feed the chicken and check the state
            thisChicken.feed();
            if( thisChicken.getWeight() != weights[i] + .3 ) {
                System.err.println("Error in feed weight for Chicken " + i);
                System.err.println("\tActual: " + thisChicken.getWeight());
                System.err.println("\tExpected: " + (weights[i] + .3) );
            }

            if( thisChicken.getHeight() != heights[i] + 1 ) {
                System.err.println("Error in feed height for Chicken " + i);
                System.err.println("\tActual: " + thisChicken.getHeight());
                System.err.println("\tExpected: " + (heights[i] + 1) );
            }

            // feed the chicken again and check the state

            thisChicken.feed();

            // NOTE: this test may fail; look at the output to see why
            // We will have better ways to test later in the term.
            if( thisChicken.getWeight() != weights[i] + 2 * .3 ) {
                System.err.println("Error in second feed weight for Chicken " + i);
                System.err.println("Actual: " + thisChicken.getWeight());
                System.err.println("Expected: " + (weights[i] + 2 * .3 ));
            }

            if( thisChicken.getHeight() != heights[i] + 2 * 1 ) {
                System.err.println("Error in second feed height for Chicken " + i);
                System.err.println("Actual: " + thisChicken.getHeight());
                System.err.println("Expected: " + (heights[i] + 2 * 1 ));
            }
            
            thisChicken.setName(newNames[i]);
            
            if( !thisChicken.getName().equals(newNames[i]) ) {
                System.err.println("Problem likely in setName");
                System.err.println("\tActual: " + thisChicken.getName());
                System.err.println("\tExpected: " + newNames[i]);
            }
        }

    }
}
