#!/usr/bin/perl
#
#
# To do - put in check for grade correction within grade correction 
#       - put in valid grade checking. no grades other than "p k b x".
#       - Not all of the error checking is in yet.
#       - Final request to change grade after last utt is graded.

#---------------------------------
# GLOBAL variables
#---------------------------------


$DEBUG=0; # When equal 1, show debug statements
$OFFLINE=0;
$QUIT=0; # when equal 1, signal to quit grading

$QSTYLE=0;
$COPY=1; # 1 : (default) copy old grades to new grades when translation is identical
         # 0 : (-nocopy command line arguemnt) force grader to grade all new translations 
         #     regardless of being identical to their respective old translations

# not used yet
@PossibleGrades = (p, k, b, u, x); 

# Type/subname of evaluation.
$GradeType = "eval";
$NumberOfGraders = 1;

# User id used for grade/score output file names
#
$UserId= (getlogin() || "unknown");

#---------------------------------
# GLOBAL utterance info variables
#---------------------------------

#---------------------------------
# Current utterance number to grade
$CurrentUtt;
$CurrentSDUCount=0;
$CurrentGradeCount=0;

#---------------------------------
# Source utterances
#

$SourceFile = 0;
@SourceUtts;
$SourceUttCount=0;

$SpeakerFile = 0;
@Speakers;
$SpeakerCount=0;
$Speaker=0;

#---------------------------------
# New versions of translations
#
    
$NewTargetFile = 0;
@NewTargetUtts;
$NewTargetUttCount=0;



#---------------------------------
#The 2 files below are set after 
# the files above have been
#retrieved from the arglist (@ARGV)
#

$NewGradeFile;
$NewScoreFile;


@NewGrades;

#---------------------------------
# Must be defined for calculating 
# scores.
#

@FinalGrades;

#---------------------------------
# Old versions of translations

$OldTargetFile = 0;
@OldTargetUtts;
$OldTargetUttCount=0;

$OldGradeFile = 0;
@OldGrades;
$OldGradeCount=0;


#---------------------------------
# Do not set temp file until after 
# we check if we are reading one in. 
# With -temp option.
# Later this will be ($NewGradeFile . "-temp")
#

$TempGradeFile = 0; 

#---------------------------------
# Files for sorting utts by grade

$BadFile = 0;
$OkFile = 0;
$PerfectFile = 0;
$UndefinedFile = 0;
$NullFile = 0;

#---------------------------------
# These are set when files are read 
# in to allow or disallow grading.
#

$CanGrade=0;
$CanRegrade=0;

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

#---------------------------------
#  Body of this program
#---------------------------------



#1--FLAGS---
# Fetch the command-line arguments

ReadFlags(); 


#2--FILES---
# Fetch the input files for grading

GetOption();

ReadFiles();


# Fetch the target input file name and set these.
$NewGradeFile =($NewTargetFile . "." . $GradeType . ".grades-" . $UserId);

if ($NumberOfGraders > 1) {
    $NewScoreFile = ($NewGradeFile . "-" . $NumberOfGraders . "aver-scores");
} else {$NewScoreFile = ($NewGradeFile . "-scores");}


#3---TEMP----
# Set this after TempGradeFile has been read in.
# check for exisiting temp grade file and copy 

$TempGradeFile = ($NewGradeFile . "-temp");


if ((-e ($TempGradeFile . ".BAK2"))  && (-e ($TempGradeFile . ".BAK1"))) {
    print ("Copying temp file Backup 2 to Backup 3.\n");
    rename (($TempGradeFile . ".BAK2"), ($TempGradeFile . ".BAK3"));
    if (-e ($TempGradeFile . ".BAK3")) {print ("Over writing Backup 3 temp file. I hope you didn't need it.\n");}

} 

if ((-e ($TempGradeFile . ".BAK1"))) {
    print ("Copying temp file Backup 1 to Backup 2.\n");
    rename (($TempGradeFile. ".BAK1"), ($TempGradeFile . ".BAK2"));
}


    print ("Copying existing temp file to Backup 1.\n");
    rename (($TempGradeFile), ($TempGradeFile . ".BAK1"));



#3--GRADES---
# Start Grading     

  $CurrentUtt = (@NewGrades + 1);

  if ($CanGrade) {
   GradingLoop ($CurrentUtt); 
  }

#5--SAVE GRADES/SCORE--
  unless ($QUIT) {
    SaveFinalGrades ();
  }
   

#6---DONE----
  print ("\nGrading Session Over! \n Good Bye!\n");


sub GetOption {
  my($opt, $outfile, $line, @fields, $name);
  
  $opt = 0;

  while ($opt != 1 && $opt != 2) {
    print "\nHow would like to grade?\n";
    print "   1. Binary Choice \n";
    print "   2. Single Choice \n\n\n";
    print " Please enter your choice? (1/2): ";  
    $opt = <STDIN>;
  }

  $QSTYLE = $opt;
}

 
#---------------------------------
#         SUBROUTINES
#        defined below
#---------------------------------

sub SaveFinalGrades {
    my($input);
    my($tempgrade);
    print ("You have finished grading all of the utterances in the file.\n");
    until ($input eq "q") {
          print ("You can still change your grades.\n"); 
          print ("Enter a number (from 1 to $SourceUttCount) or \"q\" to quit/save: ");
          $input = <STDIN>;
          chop($input);
          
          if (($input > 0) && ($input <= $SourceUttCount)) {
	      $tempgrade = PromptGrade($input, 1);
              if (!($tempgrade eq "")) {
	       ProcessGrade($input, $tempgrade, 1);
	       WriteGradeFile ($TempGradeFile, @NewGrades);}
              else {print ("Invalid grade entry!\n");}
	   



          } elsif ($input eq "q") {
	      print ("\nSaving final grades and calculating scores!\n");
	  } else { 
	      print ("Invalid entry!\n");
	  }
      }


         
         @FinalGrades = @NewGrades;
         WriteGradeFile ($NewGradeFile, @FinalGrades);


	if (@FinalGrades) {
	    GetFinalScores ($NewScoreFile, @FinalGrades);
            print ("\nYour grades have been saved in: \"$NewGradeFile\"\n");
            print ("Your scores have been saved in: \"$NewScoreFile\"\n");
         } else {
	   print ("No grades to process, no score files created!\n");
       }

}


#---------------------------------
# Prompt for and return grade

sub PromptGrade {
  my($opt, $i, $count, $j);
  my($utt, $correct) = @_;
  my($index) = ($utt - 1); 
  my($inputgrade);
  my($frag, $num, @fields, $xxx);

  $opt = 0;
  print("\n------------------------------------------------------------\n\nCurrent: $utt\n");
  if ($Speaker) {
    # This is just some remanant left - god knows what goes here. - untouched
    print ("\nSource Text:  $Speakers[$index]: $SourceUtts[$index]\n");
  } else {
    $frag   = $SourceUtts[$index];
    # $num    = CountSDUsInUtt ($SourceUtts[$index]);
    @fields = split(/\#/,$frag);
    $i      = 1;
    print "Source Text:  \n";
    while(@fields-1) {
      $xxx = shift(@fields);
	if ($i == 1 && $QSTYLE == 1) {
	 print "         >>  Segment $i: $xxx\n";
	} else {
            print "             Segment $i: $xxx\n";}
      $i++;
    }
    $i = 0;
    # print ("\nSource Text:  $SourceUtts[$index]\n"); 
  }
  
  print("\nTarget Translation:  $NewTargetUtts[$index] \n");
  if ($CanRegrade) {
    print("\nOld Translation:  $OldTargetUtts[$index] \n");
    print("Old Translation Grade(s):  $OldGrades[$index] \n");
  }
  if ($correct && $QSTYLE == 2) {
    print ("Currently Graded as: ",  $NewGrades[$index] );
  }
  if ($DEBUG) {
    $temp = ($NewTargetUtts[$index] eq $OldTargetUtts[$index]);
    print ("EQUAL TRANSL? $temp\n");
  }
  
  $CurrentSDUCount = CountSDUsInUtt ($SourceUtts[$index]);
  if ($CurrentSDUCount > 0) {
    if ($QSTYLE == 2) {
      print ("\n Enter $CurrentSDUCount New Grade(s): ");
    }
  }
  else {
    print ("\n (No # found) Enter 1 or more New Grades: ");
  }
  
  #print STDERR ($CurrentSDUCount);
  # Check value of $correct : correction mode deactivates identical translation copying temporarily.
  # Also, when $COPY is 0 (due to -nocopy flag in command line arguments), 
  # the program will deactivate identical translation copying throughout the session.
  
  my($tempgrade) = "";
  if (!$correct && $COPY && ($NewTargetUtts[$index] eq $OldTargetUtts[$index])) {
    $inputgrade = $OldGrades[$index];
    print ("$OldGrades[$index] \n *** ID-translations -- Copying Old Grades ***\n");
  } else {
    if ($QSTYLE == 2) {
      $inputgrade = <STDIN>;
    } else {
      for ($i = 1; $i <= $CurrentSDUCount; $i++) {
	$opt = "";
	while ($opt ne "y" && $opt ne "Y" && $opt ne "n" && $opt ne "N"
	      && $opt ne "q" && $opt ne "Q" && $opt ne "x" && $opt ne "X") {
	  if ($i > 1) {
	    $frag   = $SourceUtts[$index];
	    @fields = split(/\#/,$frag);
   	    $j      = 1;
  	    print "\nSource Text:  \n";
   	    while(@fields-1) {
     		 $xxx = shift(@fields);
		 if ($j == $i) {
		    print "         >>  Segment $j: $xxx\n";
		    } else { 
    		        print "             Segment $j: $xxx\n"; }
     		 $j++;
   		 }
          print("\nTarget Translation:  $NewTargetUtts[$index] \n");	
	  }
	  print "\nIs segment $i sufficiently translated? (Y/N/X/Q)\n";
	  $opt = <STDIN>;
	  chomp($opt);
	}
	if ($i > 1) {$tempgrade = $tempgrade . " ";}	
	if ($opt eq "x" || $opt eq "X") {
	  $tempgrade = $tempgrade . "x";
	} elsif ($opt eq "n" || $opt eq "N") {
	  $opt = 0;
	  while ($opt ne "y" && $opt ne "Y" && $opt ne "n" && $opt ne "N"
		 && $opt ne "q" && $opt ne "Q") {
	    print "\nIs segment $i almost acceptable? (partially translated and/or just hard to understand) (Y/N/Q)\n";
	    $opt = <STDIN>;
	    chomp($opt);}

         if ($opt eq "y" || $opt eq "Y") {
	    $tempgrade = $tempgrade . "b";
	  } elsif ($opt eq "n" || $opt eq "N") {

	    $tempgrade = $tempgrade . "u";
	  } else {
	   $tempgrade = "q";
	   goto LV;
          }
	
    
	} elsif ($opt eq "y" || $opt eq "Y") {
	  $opt = 0;
	  while ($opt ne "y" && $opt ne "Y" && $opt ne "n" && $opt ne "N"
		 && $opt ne "q" && $opt ne "Q") {
	    print "\nIs segment $i fully understandable and equivalent in meaning? (Y/N/Q)\n";
	    $opt = <STDIN>;
	    chomp($opt);
	  }
	  if ($opt eq "y" || $opt eq "Y") {
	    $tempgrade = $tempgrade . "p";
	  } elsif ($opt eq "n" || $opt eq "N") {

	    $tempgrade = $tempgrade . "k";
	  } else {
	   $tempgrade = "q";
	   goto LV;
	  }
	} else {
	  $tempgrade = "q";
	  goto LV;
	}
      }
    LV:
      $inputgrade = $tempgrade;
    }
  }

  if ($QSTYLE == 2) { chop($inputgrade); }
  $CurrentGradeCount = CountGradesInNewGrade ($inputgrade);

  #HERE is the part for alligning grades and SDUs
  #print ("DEBUG $inputgrade $correct $CurrentSDUCount $CurrentGradeCount");
  if (!($inputgrade eq "")      && $CurrentSDUCount   && !($inputgrade =~ /\d/g)  && !($inputgrade =~ /[cqCQ]/g) 
      && !($inputgrade =~ /h/g) && $CurrentSDUCount   && (!($CurrentSDUCount eq  $CurrentGradeCount)  || ($CurrentGradeCount < 1))) {
    print ("\n\n\n\n\n\n *** INCORRECT NUMBER OF VALID GRADES (not saved) ***: $CurrentGradeCount -- expecting $CurrentSDUCount  \n\n\n\n\n\n");
    $inputgrade = "";
  }
  
  if (!($inputgrade eq "") && !($inputgrade eq "quit") && !($inputgrade eq "QUIT") && ($inputgrade =~ /[aAdDeEfFgGiIjJlLmMnNoOrRsStTvVwWyYzZ]/g)) {
    print ("\n\n\n\n\n\n *** INVALID grade letter (not saved) *** \n\n\n\n\n\n");    
    $inputgrade = "";
  }
  
  # Empty grade var will cause re-prompt.
  return($inputgrade);
}
    

#---------------------------------
# Grading loop for prompting grades 
# and setting them.

sub GradingLoop {
    
    my($current) = @_; # may be > 1 if temp file was read in
    my($end); # number of utterances to grade
    my($tempgrade);
    $end = @SourceUtts;

    #check for quit
    #check for 0
    if ($DEBUG) {
       $foo=@SourceUtts; 
       print ("sources: source Utt count $SourceUttCount, END $end , SourceUtts $foo.\n");
    }
    if ($end eq 0) {
        print ("\n*** Nothing to process! ***\n");
	$QUIT = 1;
    }

    if ($QSTYLE == 1){
       PrintHelp2();
    } else {PrintHelp();}

    while ((!$QUIT) && ($current > 0) && ($current <= $end)) {
        # may need 0 as second arg below too.  ( not a grade correction prompt)

	$tempgrade = PromptGrade($current); 

        if (($tempgrade eq "h") || ($tempgrade eq "help") || ($tempgrade eq "?")) {
           PrintHelp();           
           print ("Returning to last known ungraded utterance.\n");
        } elsif (($tempgrade >= 1) && ($tempgrade < $current)) { 
	   $correction = $tempgrade;

           PrintHelp(); 
           print ("You should only type grades or [return] to copy here!");

	   $tempgrade = PromptGrade($correction, 1); 
           if (($tempgrade =~ /[pkbPKBxXuU]/g) || ($tempgrade eq "")) {
	       ProcessGrade($correct, $tempgrade, 1);}
	   else {print ("Invalid Grade Entry No Changes Made!\n");}
           print ("Returning to last known ungraded utterance.\n");
        } else {
	   $result = ProcessGrade($current, $tempgrade, 0);
           if ($DEBUG) {print ("\t DEBUG in grade loop process grade's result: **$result** \n");}
           if ($result) {
	       ++$current;
               WriteGradeFile ($TempGradeFile, @NewGrades);
	   }
       }
    }
    WriteGradeFile ($TempGradeFile, @NewGrades);
    
}

#---------------------------------
# We will need to check the grades
#sub CheckGradeList { }


#---------------------------------
sub ProcessGrade {

# disable help and correction  under the redo/correction option
# quitting ok.

    my($current, $inputgrade, $redo) = @_;

    # remove extra spaces.
    $inputgrade=~ s/   / /; 
    $inputgrade=~ s/  / /; 

    if ($DEBUG) {print ("\t DEBUG PROCESSGRADE (1) : $current $inputgrade $redo \n");}

       # If there is a number still, it is invalid! Prevents redo from getting a number.
    if (($inputgrade > $current) || ($inputgrade < 0)) {
        print ("Invalid entry!\n");
	print ("Returning to last known utterance yet to be graded.\n");
        $result = 0;
    } elsif (($inputgrade eq "q") || ($inputgrade eq "quit") || ($inputgrade eq "QUIT")) {
	print ("QUITTING!\n");
        $QUIT = 1;
	$result = 0;
    }  elsif (($inputgrade eq "") || ($inputgrade eq " ")  || ($inputgrade eq "\t")) {
	$result = 0;
    } elsif (($inputgrade eq "h") || ($inputgrade eq "?") || ($inputgrade eq "help")) {
        PrintHelp();
	$result = 0;
    } elsif (($CanRegrade) && ($inputgrade eq "c")) {
        @NewGrades[$current - 1] = @OldGrades[$current - 1];
	$result = 1;
    } elsif ((!$CanRegrade) && ($inputgrade eq "c")) {
        print ("Invalid use of \"c\" (copy)!\n");
	$result = 0;
    } else {
	@NewGrades[$current - 1] = $inputgrade;
	$result = 1;
    }

    
  # Keep these at end of routine

    # Always return 0 if redoing a grade.
    # 1 will trigger goto next utterance in Main loop.
    if ($redo) {
	$result=0;
    }
    return($result);

}



#---------------------------------
# PrintHelp()
sub PrintHelp {

print ("\n
Possible responses\n
 New Grade(s):  \n\n
\t  p = very good (perfect)\n
\t  k = good (ok)\n
\t  b = bad\n
\t  u = very bad (interfering translaiton of no translation) \n
\t  x = null grade (*NLC* = no language content)\n
\n
\t  c = Copy grade(s) from the older translation to the new translation.\n
\n
\t  [return] = While correcting an earlier utterance, leave the existing grade as is.\n
\t             Otherwise, redisplay current utterance.\n\n
\t  h / ?    = print this help message \n 
\t                 (Help is deactivated while correcting a previous grade)\n
\t  q        = quit \n
\t  [1 - N]  = transfer temporarily to a previously graded utterance.  This is the number for \n
\t             the utterance that you would like to correct (must be less than current utt). \n
\t             (Deactivated when already correcting grades for previously graded utts) \n
\t              
\n
\n");
}


#---------------------------------
# PrintHelp2()
sub PrintHelp2 {
    
print ("\n
Possible responses\n
 New Grade(s):  \n\n
\t  y = yes\n
\t  n = no\n
\t  x = null grade\n
\t  q = quit\n
\t
\n
\n");
}


#---------------------------------
# Used at end of grading session.

sub PrintHelpQuit {
print ("\n
\t  q = quit\n
\t [1-N] = regrade the utterance with this number\n
\n
\n");
}



#---------------------------------
# Fetch the command-line arguments
# ReadFlags()

sub ReadFlags {

    $FirstArg = shift(@ARGV);
    $SecondArg = shift(@ARGV);

    if ($DEBUG) {print ("READING $FirstArg and $SecondArg \n");}

    if ($FirstArg eq "-score") {
	@FinalGrades = GetGradesFromFile ($SecondArg);
	$ScoreFile = ($SecondArg . "-scores");
	GetFinalScores ($ScoreFile, @FinalGrades);
        # finish program here
	exit(); 
    }
    #if ($FirstArg eq "-sort") {
    #    @FinalGrades = GetGradesFromFile ($SecondArg);
	#$BadFile = ($SecondArg . "-b");
	#$OkFile = ($SecondArg . "-k");
	#$PerfectFile = ($SecondArg . "-p");
	#$UndefinedFile = ($SecondArg . "-u");
	#$NullFile = ($SecondArg . "-x");
        #$SourceFile = shift(@ARGV);
        #$NewTargetFile = shift(@ARGV);
	#SortGradedSentences (@FinalGrades);
        #exit(); 
    #}


    if ($FirstArg eq "-offline") {
	$OFFLINE = 1;
	$OffLineFile = $SecondArg;
        $SourceFile = shift (@ARGV);
	$OldTargetFile = shift (@ARGV);
	$NewTargetFile = shift (@ARGV);
        ReadFiles();
        if ($CanGrade) {
	    MakeOfflineFile();
	} else {
	    print ("Cannot make offline file! Check Allignment! \n");
	}
	exit();
    }
    
    if ($FirstArg eq "-help") {
	ShowProgramHelp ();
        # finish program here
	exit();
    }

    if ($FirstArg) {
	$SourceFile = $FirstArg;
    } else { 
	print ("To grade: First file must be the Source language file.\n");
    }

    if ($SecondArg) {
	$NewTargetFile = $SecondArg;
    } else { 
	print ("To grade: Second argument must be the Target language file to be graded.\n");
    }

    while (@ARGV) {

        # The first remaining argument is assigned to $flag ...
	$flag = shift (@ARGV);

        # Checking for the filename and error-correction flags ...
 
	if ($flag eq "-old") {
	    $OldTargetFile = shift(@ARGV);
	    $OldGradeFile = shift(@ARGV);
	    next;
	}
	if ($flag eq "-average") {
	    $NumberOfGraders = shift(@ARGV);
	    next;
	}

	if ($flag eq "-user") {
	    $UserId = shift(@ARGV); # overwrite the user id
	    next;
	}

	if ($flag eq "-type") {
	    $GradeType = shift(@ARGV); # overwrite the user id
	    next;
	}

	if ($flag eq "-speaker") {
	    $SpeakerFile = shift(@ARGV); #
	    next;
	}
	
	if ($flag eq "-temp") {
	    $TempGradeFile = shift(@ARGV);
	    next;
	}

        if ($flag eq "-nocopy") {
	    $COPY = 0;   # this toggles $COPY mode; when on
	    next;        # duplicate translations will copy old grades to new
	}

        if ($flag eq "-debug") {
	    $DEBUG = 1;   # this toggles DEBUG mode; when on, various 
	    next;         # DEBUG statements are printed
	}

	# If there's anything else preceded by a '-', it gets kicked out
	# with a warning message...

	if (substr($flag,0,1) eq "-") {
	    warn ("Unrecognized option ".$_." in command line\n");
	    next;
	}
    }
    
}


sub GetGradesFromFile {
    my($infile) = @_;
    my($counter) = 0;
    my(@grades);
    my($line);
    if ((-e $infile) && open (SOURCE, $infile)) {
	$line = <SOURCE>;
        while ($line ne "") {
            chop($line);
            $line=~ s/\d+ //; 
            $line=~ s/\d+//; 
            if ($DEBUG) {print ("$line\n");}
	    $grades[$counter] = $line;
            $line = <SOURCE>;
            ++$counter;
	}
    } else {
	    print ("Cannot open file \"$infile\".\n");
	}
    # return the grades
    @grades;
}

sub SortGradedSentences {
    my(@grades) = @_;
    my($counter) = 0;
    my(@grades);
    my($line);
    if ((-e $infile) && open (SOURCE, $infile)) {
	$line = <SOURCE>;
        while ($line ne "") {
            chop($line);
            $line=~ s/\d+ //; 
            $line=~ s/\d+//; 
            if ($DEBUG) {print ("$line\n");}
	    $grades[$counter] = $line;
            $line = <SOURCE>;
            ++$counter;
	}
    } else {
	    print ("Cannot open file \"$infile\".\n");
	}
    # return the grades
    @grades;
}



    
sub GetFinalScores {
    my($outfile, @grades) = @_;
    my($cs_perfect) = 0;
    my($cs_ok) = 0;
    my($cs_bad) = 0;
    my($cs_undef) = 0;
    my($cs_null) = 0;
    my($cs_acceptable) = 0; 
    my($cs_linegrades);
    my($cs_count);
    my($templine);

    my($Subtotal);
    my($Total);
    my($PerfectScore); 
    my($OkScore); 
    my($BadScore); 
    my($UndefScore); 
    my($AcceptableScore); 


    if ($DEBUG) {
        $cs_count = @grades;
	print ("@grades\n");
	print ("$cs_count\n");
	while ($cs_count) {
	    --$cs_count;
	    print ("$grades[$cs_count]\n");
	}
    }
    $cs_count = @grades;
    while ($cs_count) {
	--$cs_count;
        $cs_linegrades = $grades[$cs_count];
        $templine = $cs_linegrades;
        while ($templine =~ /p/ig) {
	    #$match = $&;
            ++$cs_perfect;
	}
	$templine = $cs_linegrades;
        while ($templine =~ /k/ig) {
	    #$match = $&;
            ++$cs_ok;
	}
	$templine = $cs_linegrades;
        while ($templine =~ /b/ig) {
	    #$match = $&;
            ++$cs_bad;
	}
	$templine = $cs_linegrades;
        while ($templine =~ /u/ig) {
	    #$match = $&;
            ++$cs_undef;
	}
	$templine = $cs_linegrades;
        while ($templine =~ /x/ig) {
	    #$match = $&;
            ++$cs_null;
	}
    }
    $cs_count = @grades;
    if ($cs_count) {
	$SubTotal = ($cs_perfect + $cs_ok + $cs_bad + $cs_undef);
	$Total = ($SubTotal + $cs_null);

	$PerfectScore = (100 * ($cs_perfect / $SubTotal));
	$OkScore = (100 * ($cs_ok / $SubTotal));
	$BadScore = (100 * ($cs_bad / $SubTotal));
	$UndefScore = (100 * ($cs_undef / $SubTotal));
	$AcceptableScore = ($PerfectScore + $OkScore);
	$cs_acceptable = ($cs_perfect + $cs_ok);
	
        if ($NumberOfGraders > 1) {
	    $cs_perfect = ($cs_perfect / $NumberOfGraders);
	    $cs_ok = ($cs_ok / $NumberOfGraders);
	    $cs_bad = ($cs_bad / $NumberOfGraders);
	    $cs_undef = ($cs_undef / $NumberOfGraders);
	    $cs_acceptable = ($cs_acceptable / $NumberOfGraders);
            $SubTotal = ($SubTotal / $NumberOfGraders);
            $Total = ($Total / $NumberOfGraders);
            $cs_count = ($cs_count / $NumberOfGraders);}

        print ("______________________________________\n\n");
        print ("          GRADE SCORES          \n");
        print ("______________________________________\n\n");
	print (" Perfect      = \%$PerfectScore \($cs_perfect)\n");
	print (" Ok           = \%$OkScore \($cs_ok)\n");
	print (" Bad          = \%$BadScore \($cs_bad)\n");
	print (" Undefined    = \%$UndefScore \($cs_undef)\n");
	print ("______________________________________\n\n");
	print (" Acceptable   = \%$AcceptableScore ($cs_acceptable)\n");
	print (" SDU SubTotal = $SubTotal \n");
	print (" SDU Total    = $Total (including null) \n");
	print (" Utterances   = $cs_count \n");
	print ("______________________________________\n\n");
    

        if ($outfile) {
	    open (OUTFILE, (">" . $outfile));
	    print OUTFILE ("______________________________________\n\n");
	    print OUTFILE ("          GRADE SCORES          \n");
	    print OUTFILE ("______________________________________\n\n");
	    print OUTFILE (" Perfect      = \%$PerfectScore \($cs_perfect)\n");
	    print OUTFILE (" Ok           = \%$OkScore \($cs_ok)\n");
	    print OUTFILE (" Bad          = \%$BadScore \($cs_bad)\n");
	    print OUTFILE (" Undefined    = \%$UndefScore \($cs_undef)\n");
	    print OUTFILE ("______________________________________\n\n");
	    print OUTFILE (" Acceptable   = \%$AcceptableScore ($cs_acceptable)\n");
	    print OUTFILE (" SDU SubTotal = $SubTotal \n");
	    print OUTFILE (" SDU Total    = $Total (including null) \n");
	    print OUTFILE (" Utterances   = $cs_count \n");
	    print OUTFILE ("______________________________________\n\n");

	}

    } else {
	print ("No grades. No scores.");
    }
}


sub WriteGradeFile {
    my($gradefile, @grades) = @_;
    my($index) = 0;
    my($gradecount);
    my($gradelist);
    $gradecount = @grades;


    open (OUTFILE, (">" . $gradefile));
    while ($index < $gradecount) {
        $gradelist = $grades[$index];
        if ($DEBUG) {print (($index + 1) , " $gradelist \n");}
	print OUTFILE (($index + 1) , " $gradelist \n");
        ++$index; 
    
    }

}






#-----------------
# ReadFiles () : Read the input files for grading. 

#-offline ofile sfile tfile1 tfile2
#sfile tfile2 tfile1 tfile1grades


sub ReadFiles {
    if ($SourceFile && (-e $SourceFile) && open(SOURCE, $SourceFile)){
	$line = <SOURCE>;
	while ($line ne "") {
	    #if ($DEBUG) {print ("READING from SOURCE:  $line \n");}
	    $SourceUtts[$SourceUttCount]=$line;
	    $line = <SOURCE>;
            ++$SourceUttCount;
	}
    } else {
	print ("You need a valid Source language input file!\n");
    }
    if ($SourceUttCount > 0) {
	$CanGrade=1; 
    }

    if ($SpeakerFile && (-e $SpeakerFile) && open(SOURCE, $SpeakerFile)){
	$line = <SOURCE>;
	while ($line ne "") {
            chop($line);
	    #if ($DEBUG) {print ("READING from SOURCE:  $line \n");}
	    $Speakers[$SpeakerCount]=$line;
	    $line = <SOURCE>;
            ++$SpeakerCount;

	}
	if ($SpeakerCount == $SourceUttCount) {
	    $Speaker=1;
	} else {
	    print ("Not using speaker info. Number of Speakers not equal to Source file!\n");
	}
    } else {
	print ("No speaker file is loaded!\n");
    }


    if ($CanGrade && $NewTargetFile && (-e $NewTargetFile) && open(NEWTARGET, $NewTargetFile))
      {
	$line = <NEWTARGET>;
	while ($line ne "") {
	    $NewTargetUtts[$NewTargetUttCount]=$line;
	    $line = <NEWTARGET>;
            ++$NewTargetUttCount;
            if ($OFFLINE) {$CanRegrade=1;}
	}
    } else {
        if ($OFFLINE) {
	    $CanRegrade=0;
	    print ("No Second Target language input file (to grade) has been loaded!\n");
	} else {
            $CanGrade=0;
	    print ("No New Target language input file (to grade) has been loaded!\n");
	}
    }



    if ($CanGrade && $OldTargetFile && (-e $OldTargetFile) && open(OLDTARGET, $OldTargetFile))
    {   if ($OFFLINE) {$CanGrade=1;} else {$CanRegrade=1;}
        $line = <OLDTARGET>;
	while ($line ne "") {
	    $OldTargetUtts[$OldTargetUttCount]=$line;
	    $line = <OLDTARGET>;
            ++$OldTargetUttCount;
	}
    } else {
        # Kill all grading just in case.
        if ($OldTargetFile) {$CanGrade=0;}
        $CanRegrade=0;
        if ($OFFLINE) {

	    print ("No First Target translation file loaded. You cannot grade!\n");
	} else {
	    print ("No Old Target translation file loaded. You cannot regrade!\n");
	}
    }
    unless ($OFFLINE) {
	if ($CanRegrade && $CanGrade && $OldGradeFile && (-e $OldGradeFile) && open(OLDGRADES, $OldGradeFile)) {
      
	    $line = <OLDGRADES>;
	    while ($line ne "") {
		$OldGrades[$OldGradeCount]=$line;
		$line = <OLDGRADES>;
		++$OldGradeCount;
	    }
	} else {
        ## Kill all grading here, just in case.
	    if ($CanRegrade) {$CanGrade=0;}
	    $CanRegrade=0;
	    print ("No Old Grade file loaded. You cannot regrade!\n");
	}
    }

# Check to be sure the files have the same number of Utterances/grades.
# Allignment is required here.

    if ((!$OFFLINE) && ($CanGrade)) {
        $CanGrade = ($NewTargetUttCount == $SourceUttCount);
        if (!$CanGrade) {
	    print ("Input Files are not aligned:\n source = $SourceUttCount, new target = $NewTargetUttCount\n\n");
	}
    } elsif (($OFFLINE) && ($CanGrade)) {
	$CanGrade = ($OldTargetUttCount == $SourceUttCount);
        if (!$CanGrade) {
	    print ("Input Files are not aligned:\n source = $SourceUttCount, target1 = $OldTargetUttCount\n\n");
	}
    }

    #print ("DEBUG: Input Files counts:\n source = $SourceUttCount, target = $NewTargetUttCount \n, old target = $OldTargetUttCount, old grades = $OldGradeCount\n");

    #Bipass the grade equal check for offline mode
    if ($OFFLINE) {$OldGradeCount = $OldTargetUttCount;}

    if ($CanGrade && $CanRegrade) {
        $CanRegrade = (($OldTargetUttCount == $OldGradeCount) && ($NewTargetUttCount == $OldTargetUttCount)); 
        $CanGrade = $CanRegrade;
	#print ("DEBUG: CanReGrade = $CanRegrade \n");
	if ((!$OFFLINE) && (!$CanGrade)) {
	    print ("Input Files are not aligned:\nsource = $SourceUttCount, target = $NewTargetUttCount, old target = $OldTargetUttCount, old grades = $OldGradeCount\n\nNo grading allowed.\n");
	} elsif (!$CanGrade) {
	    if ($NewTargetFile) {
		print ("Input Files are not aligned:\nsource = $SourceUttCount, target1 = $OldTargetUttCount, target2= $NewTargetUttCount. Cannot make offline grading file.\n");
	    }else{
		print ("Input Files are not aligned:\nsource = $SourceUttCount, target1 = $OldTargetUttCount. Cannot make offline grading file.\n");
	    }
	}

    }

    if ($CanGrade && $CanRegrade) {
	print ("\nOK to start regrading!\n");
    } elsif ($CanGrade) {
	print ("\nOK to start first time grading!\n");
    } elsif ($OFFLINE) {
        print ("\nNOT OK to make offline grade file!\n");
    } else {
	print ("\nNOT OK to start grading!\n");
    }

    if ((!$OFFLINE) && ($DEBUG)) {print ("tempfile = $TempGradeFile\n");}

    if ((!$OFFLINE) && ($CanGrade) && $TempGradeFile) {
	@NewGrades = GetGradesFromFile($TempGradeFile);
    }
}
sub ShowProgramHelp {
    print ("\nTo view this help message: \n % new-grade.pl -help\n");
    print ("\nTo make a file for offline grading: \n % new-grade.pl -offline \"**OFFLINE output file name**\"  \"source filename\" \"first set (a) of target translations filename\" and optionally \"second set (b) of target translations filename\".\n");

   print ("\nExample: % new-grade.pl -offline \"sample-offline-file\" \"sample-source\" \"sampletarget\" \"sampletarget-v2\"\n");
    print ("\n*NOTE* Please use \# to mark SDU boundaries for grading. \n If no bouandries found in source transcript, \n then program will assume any number of grades possible.\n");
    print ("\nTo get scores for a grade file: \n % new-grade.pl -score \"grade filename\".\n");
    print ("\tNote: Scores are calculated when you finish grading. \n\t      Use this if you change the grade file by hand\n\t       and want to recalculate the scores.\n\t** Do not use this in combination with any option below! **\n");
    print ("\nTo grade a new translation file: \n % new-grade.pl \"source language filename\" \"target language filename\".\n");
    print ("\nTo (re)grade a new version of a translation file by comparing it \nto a previously graded set of translations from the same source use: \n");
    print ("\t -old <old transl> <old grades> \n\t This will save you some time in grading \n\t since it automatically copies grades for identical translations\n\t (See -nocopy for how to override the grade copy feature) \n\n % new-grade.pl \"sample-source\" \"sampletarget\" -old \"sampleoldtarget\" \"sampleoldtarget.eval.grades-dmg\"\n\n");

    print ("\nTo use a temp grade file:\n (This allows you start over where you left off before\n  quitting a long session or before a computer/file system error.)\n\t-temp <tempfile>\n % new-grade.pl \"samplesource\" \"sampletarget\" -temp \"sampletarget.eval.grades-dmg-temp\"\n");
    print ("\nThe -temp option will work with regrade as well. \n Note: -temp <tempfile> goes after the list of -old files.\n");
    print ("\n % new-grade.pl \"samplesource\" \"sampletarget-v2\" -old \"sampleoldtarget\" \"sampleoldtarget.eval.grades-dmg\" -temp \"sampletarget-v2.eval.grades-dmg-temp\"\n");
    print ("\n\tTo prevent loss of grades in the temp file, there are up to \n\t3 backups of a temp file: xxx.BAK1, xxx.BAK2, xxx.BAK3\n");
    print ("\nOther key words that can be used (except with -score option): \n\n ");
    print ("\t -user \"yourname/userid\" \n\t  automatically uses your login name, \n\t  only use this if you want a different user extension).\n");
    print ("\t -type <type> : type of evaluation \"eval\" or \"dev\" \n");
    print ("\t   or whatever string you want inserted in the output\n\t   filename to help distinguish it.\n");
    print ("\t -nocopy : For identical translations, do not copy grades from older translations.\n\n");
    print ("\t -debug :  Show debug statements (not recommended for use while garding). \n\n");

    print ("\t PLEASE NOTE: In order for the grading program to allow you to grade,\n\t the source utterance file and target translation file must be alligned perfectly.\n\t There should be 1 utterance per line and no empty lines other than the last line of a file. \n\t An empty translation should have something on the line as a space filler.\n\t This applies to the old translation and grade files as well (empty grade = x).\n\n");

    print ("\t For more information or if you have questions \n \t or problems contact: Donna M. Gates (email: dmg\@cs.cmu.edu, office phone: 1-412-268-6594) \n\n");
    print ("\t Property of:\tLanguage Technologies Institute \n \t\t\tCarnegie Mellon University \n");
    print ("\t\t\t5000 Forbes Ave.\n");
    print ("\t\t\tPittsburgh, PA, 15213\n");
    print ("\t\t\tUSA\n");
}


sub MakeOfflineFile {
    my($index) = 0;
    my($utt) = 1;
    open (OUTFILE, (">" . $OffLineFile));
       # $SourceUttCount for termination of loop.
    while ($index < $SourceUttCount) {
        print OUTFILE ("\n------------------------------------------------------------\n\nUtt: $utt\n");  
        if ($Speaker) {
	    print OUTFILE ("\nSource Text:  $Speakers[$index]: $SourceUtts[$index]\n");
	} else {
	    print OUTFILE ("\nSource Text:  $SourceUtts[$index]\n"); }
	print OUTFILE ("\nTranslation (a):  $OldTargetUtts[$index] \n");
	print OUTFILE ("  [ ] Perfect       [ ] Ok         [ ] Bad \n");
        if ($CanRegrade) {
	    print OUTFILE ("\n\nTranslation (b):  $NewTargetUtts[$index] \n");
            print OUTFILE ("  [ ] Perfect       [ ] Ok         [ ] Bad \n");
	}
	++$index;
	++$utt;
       }
}

    


       
sub CountSDUsInUtt {
    my($utt) = @_;
    my($sducounter) = 0;
    
    while ($utt =~ /\#/ig) {
	    
	++$sducounter;
       }
    return ($sducounter);}

sub CountGradesInNewGrade {
    my ($gradestring) = @_;
    my ($gradecounter) = 0;
    while ($gradestring =~ /[pPbBkKxXuU]/ig) {
	++$gradecounter;
    }
    return ($gradecounter);
   
}
    
    
     
