/*
***********************************************************************
* Copyright (C) 2016 and later: Unicode, Inc. and others.
* License & terms of use: http://www.unicode.org/copyright.html#License
***********************************************************************
**********************************************************************
* Copyright (C) 1998-2012, International Business Machines Corporation
* and others.  All Rights Reserved.
**********************************************************************
*
* File date.c
*
* Modification History:
*
*   Date        Name        Description
*   06/16/99    stephen     Creation.
*******************************************************************************
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "unicode/uloc.h"
#include "unicode/udat.h"
#include "unicode/ucal.h"
#include "unicode/ustring.h"
#include "unicode/uclean.h"

#include "uprint.h"

#if UCONFIG_NO_FORMATTING

int main(int argc, char **argv)
{
  printf("%s: Sorry, UCONFIG_NO_FORMATTING was turned on (see uconfig.h). No formatting can be done. \n", argv[0]);
  return 0;
}
#else


/* Protos */
static void usage(void);

static void version(void);

static void cal(int32_t month, int32_t year,
                UBool useLongNames, UErrorCode *status);

static void get_symbols(const UDateFormat *fmt,
                        UDateFormatSymbolType type,
                        UChar *array[],
                        int32_t arrayLength,
                        int32_t lowestIndex,
                        int32_t firstIndex,
                        UErrorCode *status);

static void free_symbols(UChar *array[],
                         int32_t arrayLength);

static void get_days(const UDateFormat *fmt,
                     UChar *days [], UBool useLongNames, 
                     int32_t fdow, UErrorCode *status);

static void free_days(UChar *days[]);

static void get_months(const UDateFormat *fmt,
                       UChar *months [], UBool useLongNames,
                       UErrorCode *status);

static void free_months(UChar *months[]);

static void indent(int32_t count, FILE *f);

static void print_days(UChar *days [], FILE *f, UErrorCode *status);

static void  print_month(UCalendar *c, 
                         UChar *days [], 
                         UBool useLongNames, int32_t fdow, 
                         UErrorCode *status);

static void  print_year(UCalendar *c, 
                        UChar *days [], UChar *months [],
                        UBool useLongNames, int32_t fdow, 
                        UErrorCode *status);

/* The version of cal */
#define CAL_VERSION "1.0"

/* Number of days in a week */
#define DAY_COUNT 7

/* Number of months in a year (yes, 13) */
#define MONTH_COUNT 13

/* Separation between months in year view */
#define MARGIN_WIDTH 4

/* Size of stack buffers */
#define BUF_SIZE 64

/* Patterm string - "MMM yyyy" */
static const UChar sShortPat [] = { 0x004D, 0x004D, 0x004D, 0x0020, 
0x0079, 0x0079, 0x0079, 0x0079 };
/* Pattern string - "MMMM yyyy" */
static const UChar sLongPat [] = { 0x004D, 0x004D, 0x004D, 0x004D, 0x0020, 
0x0079, 0x0079, 0x0079, 0x0079 };


int
main(int argc,
     char **argv)
{
    int printUsage = 0;
    int printVersion = 0;
    UBool useLongNames = 0;
    int optInd = 1;
    char *arg;
    int32_t month = -1, year = -1;
    UErrorCode status = U_ZERO_ERROR;
    
    
    /* parse the options */
    for(optInd = 1; optInd < argc; ++optInd) {
        arg = argv[optInd];
        
        /* version info */
        if(strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0) {
            printVersion = 1;
        }
        /* usage info */
        else if(strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
            printUsage = 1;
        }
        /* use long day names */
        else if(strcmp(arg, "-l") == 0 || strcmp(arg, "--long") == 0) {
            useLongNames = 1;
        }
        /* POSIX.1 says all arguments after -- are not options */
        else if(strcmp(arg, "--") == 0) {
            /* skip the -- */
            ++optInd;
            break;
        }
        /* unrecognized option */
        else if(strncmp(arg, "-", strlen("-")) == 0) {
            printf("cal: invalid option -- %s\n", arg+1);
            printUsage = 1;
        }
        /* done with options, display cal */
        else {
            break;
        }
    }
    
    /* Get the month and year to display, if specified */
    if(optInd != argc) {
        
        /* Month and year specified */
        if(argc - optInd == 2) {
            sscanf(argv[optInd], "%d", (int*)&month);
            sscanf(argv[optInd + 1], "%d", (int*)&year);
            
            /* Make sure the month value is legal */
            if(month < 0 || month > 12) {
                printf("icucal: Bad value for month -- %d\n", (int)month);
                
                /* Display usage */
                printUsage = 1;
            }
            
            /* Adjust because months are 0-based */
            --month;
        }
        /* Only year specified */
        else {
            sscanf(argv[optInd], "%d", (int*)&year);
        }
    }
    
    /* print usage info */
    if(printUsage) {
        usage();
        return 0;
    }
    
    /* print version info */
    if(printVersion) {
        version();
        return 0;
    }
    
    /* print the cal */
    cal(month, year, useLongNames, &status);
    
    /* ICU cleanup.  Deallocate any memory ICU may be holding.  */
    u_cleanup();

    return (U_FAILURE(status) ? 1 : 0);
}

/* Usage information */
static void
usage()
{  
    puts("Usage: icucal [OPTIONS] [[MONTH] YEAR]");
    puts("");
    puts("Options:");
    puts("  -h, --help        Print this message and exit.");
    puts("  -v, --version     Print the version number of cal and exit.");
    puts("  -l, --long        Use long names.");
    puts("");
    puts("Arguments (optional):");
    puts("  MONTH             An integer (1-12) indicating the month to display");
    puts("  YEAR              An integer indicating the year to display");
    puts("");
    puts("For an interesting calendar, look at October 1582");
}

/* Version information */
static void
version()
{
    printf("icucal version %s (ICU version %s), created by Stephen F. Booth.\n", 
        CAL_VERSION, U_ICU_VERSION); 
    puts(U_COPYRIGHT_STRING);
}

static void
cal(int32_t month,
    int32_t year,
    UBool useLongNames,
    UErrorCode *status)
{
    UCalendar *c;
    UChar *days [DAY_COUNT];
    UChar *months [MONTH_COUNT];
    int32_t fdow;
    
    if(U_FAILURE(*status)) return;
    
    /* Create a new calendar */
    c = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
    
    /* Determine if we are printing a calendar for one month or for a year */
    
    /* Print an entire year */
    if(month == -1 && year != -1) {
        
        /* Set the year */
        ucal_set(c, UCAL_YEAR, year);
        
        /* Determine the first day of the week */
        fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
        
        /* Print the calendar for the year */
        print_year(c, days, months, useLongNames, fdow, status);
    }
    
    /* Print only one month */
    else {
        
        /* Set the month and the year, if specified */
        if(month != -1)
            ucal_set(c, UCAL_MONTH, month);
        if(year != -1)
            ucal_set(c, UCAL_YEAR, year);
        
        /* Determine the first day of the week */
        fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
        
        /* Print the calendar for the month */
        print_month(c, days, useLongNames, fdow, status);
    }
    
    /* Clean up */
    ucal_close(c);
}
/*
 * Get a set of DateFormat symbols of a given type.
 *
 * lowestIndex is the index of the first symbol to fetch.
 * (e.g. it will be one to fetch day names, since Sunday is
 *  day 1 *not* day 0.)
 *
 * firstIndex is the index of the symbol to place first in
 * the output array. This is used when fetching day names
 * in locales where the week doesn't start on Sunday.
 */
static void get_symbols(const UDateFormat *fmt,
                        UDateFormatSymbolType type,
                        UChar *array[],
                        int32_t arrayLength,
                        int32_t lowestIndex,
                        int32_t firstIndex,
                        UErrorCode *status)
{
    int32_t count, i;
    
    if (U_FAILURE(*status)) {
        return;
    }

    count = udat_countSymbols(fmt, type);

    if(count != arrayLength + lowestIndex) {
        return;
    }

    for(i = 0; i < arrayLength; i++) {
        int32_t idx = (i + firstIndex) % arrayLength;
        int32_t size = 1 + udat_getSymbols(fmt, type, idx + lowestIndex, NULL, 0, status);
        
        array[idx] = (UChar *) malloc(sizeof(UChar) * size);

        *status = U_ZERO_ERROR;
        udat_getSymbols(fmt, type, idx + lowestIndex, array[idx], size, status);
    }
}

/* Free the symbols allocated by get_symbols(). */
static void free_symbols(UChar *array[],
                         int32_t arrayLength)
{
    int32_t i;

    for(i = 0; i < arrayLength; i++) {
        free(array[i]);
    }
}

/* Get the day names for the specified locale, in either long or short
form.  Also, reorder the days so that they are in the proper order
for the locale (not all locales begin weeks on Sunday; in France,
weeks start on Monday) */
static void
get_days(const UDateFormat *fmt,
         UChar *days [],
         UBool useLongNames,
         int32_t fdow,
         UErrorCode *status)
{
    UDateFormatSymbolType dayType = (useLongNames ? UDAT_WEEKDAYS : UDAT_SHORT_WEEKDAYS);
    
    if(U_FAILURE(*status))
        return;
    
    /* fdow is 1-based */
    --fdow;

    get_symbols(fmt, dayType, days, DAY_COUNT, 1, fdow, status);
}

static void free_days(UChar *days[])
{
    free_symbols(days, DAY_COUNT);
}

/* Get the month names for the specified locale, in either long or
short form. */
static void
get_months(const UDateFormat *fmt,
           UChar *months [],
           UBool useLongNames,
           UErrorCode *status)
{
    UDateFormatSymbolType monthType = (useLongNames ? UDAT_MONTHS : UDAT_SHORT_MONTHS);
    
    if(U_FAILURE(*status))
        return;
    
    get_symbols(fmt, monthType, months, MONTH_COUNT - 1, 0, 0, status); /* some locales have 13 months, no idea why */
}

static void free_months(UChar *months[])
{
    free_symbols(months, MONTH_COUNT - 1);
}

/* Indent a certain number of spaces */
static void
indent(int32_t count,
       FILE *f)
{
    char c [BUF_SIZE];

    if(count <= 0)
    {
        return;
    }
    
    if(count < BUF_SIZE) {
        memset(c, (int)' ', count);
        fwrite(c, sizeof(char), count, f);
    }
    else {
        int32_t i;
        for(i = 0; i < count; ++i)
            putc(' ', f);
    }
}

/* Print the days */
static void
print_days(UChar *days [],
           FILE *f,
           UErrorCode *status)
{
    int32_t i;
    
    if(U_FAILURE(*status)) return;
    
    /* Print the day names */
    for(i = 0; i < DAY_COUNT; ++i) {
        uprint(days[i], f, status);
        putc(' ', f);
    }
}

/* Print out a calendar for c's current month */
static void
print_month(UCalendar *c, 
            UChar *days [], 
            UBool useLongNames,
            int32_t fdow,
            UErrorCode *status)
{
    int32_t width, pad, i, day;
    int32_t lens [DAY_COUNT];
    int32_t firstday, current;
    UNumberFormat *nfmt;
    UDateFormat *dfmt;
    UChar s [BUF_SIZE];
    const UChar *pat = (useLongNames ? sLongPat : sShortPat);
    int32_t len = (useLongNames ? 9 : 8);
    
    if(U_FAILURE(*status)) return;
    
    
    /* ========== Generate the header containing the month and year */
    
    /* Open a formatter with a month and year only pattern */
    dfmt = udat_open(UDAT_PATTERN,UDAT_PATTERN,NULL,NULL,0,pat, len,status);
    
    /* Format the date */
    udat_format(dfmt, ucal_getMillis(c, status), s, BUF_SIZE, 0, status);
    
    
    /* ========== Get the day names */
    get_days(dfmt, days, useLongNames, fdow, status);

    /* ========== Print the header */
    
    /* Calculate widths for justification */
    width = 6; /* 6 spaces, 1 between each day name */
    for(i = 0; i < DAY_COUNT; ++i) {
        lens[i] = u_strlen(days[i]);
        width += lens[i];
    }
    
    /* Print the header, centered among the day names */
    pad = width - u_strlen(s);
    indent(pad / 2, stdout);
    uprint(s, stdout, status);
    putc('\n', stdout);
    
    
    /* ========== Print the day names */
    
    print_days(days, stdout, status);
    putc('\n', stdout);
    
    
    /* ========== Print the calendar */
    
    /* Get the first of the month */
    ucal_set(c, UCAL_DATE, 1);
    firstday = ucal_get(c, UCAL_DAY_OF_WEEK, status);
    
    /* The day of the week for the first day of the month is based on
    1-based days of the week, which were also reordered when placed
    in the days array.  Account for this here by offsetting by the
    first day of the week for the locale, which is also 1-based. */
    firstday -= fdow;
    
    /* Open the formatter */
    nfmt = unum_open(UNUM_DECIMAL, NULL,0,NULL,NULL, status);
    
    /* Indent the correct number of spaces for the first week */
    current = firstday;
    if(current < 0)
    {
       current += 7;
    }
    for(i = 0; i < current; ++i)
        indent(lens[i] + 1, stdout);
    
    /* Finally, print out the days */
    day = ucal_get(c, UCAL_DATE, status);
    do {
        
        /* Format the current day string */
        unum_format(nfmt, day, s, BUF_SIZE, 0, status);
        
        /* Calculate the justification and indent */
        pad = lens[current] - u_strlen(s);
        indent(pad, stdout);
        
        /* Print the day number out, followed by a space */
        uprint(s, stdout, status);
        putc(' ', stdout);
        
        /* Update the current day */
        ++current;
        current %= DAY_COUNT;
        
        /* If we're at day 0 (first day of the week), insert a newline */
        if(current == 0) {
            putc('\n', stdout);
        }
        
        /* Go to the next day */
        ucal_add(c, UCAL_DATE, 1, status);
        day = ucal_get(c, UCAL_DATE, status);
        
    } while(day != 1);
    
    /* Output a trailing newline */
    putc('\n', stdout);
    
    /* Clean up */
    free_days(days);
    unum_close(nfmt);
    udat_close(dfmt);
}

/* Print out a calendar for c's current year */
static void
print_year(UCalendar *c, 
           UChar *days [], 
           UChar *months [],
           UBool useLongNames, 
           int32_t fdow, 
           UErrorCode *status)
{
    int32_t width, pad, i, j;
    int32_t lens [DAY_COUNT];
    UNumberFormat *nfmt;
    UDateFormat *dfmt;
    UChar s [BUF_SIZE];
    const UChar pat [] = { 0x0079, 0x0079, 0x0079, 0x0079 };
    int32_t len = 4;
    UCalendar  *left_cal, *right_cal;
    int32_t left_day, right_day;
    int32_t left_firstday, right_firstday, left_current, right_current;
    int32_t left_month, right_month;
    
    if(U_FAILURE(*status)) return;
    
    /* Alias */
    left_cal = c;
    
    /* ========== Generate the header containing the year (only) */
    
    /* Open a formatter with a month and year only pattern */
    dfmt = udat_open(UDAT_PATTERN,UDAT_PATTERN,NULL,NULL,0,pat, len, status);
    
    /* Format the date */
    udat_format(dfmt, ucal_getMillis(left_cal, status), s, BUF_SIZE, 0, status);
    
    /* ========== Get the month and day names */
    get_days(dfmt, days, useLongNames, fdow, status);
    get_months(dfmt, months, useLongNames, status);

    /* ========== Print the header, centered */
    
    /* Calculate widths for justification */
    width = 6; /* 6 spaces, 1 between each day name */
    for(i = 0; i < DAY_COUNT; ++i) {
        lens[i] = u_strlen(days[i]);
        width += lens[i];
    }
    
    /* width is the width for 1 calendar; we are displaying in 2 cols
    with MARGIN_WIDTH spaces between months */
    
    /* Print the header, centered among the day names */
    pad = 2 * width + MARGIN_WIDTH - u_strlen(s);
    indent(pad / 2, stdout);
    uprint(s, stdout, status);
    putc('\n', stdout);
    putc('\n', stdout);
    
    /* Generate a copy of the calendar to use */
    right_cal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
    ucal_setMillis(right_cal, ucal_getMillis(left_cal, status), status);
    
    /* Open the formatter */
    nfmt = unum_open(UNUM_DECIMAL,NULL, 0,NULL,NULL, status);
    
    /* ========== Calculate and display the months, two at a time */
    for(i = 0; i < MONTH_COUNT - 1; i += 2) {
        
        /* Print the month names for the two current months */
        pad = width - u_strlen(months[i]);
        indent(pad / 2, stdout);
        uprint(months[i], stdout, status);
        indent(pad / 2 + MARGIN_WIDTH, stdout);
        pad = width - u_strlen(months[i + 1]);
        indent(pad / 2, stdout);
        uprint(months[i + 1], stdout, status);
        putc('\n', stdout);
        
        /* Print the day names, twice  */
        print_days(days, stdout, status);
        indent(MARGIN_WIDTH, stdout);
        print_days(days, stdout, status);
        putc('\n', stdout);
        
        /* Setup the two calendars */
        ucal_set(left_cal, UCAL_MONTH, i);
        ucal_set(left_cal, UCAL_DATE, 1);
        ucal_set(right_cal, UCAL_MONTH, i + 1);
        ucal_set(right_cal, UCAL_DATE, 1);
        
        left_firstday = ucal_get(left_cal, UCAL_DAY_OF_WEEK, status);
        right_firstday = ucal_get(right_cal, UCAL_DAY_OF_WEEK, status);
        
        /* The day of the week for the first day of the month is based on
        1-based days of the week.  However, the days were reordered
        when placed in the days array.  Account for this here by
        offsetting by the first day of the week for the locale, which
        is also 1-based. */
        
        /* We need to mod by DAY_COUNT since fdow can be > firstday.  IE,
        if fdow = 2 = Monday (like in France) and the first day of the
        month is a 1 = Sunday, we want firstday to be 6, not -1 */
        left_firstday += (DAY_COUNT - fdow);
        left_firstday %= DAY_COUNT;
        
        right_firstday += (DAY_COUNT - fdow);
        right_firstday %= DAY_COUNT;
        
        left_current = left_firstday;
        right_current = right_firstday;
        
        left_day = ucal_get(left_cal, UCAL_DATE, status);
        right_day = ucal_get(right_cal, UCAL_DATE, status);
        
        left_month = ucal_get(left_cal, UCAL_MONTH, status);
        right_month = ucal_get(right_cal, UCAL_MONTH, status);
        
        /* Finally, print out the days */
        while(left_month == i || right_month == i + 1) {
            
        /* If the left month is finished printing, but the right month
        still has days to be printed, indent the width of the days
            strings and reset the left calendar's current day to 0 */
            if(left_month != i && right_month == i + 1) {
                indent(width + 1, stdout);
                left_current = 0;
            }
            
            while(left_month == i) {
                
            /* If the day is the first, indent the correct number of
                spaces for the first week */
                if(left_day == 1) {
                    for(j = 0; j < left_current; ++j)
                        indent(lens[j] + 1, stdout);
                }
                
                /* Format the current day string */
                unum_format(nfmt, left_day, s, BUF_SIZE, 0, status);
                
                /* Calculate the justification and indent */
                pad = lens[left_current] - u_strlen(s);
                indent(pad, stdout);
                
                /* Print the day number out, followed by a space */
                uprint(s, stdout, status);
                putc(' ', stdout);
                
                /* Update the current day */
                ++left_current;
                left_current %= DAY_COUNT;
                
                /* Go to the next day */
                ucal_add(left_cal, UCAL_DATE, 1, status);
                left_day = ucal_get(left_cal, UCAL_DATE, status);
                
                /* Determine the month */
                left_month = ucal_get(left_cal, UCAL_MONTH, status);
                
                /* If we're at day 0 (first day of the week), break and go to
                the next month */
                if(left_current == 0) {
                    break;
                }
            };
            
            /* If the current day isn't 0, indent to make up for missing
            days at the end of the month */
            if(left_current != 0) {
                for(j = left_current; j < DAY_COUNT; ++j)
                    indent(lens[j] + 1, stdout);
            }
            
            /* Indent between the two months */
            indent(MARGIN_WIDTH, stdout);
            
            while(right_month == i + 1) {
                
            /* If the day is the first, indent the correct number of
                spaces for the first week */
                if(right_day == 1) {
                    for(j = 0; j < right_current; ++j)
                        indent(lens[j] + 1, stdout);
                }
                
                /* Format the current day string */
                unum_format(nfmt, right_day, s, BUF_SIZE, 0, status);
                
                /* Calculate the justification and indent */
                pad = lens[right_current] - u_strlen(s);
                indent(pad, stdout);
                
                /* Print the day number out, followed by a space */
                uprint(s, stdout, status);
                putc(' ', stdout);
                
                /* Update the current day */
                ++right_current;
                right_current %= DAY_COUNT;
                
                /* Go to the next day */
                ucal_add(right_cal, UCAL_DATE, 1, status);
                right_day = ucal_get(right_cal, UCAL_DATE, status);
                
                /* Determine the month */
                right_month = ucal_get(right_cal, UCAL_MONTH, status);
                
                /* If we're at day 0 (first day of the week), break out */
                if(right_current == 0) {
                    break;
                }
                
            };
            
            /* Output a newline */
            putc('\n', stdout);
        }
        
        /* Output a trailing newline */
        putc('\n', stdout);
  }
  
  /* Clean up */
  free_months(months);
  free_days(days);
  udat_close(dfmt);
  unum_close(nfmt);
  ucal_close(right_cal);
}

#endif
