/****************************************************************************/
/* Calendario gregoriano del mes del año que se desee.                      */
/*                                                                          */
/* Jaime Suarez <mcripto@bigfoot.com> 2003                                  */
/* en http://elparaiso.mat.uned.es                                            */
/****************************************************************************/

#include <stdio.h>

#include <stdlib.h>


int diasemana(uint dia, uint mes, uint anno);
int esbisiesto(uint anno);
void escribemes(uint mes, uint anno);
void uso();

main(int argc, char *argv[])
{
	uint mes,anno,i;
	
	if (argc!=3) {uso(); return 1;}
	mes =(uint)strtoul(argv[1],NULL,10);
	anno=(uint)strtoul(argv[2],NULL,10);
	
	escribemes(mes,anno); 
	return 0;
}


void uso()
{
	printf("Uso: calen <mes> <año>\n");
	printf("Escribe el calendario del mes(1-12) y año indicado.\n");
	return;
}


/* ------------------------------------------------------------------
 * diasemana
 * Entrada: dia(1-31), mes(1-12) y año números enteros positivos
 * Salida : número del 0 al 6, 0=domingo...6=sábado correspondiente
 *         a la fecha indicada
 * Notas  : el calendario gregoriano no se impuso en muchos paises 
 *         hasta el siglo XVIII e incluso más tarde.
 * ------------------------------------------------------------------ */

int diasemana(uint d, uint m, uint y)
{
	int w,c,dia,mes,anno;

	dia=d;
	if (m<3) { anno=(y-1)%100; c=(y-1)/100; mes=m+10; }
	else { anno=y%100; c=y/100; mes=m-2; }

	w=(dia+ (int)(2.6*mes-0.2) -2*c +anno +anno/4 +c/4) %7;
	if (w<0) w+=7;
	return w;
}

/* -------------------------------------------------------------------  
  Devuelve uno si el año que recibe es bisiesto y cero en otro caso 
  --------------------------------------------------------------------*/

int esbisiesto(uint anno)
{
	if (anno%4 !=0) return 0;
	else if (anno%100 ==0 && anno%400 !=0) return 0;
	else return 1;
}

/* ------------------------------------------------------------------
 * escribemes()
 * Entrada: mes (1-12) y año, enteros sin signo
 * Salida : ---
 * Efecto : Escribe el calendario del més indicado
 * -------------------------------------------------------------------*/

void escribemes(uint mes, uint anno)
{
	char *nommes[12]={"Enero","Febrero","Marzo","Abril","Mayo","Junio",
		"Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"};
	uint ndiasmes[12]={31,28,31,30,31,30,31,31,30,31,30,31};
	uint diasmes,dsem,i;
	char titulo[20];
	
	if (mes<1 | mes>12) {printf("Error: mes entre 1 y 12.\n");return;}
	
	sprintf(titulo,"%s %u",nommes[mes-1],anno);
	for (i=0; i<(21-strlen(titulo))/2; i++) printf(" ");
	printf("%s\n",titulo);
	printf("  L  M  M  J  V  S  D\n");
	
	dsem=diasemana(1,mes,anno);
	if (dsem==0) dsem=7;
	
	diasmes=ndiasmes[mes-1];
	if (mes==2) diasmes+= esbisiesto(anno);
	
	for (i=0; i<dsem-1; i++) printf("   ");
	for (i=0; i<diasmes; i++) {
		printf(" %2d",i+1);
		if (++dsem==8) {printf("\n"); dsem=1;}
	}
	printf("\n\n");
	return;
}