/*
 * BirthdayFun.java
 *
 * Version:
 *     $Id$
 *
 * Revisions:
 *     $Log$
 *
 */

//  Import statements are placed here
import java.util.Scanner;

/**
 * BirthdayFun accepts a person's name, then numeric birth month and
 * numeric birth day, and numeric today's month and numeric today's day.  
 * It then prints a message regarding the time
 * since or until the person's birthday.
 *
 * Birthday is not accurate for leap years.  The date checker is stupid.
 *
 * @author      Cheryl A. Dugas
 *
 */

public class BirthdayFun {

    /**  
     * The main program prompts for name and birtday and today
     * and prints results regarding time to/from birthday
     *
     * @param args command line arguments (ignored)
     *
     */
	public static void main ( String args[] ) {

	    String firstName;           // person's name
	    int birthMonth = 0;         // person's birth month
	    int birthDay = 0;           // person's birth day
	    int todayMonth = 0;          // today's month
	    int todayDay = 0;            // today's day
	    int daysFromBirthday = 0;   // how long before/after birthday
	    boolean inputOk = false;    // flag for input validity

	    // need scanner (instance of class Scanner) in order to read input
	    // System.in indicates input is to come from standard input
	    Scanner scanner = new Scanner( System.in ); // used for input

	    // prompt user for first name and read it in
	    System.out.println( "What is your first name?" );
	    firstName = scanner.next();  // user types in name

	    // prompt user for a valid birth month and day
	    // If either are invalid, it will prompt for both again

	    while ( !(inputOk) ) {

	    // get birth month
	    System.out.println( "What is your birth month?" );
	    System.out.println( "(Enter a number from 1 to 12)" );
	    birthMonth = scanner.nextInt();

	    // get birth day
	    System.out.println( "What is your birth day?" );
	    System.out.println( "(Enter a number from 1 to 31)" );	    
	    birthDay = scanner.nextInt();

	    // check input - checkDate returns true or false
	    inputOk = checkDate( birthMonth, birthDay );
	    }

	    // prompt user for today's month and day
	    // If either are invalid, it will prompt for both again

	    inputOk = false;  // reset flag
	    while ( !(inputOk) ) {

	    // get this month
	    System.out.println( "What is this month?" );
	    System.out.println( "(Enter a number from 1 to 12)" );
	    todayMonth = scanner.nextInt();

	    // get this day
	    System.out.println( "What is today's date?" );
	    System.out.println( "(Enter a number from 1 to 31)" );	    
	    todayDay = scanner.nextInt();

	    // check input - checkDate returns true or false
	    inputOk = checkDate( todayMonth, todayDay );
	    }

	    // find out how many days from birthday
	    // dateDifference returns a signed integer
	    daysFromBirthday = dateDifference( birthMonth, birthDay,
					       todayMonth, todayDay);

	    // print results based on dateDifference:
	    // 0:  it's the birthday
	    // positive:  birthday is in the future
	    // negative:  birthday has already occurred

	    System.out.println();
	    System.out.println( firstName + "'s birthday is on " +
				birthMonth + "/" + birthDay );
	    System.out.println();

	    if ( daysFromBirthday == 0 ) {
		System.out.println( "HAPPY BIRTHDAY, " + firstName + "!" );
	    } else if ( daysFromBirthday < 0 ) {
		System.out.println( firstName + "'s birthday was " +
				   -daysFromBirthday + " days ago.");
		    } else {
		System.out.println( firstName + "'s birthday is in " +
				    daysFromBirthday + " days.");
	    }
	    System.out.println();

	}

    /**
     *
     * The checkDate method checks for a valid month and
     * checks for a day between 1 and 31.  It is a dumb checker!
     *
     * @param     month     input month
     * @param     day       input day
     *
     * @return    true or false answer to "is it a valid date?"
     *
     */
    public static boolean checkDate( int month, int day ) {

	// check for month between 1 and 12
	if ( (month < 0) || (month > 12) ) {
	    return false;
	}
	// check for day between 1 and 31
	if ( (day < 0) || (day > 31) ) {
	    return false;
	}
	// if both are valid, control will fall to this last return
    return true;
    }

    /**
     *
     * The dateDifference method calculates the number of days between
     * an input date (date 2) and a benchmark date (usually today).  
     * If the date has gone by, the result is negative.
     *
     * @param     month2     input month
     * @param     day2       input day
     * @param     month1     benchmark month
     * @param     day1       benchmark day
     *
     * @return    days between date and benchmark, as a signed integer
     *
     */
   public static int dateDifference( int month2, int day2, 
			       int month1, int day1 ) {
	int date2 = 0;
	int date1 = 0;

	// calculate date2
	switch ( month2 ) {
	case  1 :  date2 = day2; break;
	case  2 :  date2 = 31 + day2; break;
	case  3 :  date2 = 59 + day2; break;
	case  4 :  date2 = 90 + day2; break;
	case  5 :  date2 = 120 + day2; break;
	case  6 :  date2 = 151 + day2; break;
	case  7 :  date2 = 181 + day2; break;
	case  8 :  date2 = 212 + day2; break;
	case  9 :  date2 = 243 + day2; break;
	case 10 :  date2 = 273 + day2; break;
	case 11 :  date2 = 304 + day2; break;
	case 12 :  date2 = 334 + day2; break;
	}

	// calculate date1
	switch ( month1 ) {
	case  1 :  date1 = day1; break;
	case  2 :  date1 = 31 + day1; break;
	case  3 :  date1 = 59 + day1; break;
	case  4 :  date1 = 90 + day1; break;
	case  5 :  date1 = 120 + day1; break;
	case  6 :  date1 = 151 + day1; break;
	case  7 :  date1 = 181 + day1; break;
	case  8 :  date1 = 212 + day1; break;
	case  9 :  date1 = 243 + day1; break;
	case 10 :  date1 = 273 + day1; break;
	case 11 :  date1 = 304 + day1; break;
	case 12 :  date1 = 334 + day1; break;
	}

	// return the differnce between the dates
	return ( date2 - date1 ) ;
    }

}    // BirthdayFun

