Toastmasters tmsched.pl

#!/usr/bin/perl
#
# Toastmasters Scheduler Program
#
# Remove Ah-Counter - add place for word of the day. 9/15/2013
# 1. Modify tmshed.pl (this program)
#   a. comment out line 235 calls to AssignAhCounter
#
# 2. Modify adocs/schedule.html to be replace in scheduling form.
# 3. Modify adocs/schedyou.html to replace in scheduling yourself form.
# 4. Modify adocs/agenda.html to remove ah-counter and replace word of the day with {a 'ah-counter'} or whatever the abase tag was.
#
#
# Enabled not assigning general evaluators to people with less than 2 speeches. - 2004-03-07
#
# Copyright 2006 by Richard Halverson, Jr. 2006-10-10
# Copyright 2000 by Richard Halverson, Jr. 2000-10-20
# Copyright 1997 by Richard Halverson, Jr. 1998-11-04
#
# This program generates assigns duties for a given meeting.
# Inputs:
#   desires.txt - spreadsheet containing duty desires of each member
#   availability.txt - spreadsheet containing availability of each member
#   schedule.txt - spreadsheet containing past meeting's duty assignments
#   roster.txt - spreadsheet containing toastmaster level of each member
#   
#   $path - path to the directory containing spreadsheets
#   $date - date of meeting
#
# Ouput:
#   schedule.txt - 

$vpEdEmail="Rich Halverson ";

$vpEdEmail="Colleen Murray ";

$vpEdEmail="Brian Takahashi ";

$vpEdEmail="Eric Taramasco ";

$vpEdEmail="Katie Stula ";

$vpEdEmail="John Holman ";

$vpEdEmail="Daena Lee ";

$debug=0;
$send_email=0;

$sendmail='/usr/sbin/sendmail -t -f richhalverson@gmail.com';

$stdout=">-";

$lastEmail = '/home/dbatoast/adocs/dba/schedule/lastemail.txt';

if($send_email==1){
	$outfile="| $sendmail";
}else{
	$outfile=$stdout;
};
# 
 $ToEmail='all@dbatoastmasters.com';
# $ToEmail='richtest@lists.oahumail.com';
#
#  $docroot='/usr/local/www/adocs';
#  $docroot='/www/sites/virtual/dbatoastmasters.com/adocs';
  $docroot='/home/dbatoast/adocs';
  $path='/dba/schedule/';
  $desires='desire.txt';
  $availability='availability.txt';
  $schedule='schedule.txt';
  $scheduleFileTest='testSchedule.txt';
  $roster='roster.txt';
  $cronupdate=$docroot.'/dba/updatecron.conf';
#  $weekout='weekout.tpl';
#
#  print "0=$ARGV[0], 1=$ARGV[1], 2=$ARGV[2]\n";
#

  $weeksahead=2;
  $updateschedule=1;
  $scheduleAhead=30;
  
# Constants containing the minimum number of meetings between duties
#
  $since_speaker=3;
  $since_toastmaster=8;
  $since_tabletopics=5;
  $since_inspiration=5;
  $since_jokemaster=5;
  $since_grammarian=5;
  $since_evaluator=1;
  $since_generalevaluator=3;
  $since_ahcounter=2;
  $since_timer=2;
#
#  $since_speaker=3;
#  $since_toastmaster=6;
#  $since_tabletopics=3;
#  $since_inspiration=2;
#  $since_jokemaster=3;
#  $since_grammarian=3;
#  $since_evaluator=1;
#  $since_generalevaluator=3;
#  $since_ahcounter=2;
#  $since_timer=2;
#
  $number_speakers=4;
  $number_speakers=3; # June 9, 2016
  my(%futureWednesdaysIndex,@futureWednesdaysPresent,@futureWednesdaysRecord);
  $maxMeeting=0;
#
#
# Algorithm
# 1. Input Schedule starting from meeting s.
#    Build array for each member containing the last time each duty
#    was performed.
# 
#
# Parse form input variables from client
#
  read(STDIN,$buffer,$ENV{CONTENT_LENGTH});
  if($buffer eq ''){$buffer=$ENV{QUERY_STRING}};
  @pairs=split(/&/,$buffer);
  foreach $pair(@pairs){
    ($name,$value)=split(/=/, $pair);
    $value=~tr/+/ /;
    $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $name=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $value=~s/~!/ ~!/g;
    if(!$FORM{$name}){
      $FORM{$name}=$value;
    }else{
      $FORM{$name}=$FORM{$name}.'#'.$value;
    };
  };
  if($buffer ne ''){
    print "Content-Type: text/plain\n\n";
  };
#
# Assign local variables from parsed form input variables
#
  $weekout='';
  if(exists $FORM{"\$abase"}){$weekout=$FORM{"\$abase"}};
  if(exists $FORM{"\$path"}){$path=$FORM{"\$path"}};

# Figure out which Wednesday to do the schedule for

  if($FORM{"\$date"} ne ''){
    $date=$FORM{"\$date"};
  }elsif($ARGV[0] ne ''){
    $date=$ARGV[0];
  }else{
    $date=&NextWednesday($weeksahead);
  };

  $thiswednesday=&NextWednesday(0);
  $nextwednesday=&NextWednesday(1);
  $next2wednesday=&NextWednesday(2);

  if($ARGV[1] ne ''){
    $verbose=$ARGV[1];chomp($verbose);
  }elsif($FORM{"\$verbose"} ne ''){
    $verbose=$FORM{"\$verbose"};
  }else{
    $verbose=0;
  };
  if($verbose>=1){print STDOUT "\nDBA Toastmasters Scheduling program ($date,$verbose)\n"};

# $date needs to be in the format 1-Jan-06

  $datetype=0;
  if($date=~/^\d+$/){
    $datetype=1;
  }elsif($date=~/(\d{1,2})\-([a-zA-Z])([a-z]{2})\-(\d{2})/){
    $d=$1;$M=$2;$on=$3;$y=$4;
    $date=$d.'-'.uc($M).$on.'-'.$y;
  };
  &LoadRoster;
  &LoadSchedule;
#  if($date=~/^\d+$/){
#    $date=$short_date[$date];
#  }elsif($date=~/(\d{1,2})\-([a-zA-Z])([a-z]{2})\-(\d{2})/){
#    $d=$1;$M=$2;$on=$3;$y=$4;
#    $date=$d.'-'.uc($M).$on.'-'.$y;
#  };
  &LoadDesires;
  &LoadAvailability;

# Generate future Wednesdays Calendar for when updating the schedule file

 for($i=0;$i<=$scheduleAhead;$i++){
	$futureWednesdaysRecord[$i]=&NextWednesdayArray($i);
	$futureWednesdaysIndex{&NextWednesday($i)}=$i;
	$futureWednesdaysPresent[$i]=0;
#    if($verbose>=0){print STDOUT "$i, $futureWednesdaysRecord[$i] \n"};

};

# Check to see if there's a meeting number for the $date we're supposed to be doing the schedule for

  if(exists $meeting_number{$date}){
    $meet_num=$meeting_number{$date};
    @e=split(/\t/,$schedule_file{$meet_num});
    $tw_tm=$e[$sf_tm];if($tw_tm ne ''){$tw_duty{$memberkey{$e[$sf_tm]}}="Toastmaster"};
    $tw_em=$e[$sf_em];
    $tw_in=$e[$sf_in];if($tw_in ne ''){$tw_duty{$memberkey{$e[$sf_in]}}="Inspiration"};
    $tw_jm=$e[$sf_jm];if($tw_jm ne ''){$tw_duty{$memberkey{$e[$sf_jm]}}="Jokemaster"};
    $tw_gr=$e[$sf_gr];if($tw_gr ne ''){$tw_duty{$memberkey{$e[$sf_gr]}}="Grammarian"};
    $tw_ah=$e[$sf_ah];if($tw_ah ne ''){$tw_duty{$memberkey{$e[$sf_ah]}}="Ah-Counter"};
    $tw_ti=$e[$sf_ti];if($tw_ti ne ''){$tw_duty{$memberkey{$e[$sf_ti]}}="Timer"};
    $tw_s1=$e[$sf_s1];if($tw_s1 ne ''){$tw_duty{$memberkey{$e[$sf_s1]}}="Speaker 1"};
    $tw_s2=$e[$sf_s2];if($tw_s2 ne ''){$tw_duty{$memberkey{$e[$sf_s2]}}="Speaker 2"};
    $tw_s3=$e[$sf_s3];if($tw_s3 ne ''){$tw_duty{$memberkey{$e[$sf_s3]}}="Speaker 3"};
    $tw_s4=$e[$sf_s4];if($tw_s4 ne ''){$tw_duty{$memberkey{$e[$sf_s4]}}="Speaker 4"};
    $tw_e1=$e[$sf_e1];if($tw_e1 ne ''){$tw_duty{$memberkey{$e[$sf_e1]}}="Evaluator 1"};
    $tw_e2=$e[$sf_e2];if($tw_e2 ne ''){$tw_duty{$memberkey{$e[$sf_e2]}}="Evaluator 2"};
    $tw_e3=$e[$sf_e3];if($tw_e3 ne ''){$tw_duty{$memberkey{$e[$sf_e3]}}="Evaluator 3"};
    $tw_e4=$e[$sf_e4];if($tw_e4 ne ''){$tw_duty{$memberkey{$e[$sf_e4]}}="Evaluator 4"};
    $tw_ge=$e[$sf_ge];if($tw_ge ne ''){$tw_duty{$memberkey{$e[$sf_ge]}}="General Evaluator"};
    $tw_tt=$e[$sf_tt];if($tw_tt ne ''){$tw_duty{$memberkey{$e[$sf_tt]}}="Table Topics Master"};
#
    if($verbose>=2){print STDOUT "\n"};
    if(($tw_s1 eq '')||($tw_s2 eq '')||($tw_s3 eq '')||($tw_s4 eq '')){
      &AssignSpeakers;
    }elsif($verbose>=2){print STDOUT "Speakers already assigned ($tw_s1, $tw_s2, $tw_s3, $tw_s4)\n"};
    if($tw_tm eq ''){
      &AssignToastmaster;
    }elsif($verbose>=2){print STDOUT "Toastmaster assigned ($tw_tm)\n"};
    if($tw_tt eq ''){
      &AssignTableTopics;
    }elsif($verbose>=2){print STDOUT "Table Topics Master assigned ($tw_tt)\n"};
    if($tw_in eq ''){
      &AssignInspiration;
    }elsif($verbose>=2){print STDOUT "Inspiration assigned ($tw_in)\n"};
    if($tw_jm eq ''){
      &AssignJokemaster;
    }elsif($verbose>=2){print STDOUT "Jokemaster assigned ($tw_jm)\n"};
    if($tw_gr eq ''){
      &AssignGrammarian;
    }elsif($verbose>=2){print STDOUT "Grammarian assigned ($tw_gr)\n"};
    if($tw_ge eq ''){
      &AssignGeneralEvaluator;
    }elsif($verbose>=2){print STDOUT "General Evaluator assigned ($tw_ge)\n"};
    if($tw_ah eq ''){
#      &AssignAhCounter;
    }elsif($verbose>=2){print STDOUT "Word of the day assigned ($tw_ah)\n"};
    if($tw_ti eq ''){
      &AssignTimer;
    }elsif($verbose>=2){print STDOUT "Timer assigned ($tw_ti)\n"};
    if(($tw_e1 eq '')||($tw_e2 eq '')||($tw_e3 eq '')||($tw_e4 eq '')){
      &AssignEvaluators;
    }elsif($verbose>=2){print STDOUT "Evaluators assigned ($tw_e1, $tw_e2, $tw_e3, $tw_e4)\n"};
#
    $tw_em=$memberemail{$memberkey{$tw_tm}};
    if($verbose>=1){
      print STDOUT "\n";
      print STDOUT "       Schedule for: $date\n\n";
      print STDOUT "        Toastmaster: $tw_tm\n";
      print STDOUT "              Email: $tw_em\n";
      print STDOUT "        Inspiration: $tw_in\n";
      print STDOUT "         Jokemaster: $tw_jm\n";
      print STDOUT "         Grammarian: $tw_gr\n";
      print STDOUT "    Word of the day: $tw_ah\n";
      print STDOUT "              Timer: $tw_ti\n";
      print STDOUT "          Speaker 1: $tw_s1\n";
      print STDOUT "          Speaker 2: $tw_s2\n";
      print STDOUT "          Speaker 3: $tw_s3\n";
      print STDOUT "          Speaker 4: $tw_s4\n";
      print STDOUT "        Evaluator 1: $tw_e1\n";
      print STDOUT "        Evaluator 2: $tw_e2\n";
      print STDOUT "        Evaluator 3: $tw_e3\n";
      print STDOUT "        Evaluator 4: $tw_e4\n";
      print STDOUT "Table Topics Master: $tw_tt\n";
      print STDOUT "  General Evaluator: $tw_ge\n";
      print STDOUT "\n";
    };
    if($weekout ne ''){
      $file=$docroot.'/'.$path.'/'.$weekout;$file=~s/\/+/\//g;
      if(open(F,'>'.$file)){
        if($verbose>=4){print STDOUT "Printing $file\n\n\n"};
        print F "{a ShortDate=$date}\n";
        print F "{a Meeting=$meet_num}\n";
        print F "{a Toastmaster=$tw_tm}\n";
        print F "{a Email=$tw_em}\n";
        print F "{a Inspiration=$tw_in}\n";
        print F "{a Jokemaster=$tw_jm}\n";
        print F "{a Grammarian=$tw_gr}\n";
        print F "{a Ah-Counter=$tw_ah}\n";
        print F "{a Timer=$tw_ti}\n";
        print F "{a Speaker1=$tw_s1}\n";
        print F "{a Speaker2=$tw_s2}\n";
        print F "{a Speaker3=$tw_s3}\n";
        print F "{a Speaker4=$tw_s4}\n";
        print F "{a Evaluator1=$tw_e1}\n";
        print F "{a Evaluator2=$tw_e2}\n";
        print F "{a Evaluator3=$tw_e3}\n";
        print F "{a Evaluator4=$tw_e4}\n";
        print F "{a GeneralEvaluator=$tw_ge}\n";
        print F "{a TableTopicsMaster=$tw_tt}\n";
        close(F);
      };
    };

    if($updateschedule ne ''){&UpdateScheduleFile};

    $file=$docroot.'/'.$path.'/'.$weekout;$file=~s/\/+/\//g;
    if(1==0){
      if(open(F,'>'.$file)){
        print F "ShortDate\tMeeting\tToastmaster\tInspiration\tJokemaster\t";
        print F "Grammarian\tAh-Counter\tTimer\t";
        print F "Speaker 1\tSpeaker 2\tSpeaker 3\tSpeaker 4\t";
        print F "Evaluator 1\tEvaluator 2\tEvaluator 3\tEvaluator 4\t";
        print F "General Evaluator\tTable Topics Master";
        print F "\n";
        print F "$date\t$meet_num\t$tw_tm\t$tw_in\t$tw_jm\t";
        print F "$tw_gr\t$tw_ah\t$tw_ti\t";
        print F "$tw_s1\t$tw_s2\t$tw_s3\t$tw_s4\t";
        print F "$tw_e1\t$tw_e2\t$tw_e3\t$tw_e4\t";
        print F "$tw_ge\t$tw_tt";
        print F "\n";
        close(F);
      };
    };
  }else{
    if($verbose>=2){print STDOUT "No meeting scheduled on $date\n"};
  };
#
exit;
#
################################################################################ Assign Speaker
#
sub AssignSpeakers{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Speakers for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
    }elsif($sp_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
    }elsif($sp_last{$i}>$meet_num-$since_speaker){
      $possibility=0;
      if(($verbose>=3)&&($sp_last{$i}>=$meet_num)){
        print STDOUT "is already speaking on "
      }elsif($verbose>=3){
        print STDOUT "just spoke on "
      };
      if($verbose>=3){print STDOUT "$short_date[$sp_last{$i}]"};
    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just toastmaster"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($sp_last{$i} eq ''){$sp_last{i}=0};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
      $r=(5-$sp_desire{$i})*100000+$r*1000+$sp_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$sp_last{$i}\t$short_date[$sp_last{$i}]";
      if($verbose>=3){
        if($sp_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for speaker\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_s1 eq '')&&($number_speakers>=1)){
    @e=split(/\t/,$candidate[$j]);
    $tw_s1=$membername{$e[0]};
    $tw_duty{$e[0]}="Speaker 1";
    $j+=1;
  };
  if(($j<$c)&&($tw_s2 eq '')&&($number_speakers>=2)){
    @e=split(/\t/,$candidate[$j]);
    $tw_s2=$membername{$e[0]};
    $tw_duty{$e[0]}="Speaker 2";
    $j+=1;
  };
  if(($j<$c)&&($tw_s3 eq '')&&($number_speakers>=3)){
    @e=split(/\t/,$candidate[$j]);
    $tw_s3=$membername{$e[0]};
    $tw_duty{$e[0]}="Speaker 3";
    $j+=1;
  };
  if(($j<$c)&&($tw_s4 eq '')&&($number_speakers>=4)){
    @e=split(/\t/,$candidate[$j]);
    $tw_s4=$membername{$e[0]};
    $tw_duty{$e[0]}="Speaker 4";
    $j+=1;
  };
};
#
################################################################################ Assign Toastmaster
#
sub AssignToastmaster{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Toastmaster for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($tm_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
    }elsif($memberspeeches{$i}<3){
      $possibility=0;
      if($verbose>=3){print STDOUT "hasn't given 3 speeches yet"};
    }elsif($tm_last{$i}>$meet_num-$since_toastmaster){
      $possibility=0;
      if(($verbose>=3)&&($tm_last{$i}>=$meet_num)){
        print STDOUT "is already toastmaster on "
      }elsif($verbose>=3){
        print STDOUT "was just toastmaster on "
      };
      if($verbose>=3){print STDOUT "$short_date[$tm_last{$i}]"};
    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just spoke"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($tm_last{$i} eq ''){$tm_last{i}=0};
#      $r=(2-$tm_desire{$i})*10000+$memberrank{$i}*1000+$tm_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
# Seasoned TMs have priority over rookies
      if($r<10){$r=9-$r};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$tm_desire{$i})*100000+$r*1000+$tm_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$tm_last{$i}\t$short_date[$tm_last{$i}]";
      if($verbose>=3){
        if($tm_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for toastmaster\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_tm eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_tm=$membername{$e[0]};
    $tw_duty{$e[0]}="Toastmaster";
    $j+=1;
  };
};
#
################################################################################ Assign Table Topics
#
sub AssignTableTopics{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Table Topics Master for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($tt_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($tt_last{$i}>$meet_num-$since_tabletopics){
      $possibility=0;
      if(($verbose>=3)&&($tt_last{$i}>=$meet_num)){
        print STDOUT "is already table topics master on "
      }elsif($verbose>=3){
        print STDOUT "was just table topics master on "
      };
      if($verbose>=3){print STDOUT "$short_date[$tt_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
    }elsif($memberspeeches{$i}<2){
      $possibility=0;
      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just was toastmaster"};
    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just spoke"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($tt_last{$i} eq ''){$tt_last{i}=0};
#      $r=(2-$tt_desire{$i})*10000+$memberrank{$i}*1000+$tt_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
# Seasoned TMs have priority over rookies
      if($r<10){$r=9-$r};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$tt_desire{$i})*100000+$r*1000+$tt_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$tt_last{$i}\t$short_date[$tt_last{$i}]";
      if($verbose>=3){
        if($tt_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for table topics master\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_tt eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_tt=$membername{$e[0]};
    $tw_duty{$e[0]}="Table Topics Master";
    $j+=1;
  };
};
#
################################################################################ Assign Inspiration
#
sub AssignInspiration{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Inspiration for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($in_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($in_last{$i}>$meet_num-$since_inspiration){
      $possibility=0;
      if(($verbose>=3)&&($in_last{$i}>=$meet_num)){
        print STDOUT "is already giving the inspiration on "
      }elsif($verbose>=3){
        print STDOUT "just gave the inspiration on "
      };
      if($verbose>=3){print STDOUT "$short_date[$in_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
#    }elsif($memberspeeches{$i}<4){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "hasn't given 4 speeches yet"};
    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just was toastmaster"};
    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just spoke"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($in_last{$i} eq ''){$in_last{i}=0};
#      $r=(2-$in_desire{$i})*10000+$memberrank{$i}*1000+$in_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$in_desire{$i})*100000+$r*1000+$in_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$in_last{$i}\t$short_date[$in_last{$i}]";
      if($verbose>=3){
        if($in_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for giving the inspiration\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_in eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_in=$membername{$e[0]};
    $tw_duty{$e[0]}="Inspiration";
    $j+=1;
  };
};
#
################################################################################ Assign Jokemaster
#
sub AssignJokemaster{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Jokemaster for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($jm_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($jm_last{$i}>$meet_num-$since_jokemaster){
      $possibility=0;
      if(($verbose>=3)&&($jm_last{$i}>=$meet_num)){
        print STDOUT "is already jokemaster on "
      }elsif($verbose>=3){
        print STDOUT "was just jokemaster on "
      };
      if($verbose>=3){print STDOUT "$short_date[$jm_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
#    }elsif($memberspeeches{$i}<2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just was toastmaster"};
    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just spoke"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($jm_last{$i} eq ''){$jm_last{i}=0};
#      $r=(2-$jm_desire{$i})*10000+$memberrank{$i}*1000+$jm_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
# Seasoned TMs have priority over rookies
      if($r<10){$r=9-$r};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$jm_desire{$i})*100000+$r*1000+$jm_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$jm_last{$i}\t$short_date[$jm_last{$i}]";
      if($verbose>=3){
        if($jm_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for jokemaster\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_jm eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_jm=$membername{$e[0]};
    $tw_duty{$e[0]}="Jokemaster";
    $j+=1;
  };
};
#
################################################################################ Assign Grammarian
#
sub AssignGrammarian{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Grammarian for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($gr_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($gr_last{$i}>$meet_num-$since_grammarian){
      $possibility=0;
      if(($verbose>=3)&&($gr_last{$i}>=$meet_num)){
        print STDOUT "is already grammarian on "
      }elsif($verbose>=3){
        print STDOUT "was just grammarian on "
      };
      if($verbose>=3){print STDOUT "$short_date[$gr_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
#    }elsif($memberspeeches{$i}<2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just was toastmaster"};
    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just spoke"};
    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just table topics master"};
    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "just did inspiration"};
    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just jokemaster"};
    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
      $possibility=0;
      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($gr_last{$i} eq ''){$gr_last{i}=0};
#      $r=(2-$gr_desire{$i})*10000+$memberrank{$i}*1000+$gr_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$gr_desire{$i})*100000+$r*1000+$gr_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$gr_last{$i}\t$short_date[$gr_last{$i}]";
      if($verbose>=3){
        if($gm_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for grammarian\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_gr eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_gr=$membername{$e[0]};
    $tw_duty{$e[0]}="Grammarian";
    $j+=1;
  };
};
#
########################################################################### Assign General Evaluator
#
sub AssignGeneralEvaluator{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning General Evaluator for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($ge_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($ge_last{$i}>$meet_num-$since_generalevaluator){
      $possibility=0;
      if(($verbose>=3)&&($ge_last{$i}>=$meet_num)){
        print STDOUT "is already general evaluator on "
      }elsif($verbose>=3){
        print STDOUT "was just general evaluator on "
      };
      if($verbose>=3){print STDOUT "$short_date[$ge_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
    }elsif($memberspeeches{$i}<2){
      $possibility=0;
      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
#    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just was toastmaster"};
#    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just spoke"};
#    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just table topics master"};
#    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just did inspiration"};
#    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just jokemaster"};
#    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($ge_last{$i} eq ''){$ge_last{i}=0};
#      $r=(2-$ge_desire{$i})*10000+$memberrank{$i}*1000+$ge_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
# Seasoned TMs have priority over rookies
      if($r<10){$r=9-$r};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$ge_desire{$i})*100000+$r*1000+$ge_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$ge_last{$i}\t$short_date[$ge_last{$i}]";
      if($verbose>=3){
        if($ge_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for general evaluator\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_ge eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_ge=$membername{$e[0]};
    $tw_duty{$e[0]}="General Evaluator";
    $j+=1;
  };
};
#
################################################################################ Assign AhCounter
#
sub AssignAhCounter{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Ah-Counter for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($ah_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($ah_last{$i}>$meet_num-$since_ahcounter){
      $possibility=0;
      if(($verbose>=3)&&($ah_last{$i}>=$meet_num)){
        print STDOUT "is already ah counter on "
      }elsif($verbose>=3){
        print STDOUT "was just ah counter on "
      };
      if($verbose>=3){print STDOUT "$short_date[$ah_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
#    }elsif($memberspeeches{$i}<2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
#    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just was toastmaster"};
#    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just spoke"};
#    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just table topics master"};
#    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just did inspiration"};
#    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just jokemaster"};
#    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($ah_last{$i} eq ''){$ah_last{i}=0};
#      $r=(2-$ah_desire{$i})*10000+$memberrank{$i}*1000+$ah_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$ah_desire{$i})*100000+$r*1000+$ah_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$ah_last{$i}\t$short_date[$ah_last{$i}]";
      if($verbose>=3){
        if($ah_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };

  if($verbose>=2){print STDOUT "\n$c candidates available for ah counter\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_ah eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_ah=$membername{$e[0]};
    $tw_duty{$e[0]}="Ah-Counter";
    $j+=1;
  };


};
#
################################################################################ Assign Timer
#
sub AssignTimer{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Timer for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($ti_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($ti_last{$i}>$meet_num-$since_timer){
      $possibility=0;
      if(($verbose>=3)&&($ti_last{$i}>=$meet_num)){
        print STDOUT "is already timer on "
      }elsif($verbose>=3){
        print STDOUT "was just timer on "
      };
      if($verbose>=3){print STDOUT "$short_date[$ti_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
#    }elsif($memberspeeches{$i}<2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "hasn't given 2 speeches yet"};
#    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just was toastmaster"};
#    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just spoke"};
#    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just table topics master"};
#    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just did inspiration"};
#    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just jokemaster"};
#    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($ti_last{$i} eq ''){$ti_last{i}=0};
#      $r=(2-$ti_desire{$i})*10000+$memberrank{$i}*1000+$ti_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$ti_desire{$i})*100000+$r*1000+$ti_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$ti_last{$i}\t$short_date[$ti_last{$i}]";
      if($verbose>=3){
        if($ti_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for timer\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_ti eq '')){
    @e=split(/\t/,$candidate[$j]);
    $tw_ti=$membername{$e[0]};
    $tw_duty{$e[0]}="Timer";
    $j+=1;
  };
};
#
################################################################################ Assign Evaluators
#
sub AssignEvaluators{
  my(@candidate,$i,$j,$possibility,$c,@sc,$r);
  if($verbose>=2){print STDOUT "\nAssigning Evaluators for date $date ($meet_num) ...\n"};
  $c=0;
  foreach $i(keys %membername){
    $possibility=1;
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "  $membername{$i}, $membertitle{$i} ";
      };
    };
    if($member_available{$i} ne ''){
      $possibility=0;
#      if($verbose>=3){print STDOUT "is not available"};
    }elsif($ev_desire{$i}==0){
      $possibility=0;
      if($verbose>=3){print STDOUT "doesn't want to"};
    }elsif($ev_last{$i}>$meet_num-$since_evaluator){
      $possibility=0;
      if(($verbose>=3)&&($ev_last{$i}>=$meet_num)){
        print STDOUT "is already an evaluator on "
      }elsif($verbose>=3){
        print STDOUT "was just an evaluator on "
      };
      if($verbose>=3){print STDOUT "$short_date[$ev_last{$i}]"};
    }elsif($tw_duty{$i} ne ''){
      $possibility=0;
      if($verbose>=3){print STDOUT "is already $tw_duty{$i}"};
#    }elsif($memberrank{$i}>2){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "is a DTM"};
    }elsif($memberspeeches{$i}<3){
      $possibility=0;
      if($verbose>=3){print STDOUT "hasn't given 3 speeches yet"};
#    }elsif(($tm_last{$i}==$meet_num-1)||($tm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just was toastmaster"};
#    }elsif(($sp_last{$i}==$meet_num-1)||($sp_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just spoke"};
#    }elsif(($tt_last{$i}==$meet_num-1)||($tt_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just table topics master"};
#    }elsif(($in_last{$i}==$meet_num-1)||($in_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "just did inspiration"};
#    }elsif(($jm_last{$i}==$meet_num-1)||($jm_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just jokemaster"};
#    }elsif(($gr_last{$i}==$meet_num-1)||($gr_last{$i}==$meet_num+1)){
#      $possibility=0;
#      if($verbose>=3){print STDOUT "was just grammarian"};
    };
    if($possibility){
      if($ev_last{$i} eq ''){$ev_last{i}=0};
#      $r=(2-$ev_desire{$i})*10000+$memberrank{$i}*1000+$ev_last{$i};
      $r=$memberspeeches{$i};
      if($r>10){$r=10};
# Seasoned TMs have priority over rookies
      if($r<10){$r=9-$r};

# Remove influence of number of speeches Feb 27, 2002
      $r=1;

      $r=(5-$ev_desire{$i})*100000+$r*1000+$ev_last{$i};
      $candidate[$c]="$i\t$membertitle{$i}\t$r\t$ev_last{$i}\t$short_date[$ev_last{$i}]";
      if($verbose>=3){
        if($ev_desire{$i}==1){
          print STDOUT "is a reluctant candidate ++++++++ ";
        }else{
          print STDOUT "is a candidate ************ ";
        };
      };
      $c+=1;
    };
    if($verbose>=3){
      if($member_available{$i} eq ''){
        print STDOUT "\n";
      };
    };
  };
  if($verbose>=2){print STDOUT "\n$c candidates available for evaluator\n"};
  @candidate=sort{(split(/\t/,$a))[2]<=>(split(/\t/,$b))[2]}@candidate;
  for($j=0;$j<$c;$j++){
    @e=split(/\t/,$candidate[$j]);
    if($verbose>=2){print STDOUT "  $membername{$e[0]}, $e[1], $e[2]\n"};
  };
  $j=0;
  if(($j<$c)&&($tw_e1 eq '')&&($tw_s1 ne '')&&($number_speakers>=1)){
    @e=split(/\t/,$candidate[$j]);
    $tw_e1=$membername{$e[0]};
    $tw_duty{$e[0]}="Evaluator 1";
    $j+=1;
  };
  if(($j<$c)&&($tw_e2 eq '')&&($tw_s2 ne '')&&($number_speakers>=2)){
    @e=split(/\t/,$candidate[$j]);
    $tw_e2=$membername{$e[0]};
    $tw_duty{$e[0]}="Evaluator 2";
    $j+=1;
  };
  if(($j<$c)&&($tw_e3 eq '')&&($tw_s3 ne '')&&($number_speakers>=3)){
    @e=split(/\t/,$candidate[$j]);
    $tw_e3=$membername{$e[0]};
    $tw_duty{$e[0]}="Evaluator 3";
    $j+=1;
  };
  if(($j<$c)&&($tw_e4 eq '')&&($tw_s4 ne '')&&($number_speakers>=4)){
    @e=split(/\t/,$candidate[$j]);
    $tw_e4=$membername{$e[0]};
    $tw_duty{$e[0]}="Evaluator 4";
    $j+=1;
  };
};
#
################################################################################ Load Roster
#
sub LoadRoster{
  my($file,$i,$j,@e,$s);
  $file=$docroot.'/'.$path.'/'.$roster;$file=~s/\/+/\//g;
  if($verbose>=4){print STDOUT "\nLoading names and titles from $file\n"};
  if($verbose>=4){print STDOUT "\n  Code, Name, Rank, Email Address, Number of Speeches\n\n"};
  if(open(F,$file)){
    $s=;chomp($s);
    @e=split(/\t/,$s);
    for($j=0;$j<=$#e;$j++){
      if($e[$j]=~/key/i){
        $key=$j;
      }elsif($e[$j]=~/^name/i){
        $name=$j;
      }elsif($e[$j]=~/title/i){
        $title=$j;
      }elsif($e[$j]=~/speech/i){
        $speeches=$j;
      }elsif($e[$j]=~/email/i){
        $email=$j;
      };
    };
    undef %membername,%memberkey,%membertitle,%memberrank;%memberemail;
    $i=0;
    while(!eof(F)){
      $s=;chomp($s);$i+=1;
      @e=split(/\t/,$s);
      $membername{$e[$key]}=$e[$name];
      $memberkey{$e[$name]}=$e[$key];
      $membertitle{$e[$key]}=$e[$title];
      $memberemail{$e[$key]}=$e[$email];
      if(lc(substr($e[$title],0,3)) eq 'dtm'){
        $memberrank{$e[$key]}=1;
        $memberspeeches{$e[$key]}=40;
      }elsif(lc(substr($e[$title],0,3)) eq 'atm'){
        $memberrank{$e[$key]}=1;
        $memberspeeches{$e[$key]}=25;
      }elsif(lc(substr($e[$title],0,3)) eq 'ctm'){
        $memberrank{$e[$key]}=1;
        $memberspeeches{$e[$key]}=10;
      }else{
        $memberrank{$e[$key]}=0;
        $memberspeeches{$e[$key]}=$e[$speeches];;
      };
      if($verbose>=4){
        print STDOUT "$i: $e[$key], $e[$name], $e[$title], $e[$email], ";
        print STDOUT "$memberspeeches{$e[$key]} speeches\n"
      };
    };
    close(F);
  }else{
    if($verbose>=2){print STDOUT "Can not open file $file\n"};
  };
};
#
################################################################################ Load Desires
#
sub LoadDesires{
  my($file,$i,$j,$s,@e,$tm,$in,$jm,$gr,$ah,$ti,$sp,$ev,$ge,$tt,$key);
  $file=$docroot.'/'.$path.'/'.$desires;$file=~s/\/+/\//g;
  if($verbose>=4){print STDOUT "\nLoading desires from $file\n"};
  if(open(F,$file)){
    $s=;chomp($s);
    @e=split(/\t/,$s);
    for($j=0;$j<=$#e;$j++){
      if($e[$j]=~/Toastmaster/i){
        $tm=$j;
      }elsif($e[$j]=~/Inspiration/i){
        $in=$j;
      }elsif($e[$j]=~/Jokemaster/i){
        $jm=$j;
      }elsif($e[$j]=~/Grammarian/i){
        $gr=$j;
      }elsif($e[$j]=~/Ah/i){
        $ah=$j;
      }elsif($e[$j]=~/Timer/i){
        $ti=$j;
      }elsif($e[$j]=~/Speaker/i){
        $sp=$j;
      }elsif($e[$j]=~/^Eval/i){
        $ev=$j;
      }elsif($e[$j]=~/Gen.*Eval/i){
        $ge=$j;
      }elsif($e[$j]=~/Table/i){
        $tt=$j;
      }elsif($e[$j]=~/Key/i){
        $key=$j;
      };
    };
    $i=0;
    while(!eof(F)){
      $s=;chomp($s);
      @e=split(/\t/,$s);
      $tm_desire{$e[$key]}=$e[$tm];
      $in_desire{$e[$key]}=$e[$in];
      $jm_desire{$e[$key]}=$e[$jm];
      $gr_desire{$e[$key]}=$e[$gr];
      $ah_desire{$e[$key]}=$e[$ah];
      $ti_desire{$e[$key]}=$e[$ti];
      $sp_desire{$e[$key]}=$e[$sp];
      $ev_desire{$e[$key]}=$e[$ev];
      $ge_desire{$e[$key]}=$e[$ge];
      $tt_desire{$e[$key]}=$e[$tt];
      $i+=1;
    };
    close(F);
    if($verbose>=4){
      print STDOUT "\n  How much each toastmaster DESIRES to fullfill each duty:\n";
      print STDOUT "  2-OK, 1-only as last resort, 0-Never\n\n";
      foreach $i(keys %membername){
        $j="$membername{$i}: ";
        $j=sprintf("%25.25s",$j);
        print STDOUT "$j ";
        print STDOUT "TM=$tm_desire{$i}, IN=$in_desire{$i}, JM=$jm_desire{$i}, ";
        print STDOUT "GR=$gr_desire{$i}, AH=$ah_desire{$i}, TI=$ti_desire{$i}, ";
        print STDOUT "SP=$sp_desire{$i}, TT=$tt_desire{$i}, GE=$ge_desire{$i}, EV=$ev_desire{$i}\n";
      };
    };
  }else{
    if($verbose>=2){print STDOUT "Can not open file $file\n"};
  };
};
#
################################################################################ Load Availability
#
sub LoadAvailability{
  my($file,$i,$j,@e,@t,$exit,$s,$key,$name);
  $file=$docroot.'/'.$path.'/'.$availability;$file=~s/\/+/\//g;
  if($verbose>=4){print STDOUT "\nLoading availability from $file\n"};
  if(open(F,$file)){
    $s=;chomp($s);
    @e=split(/\t/,$s);$exit=0;
    $j=0;
    while((!$exit)&&($j<=$#e)){
      if($e[$j]=~/key/i){
        $key=$j;
      }elsif($e[$j]=~/name/i){
        $name=$j;
      }elsif($e[$j]=~/$date/i){
        $d=$j;$exit=1;
      };
      $j+=1;
    };
    $i=0;
    if($verbose>=4){print STDOUT "\n  Which toastmasters are not available on $date:\n\n"};
    while(!eof(F)){
      $s=;chomp($s);$i+=1;
      @e=split(/\t/,$s);
      if($e[$d] eq ''){
        $a=$tm_desire{$e[$key]};
        $a+=$in_desire{$e[$key]};
        $a+=$jm_desire{$e[$key]};
        $a+=$gr_desire{$e[$key]};
        $a+=$ah_desire{$e[$key]};
        $a+=$ti_desire{$e[$key]};
        $a+=$sp_desire{$e[$key]};
        $a+=$ev_desire{$e[$key]};
        $a+=$ge_desire{$e[$key]};
        $a+=$tt_desire{$e[$key]};
        if($a==0){$e[$d]='0'};
      };
      $member_available{$e[$key]}=$e[$d];
      if($verbose>=4){
        if($e[$d] ne ''){
          print STDOUT "    $i: $e[$key], $e[$name]";
          if($e[$d] eq '0'){print STDOUT " has all desires set to 0"};
          print STDOUT "\n";
        };
      };
    };
    close(F);
  }else{
    if($verbose>=2){print STDOUT "Can not open file $file\n"};
  };
};
#
################################################################################ Load Schedule
#
sub LoadSchedule{
  my($file,$i,$j,$s,$m,@e,$tm,$in,$jm,$gr,$ah,$ti,$s1,$s2,$s3,$s4,$e1,$e2,$e3,$e4,$ge,$tt,$nam);
  $file=$docroot.'/'.$path.'/'.$schedule;$file=~s/\/+/\//g;
  if($verbose>=4){print STDOUT "\nLoading schedule from $file\n"};
  if(open(F,$file)){
    $i=0;$s=;chomp($s);
    @e=split(/\t/,$s);
    for($j=0;$j<=$#e;$j++){
      if($e[$j]=~/Toastmaster/i){
        $sf_tm=$j;
      }elsif($e[$j]=~/Inspiration/i){
        $sf_in=$j;
      }elsif($e[$j]=~/Jokemaster/i){
        $sf_jm=$j;
      }elsif($e[$j]=~/Grammarian/i){
        $sf_gr=$j;
      }elsif($e[$j]=~/Ah/i){
        $sf_ah=$j;
      }elsif($e[$j]=~/Timer/i){
        $sf_ti=$j;
      }elsif($e[$j]=~/Speaker.*1/i){
        $sf_s1=$j;
      }elsif($e[$j]=~/Speaker.*2/i){
        $sf_s2=$j;
      }elsif($e[$j]=~/Speaker.*3/i){
        $sf_s3=$j;
      }elsif($e[$j]=~/Speaker.*4/i){
        $sf_s4=$j;
      }elsif($e[$j]=~/Eval.*1/i){
        $sf_e1=$j;
      }elsif($e[$j]=~/Eval.*2/i){
        $sf_e2=$j;
      }elsif($e[$j]=~/Eval.*3/i){
        $sf_e3=$j;
      }elsif($e[$j]=~/Eval.*4/i){
        $sf_e4=$j;
      }elsif($e[$j]=~/Gen.*Eval/i){
        $sf_ge=$j;
      }elsif($e[$j]=~/Table/i){
        $sf_tt=$j;
      }elsif($e[$j]=~/ShortDate/i){
        $sf_sd=$j;
      }elsif($e[$j]=~/Meeting/i){
        $sf_me=$j;
      }elsif($e[$j]=~/Email/i){
        $sf_em=$j;
      };
    };
    $i=0;$exit=0;$m=1;
    while((!eof(F))&&($m!=0)){
      $s=;chomp($s);
      @e=split(/\t/,$s);
      $schedule_file{$e[$sf_me]}=$s;
      $short_date[$e[$sf_me]]=$e[$sf_sd];
      $meeting_number{$e[$sf_sd]}=$e[$sf_me];
      if(($datetype)&&($e[$sf_me]==$date)){
        $date=$e[$sf_sd];$datetype=0;
      };
      if($e[$sf_sd] eq $date){$m=-2};

		$e[$sf_tm]=&nameOnly($e[$sf_tm]);
		$e[$sf_in]=&nameOnly($e[$sf_in]);
		$e[$sf_jm]=&nameOnly($e[$sf_jm]);
		$e[$sf_gr]=&nameOnly($e[$sf_gr]);
		$e[$sf_ah]=&nameOnly($e[$sf_ah]);
		$e[$sf_ti]=&nameOnly($e[$sf_ti]);
		$e[$sf_s1]=&nameOnly($e[$sf_s1]);
		$e[$sf_s2]=&nameOnly($e[$sf_s2]);
		$e[$sf_s3]=&nameOnly($e[$sf_s3]);
		$e[$sf_s4]=&nameOnly($e[$sf_s4]);
		$e[$sf_e1]=&nameOnly($e[$sf_e1]);
		$e[$sf_e2]=&nameOnly($e[$sf_e2]);
		$e[$sf_e3]=&nameOnly($e[$sf_e3]);
		$e[$sf_e4]=&nameOnly($e[$sf_e4]);
		$e[$sf_ge]=&nameOnly($e[$sf_ge]);
		$e[$sf_tt]=&nameOnly($e[$sf_tt]);

	  $tm_last{$memberkey{$e[$sf_tm]}}=$e[$sf_me]; # last time the guy in the 'Toastmaster' column was tm was the date in the 'Meeting' column
      $in_last{$memberkey{$e[$sf_in]}}=$e[$sf_me];
      $jm_last{$memberkey{$e[$sf_jm]}}=$e[$sf_me];
      $gr_last{$memberkey{$e[$sf_gr]}}=$e[$sf_me];
      $ah_last{$memberkey{$e[$sf_ah]}}=$e[$sf_me];
      $ti_last{$memberkey{$e[$sf_ti]}}=$e[$sf_me];
      $sp_last{$memberkey{$e[$sf_s1]}}=$e[$sf_me]; $memberspeeches{$memberkey{$e[$sf_s1]}}+=1;
      $sp_last{$memberkey{$e[$sf_s2]}}=$e[$sf_me]; $memberspeeches{$memberkey{$e[$sf_s2]}}+=1;
      $sp_last{$memberkey{$e[$sf_s3]}}=$e[$sf_me]; $memberspeeches{$memberkey{$e[$sf_s3]}}+=1;
      $sp_last{$memberkey{$e[$sf_s4]}}=$e[$sf_me]; $memberspeeches{$memberkey{$e[$sf_s4]}}+=1;
      $ev_last{$memberkey{$e[$sf_e1]}}=$e[$sf_me];
      $ev_last{$memberkey{$e[$sf_e2]}}=$e[$sf_me];
      $ev_last{$memberkey{$e[$sf_e3]}}=$e[$sf_me];
      $ev_last{$memberkey{$e[$sf_e4]}}=$e[$sf_me];
      $ge_last{$memberkey{$e[$sf_ge]}}=$e[$sf_me];
      $tt_last{$memberkey{$e[$sf_tt]}}=$e[$sf_me];
      $i+=1;$m+=1;
    };
    if($verbose>=4){print STDOUT "\n  Last date input: $e[$sf_sd]\n"};
    close(F);
    if($verbose>=4){
#      print STDOUT "\n";
      print STDOUT "\n  How long ago each toastmaster fullfilled each duty:\n\n";
      foreach $i(keys %membername){
        $j="$membername{$i}: ";
        $j=sprintf("%23.23s",$j);
        print STDOUT "$j";
        print STDOUT "TM=$short_date[$tm_last{$i}]";
        print STDOUT " IN=$short_date[$in_last{$i}]";
        print STDOUT " JM=$short_date[$jm_last{$i}]";
        print STDOUT " GR=$short_date[$gr_last{$i}]";
        print STDOUT " AH=$short_date[$ah_last{$i}]";
        print STDOUT "\n                       ";
        print STDOUT "TI=$short_date[$ti_last{$i}]";
        print STDOUT " SP=$short_date[$sp_last{$i}]";
        print STDOUT " TT=$short_date[$tt_last{$i}]";
        print STDOUT " GE=$short_date[$ge_last{$i}]";
        print STDOUT " EV=$short_date[$ev_last{$i}]";
        print STDOUT " #S=$memberspeeches{$i}";
        print STDOUT "\n";
      };
    };
  }else{
    if($verbose>=2){print STDOUT "Can not open file $file\n"};
  };
};

sub nameOnly{
	my($nam)=$_[0];
	$nam.='(';
	$nam=substr($nam,0,index($nam,'('));
	$nam=&trim($nam);
	return($nam);
};
	sub trim{
		my($ret)=$_[0];
		while(($ret ne '')&&($ret=~/^[\s]/)){$ret=substr($ret,1)};
		while(($ret ne '')&&($ret=~/[\s]$/)){chop($ret)};
		return($ret);
	};

  sub UpdateScheduleFile{
#    my($date,$meet_num,$tw_tm,$tw_em,$tw_in,$tw_jm,$tw_gr,$tw_ah,$tw_ti,$tw_s1,$tw_s2,$tw_s3,$tw_s4,
#       $tw_e1,$tw_e2,$tw_e3,$tw_e4,$tw_ge,$tw_tt)=@_;
    my($file,$changed,$rec,@columns,$scheduletitle,$col,%COL,@schedulerecord,$i,$startemail,$j,$subj);
	my($lastDate);
    $file=$docroot.'/'.$path.'/'.$schedule;$file=~s/\/+/\//g;
    if($verbose>=4){print STDOUT "\nLoading schedule for update from $file\n"};
    $changed=0; $startemail=0;
    if(open(F,$file)){
      $rec=; chomp($rec);
	  $scheduletitle=$rec;
      @columns=split(/\t/,$rec);
      for($c=0;$c<=$#columns;$c++){
        $col=$columns[$c];
        if(index($col,'#')>0){$col=substr($col,0,index($col,'#'))};
        $COL{$col}=$c
      };
      do{
        $rec=; chomp($rec);
        if($rec ne ''){
          undef @columns; @columns=split(/\t/,$rec);
		  if($columns[$COL{'Location'}] ne ''){$lastlocation=$columns[$COL{'Location'}]};
		  if($columns[$COL{'Presiding Officer'}] ne ''){$lastpo=$columns[$COL{'Presiding Officer'}]};

		  if($columns[$COL{'Meeting'}]>$maxMeeting){$maxMeeting=$columns[$COL{'Meeting'}]};

		  if(exists $futureWednesdaysIndex{$columns[$COL{ShortDate}]}){$futureWednesdaysPresent[$futureWednesdaysIndex{$columns[$COL{ShortDate}]}]=1};

		  if($columns[$COL{ShortDate}] eq $date){
		    $columns[$COL{'Assigned'}]='1';
		    if($columns[$COL{'Location'}] eq ''){$columns[$COL{'Location'}]=$lastlocation};
		    if($columns[$COL{'Presiding Officer'}] eq ''){$columns[$COL{'Presiding Officer'}]=$lastpo};
            if($columns[$COL{Meeting}] eq ''){$columns[$COL{Meeting}]=$meet_num; $changed+=1};
            if($columns[$COL{Toastmaster}] eq ''){$columns[$COL{Toastmaster}]=$tw_tm; $changed+=1};
            if($columns[$COL{Email}] eq ''){$columns[$COL{Email}]=$tw_em; $changed+=1};
            if($columns[$COL{Inspiration}] eq ''){$columns[$COL{Inspiration}]=$tw_in; $changed+=1};
            if($columns[$COL{Jokemaster}] eq ''){$columns[$COL{Jokemaster}]=$tw_jm; $changed+=1};
            if($columns[$COL{Grammarian}] eq ''){$columns[$COL{Grammarian}]=$tw_gr; $changed+=1};
            if($columns[$COL{'Ah-Counter'}] eq ''){$columns[$COL{'Ah-Counter'}]=$tw_ah; $changed+=1};
            if($columns[$COL{Timer}] eq ''){$columns[$COL{Timer}]=$tw_ti; $changed+=1};
            if($columns[$COL{'Speaker 1'}] eq ''){$columns[$COL{'Speaker 1'}]=$tw_s1; $changed+=1};
            if($columns[$COL{'Speaker 2'}] eq ''){$columns[$COL{'Speaker 2'}]=$tw_s2; $changed+=1};
            if($columns[$COL{'Speaker 3'}] eq ''){$columns[$COL{'Speaker 3'}]=$tw_s3; $changed+=1};
#           if($columns[$COL{'Speaker 4'}] eq ''){$columns[$COL{'Speaker 4'}]=$tw_s4; $changed+=1};
            if($columns[$COL{'Evaluator 1'}] eq ''){$columns[$COL{'Evaluator 1'}]=$tw_e1; $changed+=1};
            if($columns[$COL{'Evaluator 2'}] eq ''){$columns[$COL{'Evaluator 2'}]=$tw_e2; $changed+=1};
            if($columns[$COL{'Evaluator 3'}] eq ''){$columns[$COL{'Evaluator 3'}]=$tw_e3; $changed+=1};
#           if($columns[$COL{'Evaluator 4'}] eq ''){$columns[$COL{'Evaluator 4'}]=$tw_e4; $changed+=1};
            if($columns[$COL{'General Evaluator'}] eq ''){$columns[$COL{'General Evaluator'}]=$tw_ge; $changed+=1};
            if($columns[$COL{'Table Topics Master'}] eq ''){$columns[$COL{'Table Topics Master'}]=$tw_tt; $changed+=1};

			if($verbose>=4){
			  foreach $var (keys %COL) {
				print STDOUT "$var=$columns[$COL{$var}]\n";
			  };
			};

			$rec=join("\t",@columns);
		  };

		  push @schedulerecord,$rec;

# if($verbose>=4){print STDOUT "$columns[$COL{ShortDate}] eq $thiswednesday\n";};

			if((($startemail>0)&&($startemail<=$weeksahead))
			||($columns[$COL{ShortDate}] eq $thiswednesday)
			||($columns[$COL{ShortDate}] eq $nextwednesday)
			||($columns[$COL{ShortDate}] eq $next2wednesday)
			){
				if($columns[$COL{'Assigned'}]==1){$recordemail[$startemail++]=$rec};
			};
		};
	  }until(eof(F));
	  close(F);
    };

	if($debug==0){
		if(open(F,">$cronupdate")){
		  print F "default form value input = \$template = members.tpl.html#abase.html#agenda.html\n";
		  print F "default form value input = AgendaDate = $date\n";
		  close(F);
		};
	};
	

	if($changed>0){
		if($debug==1){$file.='TEST'};
		if(open(F,">$file")){
			print F "$scheduletitle\n";
			for($i=0;$i<=$#schedulerecord;$i++){
				print F "$schedulerecord[$i]\n";
			};
			$i=$scheduleAhead;
			while($i>=0 && $futureWednesdaysPresent[$i]==0){$i-=1};
			if($i>=0 && $i<$scheduleAhead){
				for($j=$i+1;$j<=$scheduleAhead;$j++){
					$sMon=substr($futureWednesdaysRecord[$j],4,2);
					$sDay=substr($futureWednesdaysRecord[$j],6,2);
					$sAdd=1;
					if($sMon==1 && $sDay<=8){$sAdd=0};
					if($sMon==12 && $sDay>=18){$sAdd=0};
					if($sMon==7 && $sDay==4){$sAdd=0};
					if($sAdd==1){
						$maxMeeting+=1;
						print F "$futureWednesdaysRecord[$j]\t$maxMeeting\t\t\t\n";
					};
				};
			};
			close(F);
		};
		if($startemail>0){
			$emailtext='';$txt='';
			$emailtext.="DBA Toastmasters Schedule $thiswednesday through $date\n";
			for($i=0;$i<$startemail;$i++){
				undef @columns; @columns=split(/\t/,$recordemail[$i]);

				$txt="DBA Toastmasters Schedule $columns[$COL{'Date'}]\n";
				$txt.="$columns[$COL{'Location'}]\n";
				$txt.="PO: $columns[$COL{'Presiding Officer'}]\n";
				$txt.="TM: $columns[$COL{'Toastmaster'}], In: $columns[$COL{'Inspiration'}]\n";
				$txt.="JM: $columns[$COL{'Jokemaster'}], Gr: $columns[$COL{'Grammarian'}]\n";
				$txt.="WD: $columns[$COL{'Ah-Counter'}], Tm: $columns[$COL{'Timer'}]\n";
				$txt.="S1: $columns[$COL{'Speaker 1'}], E1: $columns[$COL{'Evaluator 1'}]\n";
				$txt.="S2: $columns[$COL{'Speaker 2'}], E2: $columns[$COL{'Evaluator 2'}]\n";
				$txt.="S3: $columns[$COL{'Speaker 3'}], E3: $columns[$COL{'Evaluator 3'}]\n";
				if($columns[$COL{'Speaker 4'}] ne '' || $columns[$COL{'Evaluator 4'}] ne ''){
					$txt.="S4: $columns[$COL{'Speaker 4'}], E4: $columns[$COL{'Evaluator 4'}]\n";
				};
				$txt.="TT: $columns[$COL{'Table Topics Master'}], GE: $columns[$COL{'General Evaluator'}]\n";

				for($j=0;$j<=$#columns;$j++){if($columns[$j] eq ''){$columns[$j]='____________'}};
				$emailtext.="\n";
				$emailtext.=" -$columns[$COL{'Date'}]-----\n";
				$emailtext.=" Location: $columns[$COL{'Location'}]\n";
				$emailtext.=" Presiding Officer: $columns[$COL{'Presiding Officer'}]\n";
				$emailtext.=" Toastmaster: $columns[$COL{'Toastmaster'}], Inspiration: $columns[$COL{'Inspiration'}]\n";
				$emailtext.=" Jokemaster: $columns[$COL{'Jokemaster'}], Grammarian: $columns[$COL{'Grammarian'}]\n";
				$emailtext.=" Word of Day: $columns[$COL{'Ah-Counter'}], Timer: $columns[$COL{'Timer'}]\n";
				$emailtext.=" Speaker 1: $columns[$COL{'Speaker 1'}], Evaluator 1: $columns[$COL{'Evaluator 1'}]\n";
				$emailtext.=" Speaker 2: $columns[$COL{'Speaker 2'}], Evaluator 2: $columns[$COL{'Evaluator 2'}]\n";
				$emailtext.=" Speaker 3: $columns[$COL{'Speaker 3'}], Evaluator 3: $columns[$COL{'Evaluator 3'}]\n";
				$emailtext.=" Speaker 4: $columns[$COL{'Speaker 4'}], Evaluator 4: $columns[$COL{'Evaluator 4'}]\n";
				$emailtext.=" Table Topics Master: $columns[$COL{'Table Topics Master'}]\n";
				$emailtext.=" General Evaluator: $columns[$COL{'General Evaluator'}]\n";
			};
			$emailtext.="\nThis schedule was generated automatically by a program that runs\n";
			$emailtext.="each week at this time. Make sure your Desires and Availability \n";
			$emailtext.="tables are up-to-date at least $weeksahead weeks and ".&DaysToWednesday." days in advance,\n";
			$emailtext.="so you are not scheduled for a duty you can not fulfill. Note\n";
			$emailtext.="that you must have completed at least 3 speeches to be assigned\n";
			$emailtext.="Toastmaster. You can update your number of speeches from the\n";
			$emailtext.="'Update my data record' menu selection on the website.\n";
			$emailtext.="\nhttp://www.dbatoastmasters.com\n\n";
#			$subj='DBA Toastmasters 3 Week Schedule';
			$subj="DBA Toastmasters Schedule $thiswednesday through $date";
			if($debug==0){
				&SendEmail($ToEmail,$subj,$emailtext,$txt);
			}else{
				&SendEmail('richhalverson@gmail.com',$subj,$emailtext,$txt);
			};
		};
	};
  };
#	yeardaytime	ShortDate	Date	Meeting	Assigned	Location	Toastmaster#text
#	Inspiration#text	Jokemaster#text	Grammarian#text	Table Topics Master#text
#	Speaker 1#text	Speaker 2#text	Speaker 3#text	Speaker 4#text	General Evaluator#text	
#	Ah-Counter#text	Timer#text	Evaluator 1#text	Evaluator 2#text	Evaluator 3#text	Evaluator 4#text
#	Email	Presiding Officer	Presiders Title
#	Theme#text	Number 1	Title 1	Number 2	Title 2	Number 3	Title 3	Number 4	Title 4

# -September 27, 2000-----------------------------------------------------
#  Location: University Health Alliance - AMFAC Tower, Ste. 300
#  Presiding Officer: ,
#  Toastmaster: Rich Sullivan, Inspiration: Lori Kaizawa
#  Jokemaster: Harvey Rackmil, Grammarian: David Oberheu
#  Ah-Counter: Katherine Tugman, Timer:
#  Speaker 1: Gary Nakatsuka, Evaluator 1: James Donnelly
#  Speaker 2: Kat McDivitt, Evaluator 2: Otto Mazenauer
#  Speaker 3: Pete Cooper, Evaluator 3: Tom Yamachika
#  Speaker 4:________________, Evaluator 4:________________
#  Table Topics Master: John Ellis
#  General Evaluator: Laura Stone-Jeraj


  sub NextWednesday{
    my($weeksahead)=$_[0];
	my($wedtime,$sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst,@months,$todaynow,$date);
	@months=('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	$wedtime=time;
	($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
	while($wday!=3){
	  $wedtime+=86400;
	  ($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
	};
	while($weeksahead>0){$wedtime+=86400*7;$weeksahead-=1};
	($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
	$year=1900+$year;
    if($year<1950){$year+=100};
	$date=$day.'-'.$months[$mo].'-'.substr($year,-2,2);
	$date
  };

	sub NextWednesdayArray{
		my($weeksahead)=$_[0];
		my($wedtime,$sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst,@months,$todaynow,$intDate,$shortDate,$longDate,$ret);
		@months=('January','February','March','April','May','June','July','August','September','October','November','December');
		$wedtime=time;
		($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
		while($wday!=3){
			$wedtime+=86400;
			($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
		};
		while($weeksahead>0){$wedtime+=86400*7;$weeksahead-=1};
		($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
		$year=1900+$year;
		if($year<1950){$year+=100};
		$shortDate=$day.'-'.substr($months[$mo],0,3).'-'.substr($year,-2,2);
		$longDate=$months[$mo].' '.$day.', '.$year;
		$intDate=$year.substr(100+$mo+1,-2,2).substr(100+$day,-2,2).'235900';
		$ret="$intDate\t$shortDate\t$longDate";
		$ret
	};



  sub DaysToWednesday{
	my($wedtime,$sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst,@months,$todaynow,$date,$i);
	$i=0;
	$wedtime=time;
	($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
	while($wday!=3){
	  $i+=1;
	  $wedtime+=86400;
	  ($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime($wedtime);
	};
	$i
  };



  sub Now{
    ($sec,$min,$hour,$day,$mo,$year,$wday,$doy,$isdst)=localtime(time);
    $year=1900+$year;
    if($year<1950){$year+=100};
    if($sec<10){$sec="0$sec"};
    if($min<10){$min="0$min"};
    if($day<10){$day="0$day"};
    if($hour<10){$hour="0$hour"};
    $dow=$days[$wday];
    $mo=$mo+1;
    if($mo<10){$mo="0$mo"};
    $todaynow="$year$mo$day$hour$min$sec";
    $todaynow
  };

  sub SendEmail{
    my($email,$subj,$msg,$txt)=@_;
    if(open(DEFOUT,$outfile)){
      print DEFOUT "Reply-To: $vpEdEmail\n";
      print DEFOUT "To: $email\n";
      print DEFOUT "From: $vpEdEmail\n";
      print DEFOUT "Bcc: richhalverson\@gmail.com\n";
      print DEFOUT "Subject: $subj\n\n";
      print DEFOUT "$msg";
      close(DEFOUT);
    };

    if(open(LE,'>'.$lastEmail)){
      print LE "$msg";
      close(LE);
    };


#   if(open(DEFOUT2,$outfile)){
#      print DEFOUT2 "To: 8083717424\@text.att.net\n\n$subj Generated.";
#      close(DEFOUT2);
#    };

  };

exit;