/* 
   Algoritmos e Estruturas de Dados II - 2004
   date.c
   Versão 0.9; 4/3/2004
*/

#include <stdio.h>

typedef struct {
  int day;
  int month;
  int year;
} date;

void printday(date d)
{
  printf("%d/%d/%d",d.day,d.month,d.year);
}

int before (date d, date e)
{
  /*  if (d.year < e.year) return 1;
  if (d.month < e.month) return 1;
  if (d.day < e.day) return 1;
  return 0;
  */
  if (daynumber(d) < daynumber (e)) return 1;
  return 0;
}

int daysinMonth (date d)
{
  switch (d.month)
    {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
      return 31;
    case 4: case 6: case 9: case 11:
      return 30;
    case 2: 
      if (((d.year % 4 == 0) && (d.year % 100 !=0)) || (d.year % 400 == 0))
	return 29;
      else
	return 28;
    }
}

int valid_day (date d)
{
  if ((((d.month < 1) || (d.month > 12)) 
       || (d.day < 1)) || (d.day > daysinMonth(d))) 
    return 0;
  else
    return 1;
}
 
date mais_um (date d)
{ 
  date a;
  if (d.day < daysinMonth(d)) 
    { 
      a.day = d.day + 1; 
      a.month = d.month;
      a.year = d.year;
    }
  else /* d.day = daysinMonth */
    if (d.month < 12)
      { 
	a.day = 1;
	a.month = d.month + 1;
	a.year = d.year;
      }
    else /* d.day = 31, d.month = 12 */
      { 
	a.day = 1;
	a.month = 1;
	a.year = d.year + 1;
      }
  return a;
}

long int daynumber (date d)
{
  long int dn;
  dn = 0;
  int year_red = d.year - 1600;
  //  dn = dn + (365 * (d.year - 1));
  dn = dn + (365 * (year_red - 1));
  dn = dn + ((year_red - 1) / 4);
  dn = dn - ((year_red - 1) / 100);
  dn = dn + ((year_red - 1) / 400);
  switch (d.month)
    {
    case 12: dn = dn + 30;
    case 11: dn = dn + 31;
    case 10: dn = dn + 30;
    case 9: dn = dn + 31;
    case 8: dn = dn + 31;
    case 7: dn = dn + 30;
    case 6: dn = dn + 31;
    case 5: dn = dn + 30;
    case 4: dn = dn + 31;
    case 3: 
      if (((d.year % 4 == 0) && (d.year % 100 !=0)) || (d.year % 400 == 0)) 
	dn = dn + 29;
      else
	dn = dn + 28;
    case 2: dn = dn + 31;
    case 1: dn = dn + d.day;
    };
  return dn;
}
  

void weekday (date d)
{
  switch (daynumber(d) % 7)
    {
    case 0: { printf("domingo"); break; }
    case 1: { printf("segunda feira"); break; }
    case 2: { printf("terça feira"); break; }
    case 3: { printf("quarta feira"); break; }
    case 4: { printf("quinta feira"); break; }
    case 5: { printf("sexta feira"); break; }
    case 6: { printf("sábado"); break; }
    };
}
  

int main ()
{
  date ontem = {3,3,2004};
  date hoje;
  hoje.day = 4;
  hoje.month = 3;
  hoje.year = 2004;
  printf("Hoje é o dia ");
  printday(hoje);
  printf(".\n");

  date in;
  int dd, mm, yy;
  do
  {
    printf("Introduza o dia: ");
    scanf("%d", &dd);
    in.day = dd;
    printf("Introduza o mês: ");
    scanf("%d", &mm);
    in.month = mm;
    printf("Introduza o ano: ");
    scanf("%d", &yy);
    in.year = yy;
    if (valid_day(in) == 0)
      printf("Data errada!\n");
  } while (valid_day(in) == 0);

  if (before(in,hoje))
    { printday(in); printf(" < \"hoje\".\n"); }
  else if (before(hoje,in))
    { printday(in); printf(" > \"hoje\".\n"); }
  else     
    { printday(in); printf(" = \"hoje\".\n"); }

  printf("O proximo dia é ");
  printday(mais_um(in));
  printf(".\n");

  printf("O \"número\" do dia é : %d.\n",daynumber(in));

  printf("O dia ");
  printday(in);
  printf(" é ");
  weekday(in);
  printf(".\n");
}

