import java.util.*;

/** An instance is an email account */
public class Acct {
    
    private String nid; // netid, obeying usual Cornell conventions
    
    /** Constructor: a new account with netid n */
    public Acct(String n) {
        nid= n;   
    }
    
    /** = this account's netid */
    public String getID() {
        return nid;
    }
    
    /** sound an alert based on message m */
    public void alert(String m) {
        System.out.println("Acct alert: " + m); // #@ for lecture purposes
    }
    
    /** some example statements to demonstrate concepts
      * from lecture 13, slide slidenum*/
    public static void testConcepts(int slidenum) {
        
        Acct a= new Acct("zy3");
        Gm g= new Gm("ac1");
        Hm h= new Hm("jp2");
        
        
        if (slidenum==2) {
            System.out.println("Slide 2: Show that Gm inherits getID()");
            System.out.println("g.getID(): " + g.getID() + "\n"); // Gm inherits getID()
        }
        else if (slidenum==3) {
            // slide 3
            a= g;
            
        }
        else if (slidenum==5) {
            
            System.out.println("Slide 5: Show that Acct alert is overridden: ");
            Vector<Acct> v= new Vector<Acct>();
            v.add( (Acct) g); // explicit cast
            v.add(null);
            v.add(h); // implicit upward cast
            
            System.out.println("v.get(0).alert(\"slide 5 test\")");
            v.get(0).alert("slide 5 test");
            
            System.out.println("v.get(2).alert(\"slide 5 test\")");
            v.get(2).alert("slide 5 test\n");
        
        }
        else if (slidenum==6) {
             
            System.out.println("Slide 6: compile problem with apparent type");
            Vector<Acct> v= new Vector<Acct>();
            v.add(g); v.add(null); v.add(h);
            
            // v.get(0).newClip("FLOOD"); // #@ Uncommenting gives compile error
            
            ((Gm) v.get(0)).newClip("FLOOD"); /// cast to get right apparent type
            
        }
        else if (slidenum == 7) {
              
            System.out.println("Slide 7: cast/fresh variable");
            a= g;
            
            // a.newClip("flood"); // #@ uncommenting gives compile error
            if (a instanceof Gm) {
                Gm newG= (Gm) a;
                newG.newClip("flood");
            }
        }
        else if (slidenum == 9) {
            System.out.println("testing equals");
            System.out.println("g.equals(g): " + g.equals(g));
            System.out.println("g.equals(a): " + g.equals(a));
            a= g; // "ac1"
            System.out.println("after a= g (note different apparent types), " +
                               "g.equals(a) is: " + g.equals(a));
            Acct acopy= new Acct(a.getID()); // duplicate a
            System.out.println("a.equals(acopy) is: " + a.equals(acopy));
        }
            
        
        
        
    }
    
    /** = Òh is an Acct with the same  values in its fields as this Acct */
    public boolean equals(Object h) {
        if (!(h instanceof Acct)) {
            return false;
        }
        
        // #@ to test the need for this, comment these lines out
         Acct a= (Acct) h; 
         return nid.equals(a.nid);
        
        // #@ uncomment and you will get compile error
        // return nid.equals(h.nid);
    }
    
}