/* File: cal-funcs.c
 * -----------------------------------
 * This file contains the implementations
 * of the calendar functions described in
 * calendar.h.
 */

#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
#include "calendar.h"

/*
 * Function: AddDay
 * Usage: new_week_day = AddDay(old_week_day, n) ;
 * ----------------------------------------------
 * AddDay returns the weekday of the day n days after
 * old_week_day.
 */

int AddDay(int weekday, int inc) {
   return( (weekday % 7 + inc % 7) % 7 ) ;
}

/*
 * Function: PrintOneMonth
 * Usage: PrintOneMonth(weekday, n) ;
 * -----------------------------------
 * PrintOneMonth prints the body of a one-month
 * calendar with n days starting on the given
 * weekday.  No headings are printed.
 */

void PrintOneMonth(int start, int days) {
   int i ;

   /* Indent the first line */
   for (i = 0 ; i < start ; i++) {
      printf("   ") ;
   }

   for (i = 1 ; i <= days ; i++) {
      printf("%3d", i) ;
      /* print newline at end of week */
      if ( (i + start) % 7 == 0 ) {
	 printf("\n") ;
      }
   }

   /* Print newline at end of month
     only if necessary */
   if( (i + start) % 7 != 1)  {
      printf("\n") ;
   }
}

/* 
 * Function: YearDays
 * Usage: ndays = YearDays(year) ;
 * ------------------------------
 * YearDays returns the number of days in the given year.
 */

int YearDays(int year) {
   if (IsLeapYear(year)) {
      return(366) ;
   } else {
      return(365) ;
   }
}

/*
 * Function: MonthDays
 * Usage: ndays = MonthDays(month, year);
 * --------------------------------------
 * MonthDays returns the number of days in the indicated
 * month and year.  The year is required to handle leap years.
 */
 
int MonthDays(int month, int year) {
    switch (month) {
      case 2:
        if (IsLeapYear(year)) return (29);
        return (28);
      case 4: case 6: case 9: case 11:
        return (30);
      default:
        return (31);
    }
}

/*
 * Function: MonthName
 * Usage: name = MonthName(month);
 * -------------------------------
 * MonthName converts a numeric month in the range 1-12
 * into the string name for that month.
 */

string MonthName(int month)
{
    switch (month) {
      case  1: return ("January");
      case  2: return ("February");
      case  3: return ("March");
      case  4: return ("April");
      case  5: return ("May");
      case  6: return ("June");
      case  7: return ("July");
      case  8: return ("August");
      case  9: return ("September");
      case 10: return ("October");
      case 11: return ("November");
      case 12: return ("December");
      default: return ("Illegal month");
    }
}

/*
 * Function: IsLeapYear
 * Usage: if (IsLeapYear(year)) . . .
 * ----------------------------------
 * This function returns TRUE if year is a leap year.
 */

bool IsLeapYear(int year) {
    return ( ((year % 4 == 0) && (year % 100 != 0))
             || (year % 400 == 0) );
}

