// # CS1 u4_date2.c
// Jonas Altrock <ew20b126@technikum-wien.at>
//
// [To overview](../).
//
// [The whole source file `u4_date2.c`.](./u4_date2.c)
/* Compile with `clang -std=c99 -Wall -o u4_date2 u4_date2.c` */
/* Test with `../checkproject u4_date2` */

// Include C-libraries for input/output.
#include <stdio.h>
#include <stdlib.h>

// # Exercise 4: if/switch-Conditions
//
// Read a date in the format yyyy-mm-dd and print it in human readable form.
//
// ## Detailed exercise
// Read a date in the given format. Then print it in the format
// “day[st/nd/rd/th] of name of month, year”.
//
// You may assume that only a valid date is entered.
//
// ### Example 1
// Input:
// ```
// 2016-08-12
// ```
// Output:
// ```
// 12th of August, 2016
// ```
//
// ### Example 2
// Input:
// ```
// 2015-12-31
// ```
// Output:
// ```
// 31st of December, 2015
// ```
//
// ### Example 3
// Input:
// ```
// 2015-10-03
// ```
// Output:
// ```
// 3rd of October, 2015
// ```

// ## Global declarations
// Forward declarations of our own functions. Any function we want to call has
// to be declared before its use. If the definition for these functions is
// later in the same file, this is called a *forward declaration*.
//
// The return type `const char *` is the type of literal strings with double
// quotes in our code. These strings are stored somewhere in the read-only
// section of the binary by the compiler.
const char *day_suffix(int d);
const char *month(int m);

// ## main()
int main() {
    // Use three integer variables for year, month, day.
    int yyyy, mm, dd;
    // The `scanf` format codes can use the same constraints as `printf`, here
    // we want to read a four-digit year, a two-digit month, and a two-digit
    // day.
    scanf("%04d-%02d-%02d", &yyyy, &mm, &dd);
    // Print in the format `day[st/nd/rd/th] of name of month, year`.
    //
    // `%s` is the format code for printing a string variable.
    printf("%d%s of %s, %d\n", dd, day_suffix(dd), month(mm), yyyy);
    // Return code `0` for everything OK.
    return 0;
}

// ## day_suffix()
// We know that days in a date can only be between 1 and 31, so we only
// have to handle a few special cases for the English number suffixes.
const char *day_suffix(int d) {
    // First
    if (d == 1 || d == 21 || d == 31) return "st";
    // Second
    if (d == 2 || d == 22) return "nd";
    // Third
    if (d == 3 || d == 23) return "rd";
    // N-th
    return "th";
}

// ## month()
// Map the month number to the fixed string containing its name.
const char *month(int m) {
    if (m == 1) return "January";
    if (m == 2) return "February";
    if (m == 3) return "March";
    if (m == 4) return "April";
    if (m == 5) return "May";
    if (m == 6) return "June";
    if (m == 7) return "July";
    if (m == 8) return "August";
    if (m == 9) return "September";
    if (m == 10) return "October";
    if (m == 11) return "November";
    if (m == 12) return "December";
    return "invalid month";
}