/**
 * Represents a Farm (poorly).  
 * Primarly used to demonstrate pass by value for object variables
 *
 * @author CSCI2100
 */
public class Farm {

    private String name;
    
    private Chicken favoriteChicken;

    public Farm(String name) {
        this.name = name;
    }
    
    /** 
     * Sets the favorite chicken of the farm
     * @param c the new favorite chicken
     */
    public void setFavoriteChicken(Chicken c) {
    	this.favoriteChicken = c;	
    }
    
    /** 
     * Sets the favorite chicken of the farm to a copy of the passed 
     * in Chicken.
     * @param c the new favorite chicken
     */
    public void setFavoriteChickenClone(Chicken c) {
    	this.favoriteChicken = c.clone();	
    }
        
    /**
     * c copies the value of the variable passed into the method
     * (i.e., the memory location of the Chicken)
     * so the Chicken object that is referenced by c will be
     * changed after this method returns.
     */
    public void feedFavoriteChicken() {
        favoriteChicken.setWeight( favoriteChicken.getWeight() + .5 );
    }
    
    /**
     * c copies the value of the variable passed into the method
     * (i.e., the memory location of the Chicken)
     * so the Chicken object that is referenced by c will be
     * changed after this method returns.
     */
    public void feedFavoriteChickenNew(Chicken c) {
    	favoriteChicken = new Chicken(c.getName(), 
                        c.getHeight(), c.getWeight() );
        favoriteChicken.setWeight( favoriteChicken.getWeight() + .5); 
    }

    /**
     * c copies the value of the variable passed into the method
     * (i.e., the memory location of the Chicken)
     * so the Chicken object that is referenced by c will be
     * changed after this method returns.
     */
    public static void feedChicken(Chicken c) {
        c.setWeight( c.getWeight() + .5 );
    }
    
    /**
     * c copies the value of the variable passed into the method.
     * When c is then assigned to a _new_ Chicken object, c now refers to 
     * a new address.  The original variable passed in does not change,
     * so calling mutators on the new Chicken object do not affect the
     * original Chicken object passed in.
     */
    public static void feedChickenNew(Chicken c) {
        c = new Chicken(c.getName(), 
                        c.getHeight(), c.getWeight() );
        c.setWeight( c.getWeight() + .5);
    }

    public static void main(String[] args) {
        Farm farm = new Farm("OldMac");
        Chicken sal = new Chicken("Sallie Mae", 45, 5.0);
        System.out.println("Sal's original weight: " + sal.getWeight());
        farm.setFavoriteChicken(sal);
        
        System.out.println("Passing object variables with static methods:");
        
        // static variations of methods: 
        feedChicken(sal);
        // weight of Sal will be higher.
        System.out.println("Sal's weight after feedChicken(sal): " + sal.getWeight());
        
        feedChickenNew(sal);
        // sal is not affected -- same weight
		System.out.println("Sal's weight after feedChickenNew(sal): " + sal.getWeight());

        
        // More variations ...
        
        System.out.println("\nNow with instance methods...");
        
        farm.feedFavoriteChicken();
        // sal is referring to the same variable as farm's favorite chicken,
        // so sal's weight is changed.
		System.out.println("Sal's weight after feedFavoriteChicken(): " + sal.getWeight());

		farm.setFavoriteChickenClone(sal);
		farm.feedFavoriteChicken();
		// sal's weight is unchanged
		System.out.println("Sal's weight after feedFavoriteChicken(): " + sal.getWeight());

        
        farm.feedFavoriteChickenNew(sal);
        // sal's weight is unchanged
        System.out.println("Sal's weight after feedFavoriteChickenNew(sal): " + sal.getWeight());
       
    }

}