import java.util.Calendar ;
import java.util.GregorianCalendar ;
import java.util.Random ;
import javax.swing.JOptionPane ;

/**
 * The ClockDisplay class implements a hour-minute digital clock.
 * The clock may be displayed in :
 *   - in a European-style 24 hour clock : from 00:00 (midnight) to 23:59
 *     (one minute before midnight) 
 *   - or in a US-style 12 hour clock :  from 01:00 am to 12:59 am  
 *     (noon = 12:00 am), and from 01:00 pm to 12:59 pm (midnight = 12:00 pm )
 * 
 * The clock display receives "ticks" (via the timeTick method) every minute
 * and reacts by incrementing the display. This is done in the usual clock
 * fashion: the hour increments when the minutes roll over to zero.
 * 
 * @author Michael Kolling and David J. Barnes, modified Albin Morelle
 * @version 2001.05.26, modified Sept 03
 */

public class ClockDisplay {
    // Two display styles
    public static final String STYLE_EUROPEAN = "EU";
    public static final String STYLE_US = "US";
    
    private NumberDisplay hours;        
    private NumberDisplay minutes;
    private String displayStyle;
    private String displayString;
    
    private String code;    // special user code for each clock
    
    /**
     * Constructor for ClockDisplay objects. This constructor 
     * creates a new clock set at 00:00 and chooses a
     * 24-hour display style
     */
    public ClockDisplay()  {
	  this(0, 0, STYLE_EUROPEAN);
    }

    /**
     * Constructor for ClockDisplay objects. This constructor
     * creates a new clock
     * @param   hour and minute : initialization time
     * @param   style : display style ("EU" vs ""US)
     */
    public ClockDisplay(int hour, int minute, String style) {
        hours   = new NumberDisplay(24);
        minutes = new NumberDisplay(60);
        displayStyle = style;
        code = createCode();
        setTime(hour, minute);
    }

    /**
     * Constructor for ClockDisplay objects. This constructor
     * creates a new clock initialized to the current time
     * @param   style : display style ("EU" vs ""US)
     */
    public ClockDisplay(String style) {
        hours   = new NumberDisplay(24);
        minutes = new NumberDisplay(60);
        displayStyle = style;
        code = createCode();
        
        Calendar calendar = new GregorianCalendar();
        setTime(calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE)); 
    }

    /**
     * This method should get called once every minute - it makes
     * the clock display go one minute forward.
     */
    public void timeTick() {
        minutes.increment();
        if(minutes.getValue() == 0) {  // it just rolled over!
            hours.increment();
        }
        updateDisplay();    
    }

    /**
     * Set the time of the display to the specified hour and
     * minute.
     */
    public void setTime(int hour, int minute) {
        hours.setValue(hour);
        minutes.setValue(minute);
        updateDisplay();
    }
    
    /**
     * Switch the display style
     */
    public void switchDisplayStyle() {
        if (displayStyle.equals(STYLE_US)) {
            displayStyle = STYLE_EUROPEAN ;
        } else {
            displayStyle = STYLE_US ;
        }
        updateDisplay();
    }

    /**
     * Return the current time of this display
     */
    public String getTime() {
        return displayString;
    }
    
    /**
     * Update the internal string that represents the display.
     */
    private void updateDisplay() {
        int hour ;
        String hourString;
        String suffix = "";
        
        hour = hours.getValue() ;
        
        if (displayStyle.equals(STYLE_US)) {
            // case US style
            if (hour > 12) {            // range 13:00 to 23:59
                hour = hour - 12 ; 
                suffix = " pm"; 
            } else if (hour == 0) {     // range 00:00 to 00:59
                hour = 12 ;
                suffix = " pm";
            } else {                    // range 01:00 to 12:59
                suffix = " am";
            }
        }
         
        if (hour < 10) {
            hourString = "0" + hour;
        } else {
            hourString = "" + hour;
        }
        
        displayString = hourString + 
                        ":" + 
                        minutes.getDisplayValue() +
                        suffix ;
     }

    /**
     * Ask the user name and compose a string code
     * @return      the 8 character string formed by
     *      the first 3 characters of the user name
     *      + the user name length modulo 10
     *      + a 4 digit random natural integer
     */
    private String createCode() {
        Random rand = new Random();
        
        String userName = JOptionPane.showInputDialog("User name ? ");
        int userNameLength = userName.length() ;
        
        String first3Char = "" ;
        if ( userNameLength > 0 ) {
            int lastUsefulIndex = Math.min(userNameLength, 3) - 1 ;            
            first3Char = userName.substring(0,lastUsefulIndex).toUpperCase() ;
        }
        switch (userNameLength) {
            case 0 : first3Char += capitalLetter(rand.nextInt(26)) ; // add a random letter
            case 1 : first3Char += capitalLetter(rand.nextInt(26)) ; // and another
            case 2 : first3Char += capitalLetter(rand.nextInt(26)) ; // and another
        }
      
        int randInt = rand.nextInt(9999);   // at most 4 digits
        String prefix = "" ;
        if (randInt < 10)        prefix = "000" ;
        else if (randInt < 100)  prefix = "00" ;
        else if (randInt < 1000) prefix = "0" ;
        
        return  first3Char + (userNameLength % 10) + prefix + randInt ;
    }     
    
    /** 
     * Return a capital letter given its rank in the alphabet
     * (the rank must be in [0, 26])
     */
    private char capitalLetter(int rank) {
        return (char)('A' + rank) ;
    }
         
} // end class ClockDisplay
    

