#!/usr/bin/perl

$input = "monthlycalendar_input.tex"; # required input data file name

#-------------------------------------------------------- help message : begin
sub helpMessage {
print STDERR <<EOD;
monthlycalendar.pl : 2012/3/9(y/m/d), N.Tajima
Function:
  This perl script writes to stdout a Latex source for monthly calendar.
Example of usage:
  In order to create a latex source file "test.tex"
  to produce a five page calendar
    whose page 1 is for year=2012, month=11(November)
    and   page 5 is for year=2013, month= 3(March),
  type in the command line as,
      ./monthlycalendar.pl 2012 11 2013 3 > test.tex
Required input file:
  ./${input}
EOD
exit(0);
}
#-------------------------------------------------------- help message : end

#------------------------------------------------------- argument loop : begin
if($#ARGV >= 0) {
  if($ARGV[0] eq "-h"||$ARGV[0] eq "--help"){ &helpMessage; }
}
if($#ARGV != 3){&helpMessage;}
foreach (@ARGV){
  unless(/^\d+$/){&helpMessage;}
}
$yearBegin  = $ARGV[0];
$monthBegin = $ARGV[1];
$yearEnd    = $ARGV[2];
$monthEnd   = $ARGV[3];
&printBeginEnd;
unless($yearBegin > 0 && $yeayBegin <= $yearEnd && $yearEnd < $yearBegin+100
&& $monthBegin >=1 && $monthBegin <= 12 && $monthEnd >=1 && $monthEnd <= 12
&& ($yearBegin < $yearEnd || $monthBegin <= $monthEnd)){
   printf STDERR "Specified input seems probably a mistake.\n";
   printf STDERR "'./monthlycalendar.pl -h' for help message\n"
}
#------------------------------------------------------- argument loop : end

#--------------------------------------- main stream of the procedures : begin
@dow=qw(Цќ Зю Ва Пх Ьк Жт Хк);
unless(-f $input){die "input data file ${input} is not found.\n";}
&printPart(1);
$y = $yearBegin;
$m = $monthBegin;
while(1){
  if ($y*12+$m > $yearEnd*12+$monthEnd){last;}
  $yearString=sprintf "%04d",$y;
  $monthString=sprintf "%d",$m;
  printf STDERR "year $yearString , month $monthString\n";
  &printPart(2);
  for ( $d = 1 ; $d <= 31 ; $d ++ ) {
    $w = &dayOfTheWeek($y,$m,$d);
    if ( $w >= 0 ) {printf "\\dom{%d}{%s}\n", $d, $dow[$w];}
  }
  &printPart(4);
  $m++;
  if($m > 12){$m=1; $y = $y + 1;}
}
&printPart(5);
exit 0;
#--------------------------------------- main stream of the procedures : end

#------------------------------------------------------------------ subroutine
sub printBeginEnd {
  printf STDERR "from year %d , month %d \n",$yearBegin,$monthBegin;
  printf STDERR "to   year %d , month %d \n",$yearEnd,$monthEnd;
}

#------------------------------------------------------------------ subroutine
sub printPart{
  my $partToPrint=$_[0];
  open(FI_printPart,$input) or die "Failed to open input data file ${input}\n";
  my $part=1;
  while(my $b=<FI_printPart>){
    if($b=~/^[\s%]*!NEXT PART![\s%]*$/){$part++;next;}
    if($part==$partToPrint){
      $b=~s/!YEAR!/${yearString}/g;
      $b=~s/!MONTH!/${monthString}/g;
      print $b;
    }
  }
  close FI_printPart;
}

#------------------------------------------------------------------ subroutine
sub dayOfTheWeek {
  my( $y , $m , $d ) = @_ ;

  if ( $m < 1 || $m > 12 || $d < 1 || $d > 31 ) { return -1 ; }
  if ( $m == 2 ) {
    if ( ( $y % 4 == 0 && $y % 100 != 0 ) || ( $y % 400 == 0 ) ) {
	if ( $d > 29 ) {return -1 ; }
    }
    elsif ( $d > 28 ) {return -1 ; }
  }
  elsif ( $m == 4 || $m == 6 || $m == 9 || $m == 11 ) {
    if ( $d > 30 ){ return -1 ; }
  }

  if ( $m <= 2 ) { $y -- ; $m += 12 ; }
  return int( $y + int( $y / 4 ) - int( $y / 100 ) + int( $y / 400 )
      + int( ( 13 * $m + 8 ) / 5 ) + $d ) % 7 ;
}

#------------------------------------------------------------------------------
