/* SiFenLi.c, c-programming source code of exe. file for dos-prompt.
   Ask an input year, then print out the date, time of shou, wang,
   zhong qi & length of month for that year on the screen. */


#include <stdio.h>


int Leap_y(int rbyear);
int Leap_m(int rbyear, int moon);

void print_s(int rbyear, int moon);

float acd_shuo(int rbyear, int moon);
float acd_wang(int rbyear, int moon);
float acd_qi(int rbyear, int qi);

int month, zq; // number of non-leap month & zhong qi.


main()
{
  int year=1, rb_year;
  int moon; // number of new moon since beginning of ru bu year.
  int tmonth;
  char continues;

  while(year != 0)
  {
 start:
	printf("\n\nPlease Enter a year to do computation (range:85~236, 0 to exit):");
	scanf("%d", &year);

	if(year == 0)	goto end;
	if(year<85 || year>236)  {
	  printf("\nCalculation of Si Fen Li doesn't apply to your input value.");
	  printf("\nPress any key to continue.");
	  getch(continues);
	  goto start;
	}

	rb_year = (year + 9281) % 76;
	tmonth = 14 + Leap_y(rb_year);

	printf("\n   MONTH       SHUO          WANG     LENGTH    ZHONG QI ");
	printf("\n            DATE  TIME    DATE  TIME           DATE  TIME");
	printf("\n  _________________________________________________________");

	month = 11;	   zq = 0;
	for(moon = 1; moon <= tmonth; moon++)  {
	  if(moon % 8 == 0)  printf("\n");
	  print_s(rb_year, moon);
	  month ++;
	  if(month > 12)  month = 1;
	}

  printf("\n\n\tPress any key to continue.");
  getch(continues);
 end:
  }
  return 0;
}


int Leap_y(int rbyear)
{
  int isLeap=0;

  if( ( (rbyear - 1) * 235 ) % 19 >= 12)
	isLeap = 1;

  return isLeap;
}

int Leap_m(int rbyear, int month)
{
  int isLeap = 0,  completed_month;
  float acd_first, acd_last, qi_first, qi_last;

  completed_month = (rbyear - 1) * (235.0/19.0) + (month - 1);

  acd_first = (completed_month * (29.0+499.0/940.0) );
  acd_last  = ((completed_month + 1.0) * (29.0+499.0/940.0) );
  qi_first  = (int)(acd_first)/(30.0+14.0/32.0);
  qi_last   = (int)(acd_last) / (30.0+14.0/32.0);

  if(qi_first-(int)(qi_first) != 0)
	if( ((int)(qi_first) == (int)(qi_last)) || (qi_last-(int)(qi_last) == 0) )
	  isLeap = 1;

  return isLeap;
}


void print_s(int rbyear, int moon)
{
  int name_s = acd_shuo(rbyear, moon), name_w = acd_wang(rbyear, moon);
  int name_q;
  int time_s = ( acd_shuo(rbyear, moon) - (float)(name_s) ) * 24.0;
  int time_w = ( acd_wang(rbyear, moon) - (float)(name_w) ) * 24.0;
  int time_q;
  int length = (int)(acd_shuo(rbyear, moon + 1)) - name_s;

  if(Leap_m(rbyear, moon) == 0)  {    // if is not a leap month.
	zq ++;
	name_q = acd_qi(rbyear, zq);
	time_q = ( acd_qi(rbyear, zq) - (float)(name_q) ) * 24.0;
	printf("\n   %3d        1    %2d      %2d    %2d     %2d"
			, month, time_s, name_w - name_s + 1, time_w, length);
	printf("      %2d    %2d",name_q - name_s + 1, time_q);
  }  else  {
	month --;
	printf("\n   %3d(Leap)  1    %2d      %2d    %2d     %2d"
			, month, time_s, name_w - name_s + 1, time_w, length);
  }
}


float acd_shuo(int rbyear, int moon)
{
  int completed_month;

  completed_month = ((rbyear - 1) * 235 / 19) + moon - 1;
  return completed_month * (29.0+499.0/940.0);
}

float acd_wang(int rbyear, int moon)
{
  int completed_month;

  completed_month = ((rbyear - 1) * 235 / 19) + moon - 1;
  return (completed_month + 0.5) * (29.0+499.0/940.0);
}

float acd_qi(int rbyear, int qi)
{
  int completed_qi;

  completed_qi = ((rbyear - 1) * 12) + qi - 1;
  return completed_qi * (30.0+14.0/32.0);
}



