--- loncom/interface/lonhelper.pm	2003/10/09 15:27:14	1.56
+++ loncom/interface/lonhelper.pm	2003/10/14 18:32:15	1.60
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # .helper XML handler to implement the LON-CAPA helper
 #
-# $Id: lonhelper.pm,v 1.56 2003/10/09 15:27:14 sakharuk Exp $
+# $Id: lonhelper.pm,v 1.60 2003/10/14 18:32:15 bowersj2 Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -172,12 +172,20 @@ before parsing XML fragments and B<Apach
 when you are done. See lonprintout.pm for examples of this usage in the
 printHelper subroutine.
 
+=head2 Localization
+
+The helper framework tries to handle as much localization as
+possible. The text is always run through
+Apache::lonlocal::normalize_string, so be sure to run the keys through
+that function for maximum usefulness and robustness.
+
 =cut
 
 package Apache::lonhelper;
 use Apache::Constants qw(:common);
 use Apache::File;
 use Apache::lonxml;
+use Apache::lonlocal;
 
 # Register all the tags with the helper, so the helper can 
 # push and pop them
@@ -257,9 +265,9 @@ sub real_handler {
     # Send header, don't cache this page
     if ($r->header_only) {
         if ($ENV{'browser.mathml'}) {
-            $r->content_type('text/xml');
+            $r->content_type('text/xml; charset=UTF-8');
         } else {
-            $r->content_type('text/html');
+            $r->content_type('text/html; charset=UTF-8');
         }
         $r->send_http_header;
         return OK;
@@ -359,9 +367,10 @@ sub end_state {
 package Apache::lonhelper::helper;
 
 use Digest::MD5 qw(md5_hex);
-use HTML::Entities;
+use HTML::Entities();
 use Apache::loncommon;
 use Apache::File;
+use Apache::lonlocal;
 
 sub new {
     my $proto = shift;
@@ -523,7 +532,7 @@ sub process {
     # Phase 1: Post processing for state of previous screen (which is actually
     # the "current state" in terms of the helper variables), if it wasn't the 
     # beginning state.
-    if ($self->{STATE} ne "START" || $ENV{"form.SUBMIT"} eq "Next ->") {
+    if ($self->{STATE} ne "START" || $ENV{"form.SUBMIT"} eq &mt("Next ->")) {
 	my $prevState = $self->{STATES}{$self->{STATE}};
         $prevState->postprocess();
     }
@@ -574,13 +583,19 @@ sub display {
     }
 
     # Phase 4: Display.
-    my $stateTitle = $state->title();
-    my $bodytag = &Apache::loncommon::bodytag("$self->{TITLE}",'','');
+    my $stateTitle = &mt($state->title());
+    my $helperTitle = &mt($self->{TITLE});
+    my $bodytag = &Apache::loncommon::bodytag($helperTitle,'','');
+    my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');
+    my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');
+    # FIXME: This should be parameterized, not concatenated - Jeremy
+    my $loncapaHelper = &mt("LON-CAPA Helper:");
 
     $result .= <<HEADER;
 <html>
     <head>
-        <title>LON-CAPA Helper: $self->{TITLE}</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+        <title>$loncapaHelper: $helperTitle</title>
     </head>
     $bodytag
 HEADER
@@ -607,12 +622,12 @@ HEADER
         }
         if ($self->{DONE}) {
             my $returnPage = $self->{RETURN_PAGE};
-            $result .= "<a href=\"$returnPage\">End Helper</a>";
+            $result .= "<a href=\"$returnPage\">" . &mt("End Helper") . "</a>";
         }
         else {
             $result .= '<nobr><input name="back" type="button" ';
-            $result .= 'value="&lt;- Previous" onclick="history.go(-1)" /> ';
-            $result .= '<input name="SUBMIT" type="submit" value="Next -&gt;" /></nobr>';
+            $result .= 'value="' . $previous . '" onclick="history.go(-1)" /> ';
+            $result .= '<input name="SUBMIT" type="submit" value="' . $next . '" /></nobr>';
         }
     }
 
@@ -626,12 +641,12 @@ HEADER
         }
         if ($self->{DONE}) {
             my $returnPage = $self->{RETURN_PAGE};
-            $result .= "<a href=\"$returnPage\">End Helper</a>";
+            $result .= "<a href=\"$returnPage\">" . &mt('End Helper') . "</a>";
         }
         else {
             $result .= '<nobr><input name="back" type="button" ';
-            $result .= 'value="&lt;- Previous" onclick="history.go(-1)" /> ';
-            $result .= '<input name="SUBMIT" type="submit" value="Next -&gt;" /></nobr>';
+            $result .= 'value="' . $previous . '" onclick="history.go(-1)" /> ';
+            $result .= '<input name="SUBMIT" type="submit" value="' . $next . '" /></nobr>';
         }
     }
 
@@ -883,6 +898,7 @@ sub start_defaultvalue {
 
 sub end_defaultvalue { return ''; }
 
+# Validators may need to take language specifications
 sub start_validator {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
 
@@ -952,11 +968,17 @@ within each other.)
 This is also a good template for creating your own new states, as it has
 very little code beyond the state template.
 
+=head3 Localization
+
+The contents of the message tag will be run through the
+normalize_string function and that will be used as a call to &mt.
+
 =cut
 
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
+use Apache::lonlocal;
 
 BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::message',
@@ -998,7 +1020,7 @@ sub end_message {
 sub render {
     my $self = shift;
 
-    return $self->{MESSAGE_TEXT};
+    return &mtn($self->{MESSAGE_TEXT});
 }
 # If a NEXTSTATE was given, switch to it
 sub postprocess {
@@ -1100,6 +1122,7 @@ tag is stored in the {VARS} hash.
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
+use Apache::lonlocal;
 
 BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::choices',
@@ -1253,7 +1276,7 @@ BUTTONS
             $choiceLabel = eval($choiceLabel);
             $choiceLabel = &$choiceLabel($helper, $self);
         }
-        $result .= "/></td><td> " . $choiceLabel . "</td></tr>\n";
+        $result .= "/></td><td> " . &mtn($choiceLabel) . "</td></tr>\n";
     }
     $result .= "</table>\n\n\n";
     $result .= $buttons;
@@ -1268,8 +1291,8 @@ sub postprocess {
     my $chosenValue = $ENV{'form.' . $self->{'variable'} . '.forminput'};
 
     if (!defined($chosenValue) && !$self->{'allowempty'}) {
-        $self->{ERROR_MSG} = "You must choose one or more choices to" .
-            " continue.";
+        $self->{ERROR_MSG} = 
+	    &mt("You must choose one or more choices to continue.");
         return 0;
     }
 
@@ -1312,9 +1335,13 @@ the result is stored in.
 
 =cut
 
+# This really ought to be a sibling class to "choice" which is itself
+# a child of some abstract class.... *shrug*
+
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
+use Apache::lonlocal;
 
 BEGIN {
     &Apache::lonhelper::register('Apache::lonhelper::dropdown',
@@ -1404,7 +1431,7 @@ sub render {
             $choiceLabel = eval($choiceLabel);
             $choiceLabel = &$choiceLabel($helper, $self);
         }
-        $result .= ">" . $choiceLabel . "\n";
+        $result .= ">" . &mtn($choiceLabel) . "\n";
     }
     $result .= "</select>\n";
 
@@ -1473,6 +1500,7 @@ Example:
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
+use Apache::lonlocal; # A localization nightmare
 
 use Time::localtime;
 
@@ -1537,7 +1565,7 @@ sub render {
         } else {
             $result .= "<option value='$i'>";
         }
-        $result .= $months[$i] . "</option>\n";
+        $result .= &mt($months[$i]) . "</option>\n";
     }
     $result .= "</select>\n";
 
@@ -1567,25 +1595,28 @@ sub render {
 
     # Display Hours and Minutes if they are called for
     if ($self->{'hoursminutes'}) {
+	# This needs parameterization for times.
+	my $am = &mt('a.m.');
+	my $pm = &mt('p.m.');
         # Build hour
         $result .= "<select name='${var}hour'>\n";
         $result .= "<option " . ($date->hour == 0 ? 'selected ':'') .
-            " value='0'>midnight</option>\n";
+            " value='0'>" . &mt('midnight') . "</option>\n";
         for ($i = 1; $i < 12; $i++) {
             if ($date->hour == $i) {
-                $result .= "<option selected value='$i'>$i a.m.</option>\n";
+                $result .= "<option selected value='$i'>$i $am</option>\n";
             } else {
-                $result .= "<option value='$i'>$i a.m</option>\n";
+                $result .= "<option value='$i'>$i $am</option>\n";
             }
         }
         $result .= "<option " . ($date->hour == 12 ? 'selected ':'') .
-            " value='12'>noon</option>\n";
+            " value='12'>" . &mt('noon') . "</option>\n";
         for ($i = 13; $i < 24; $i++) {
             my $printedHour = $i - 12;
             if ($date->hour == $i) {
-                $result .= "<option selected value='$i'>$printedHour p.m.</option>\n";
+                $result .= "<option selected value='$i'>$printedHour $pm</option>\n";
             } else {
-                $result .= "<option value='$i'>$printedHour p.m.</option>\n";
+                $result .= "<option value='$i'>$printedHour $pm</option>\n";
             }
         }
 
@@ -1624,17 +1655,26 @@ sub postprocess {
         $hour = $ENV{'form.' . $var . 'hour'};
     }
 
-    my $chosenDate = Time::Local::timelocal(0, $min, $hour, $day, $month, $year);
+    my $chosenDate;
+    eval {$chosenDate = Time::Local::timelocal(0, $min, $hour, $day, $month, $year);};
+    my $error = $@;
+
     # Check to make sure that the date was not automatically co-erced into a 
     # valid date, as we want to flag that as an error
     # This happens for "Feb. 31", for instance, which is coerced to March 2 or
-    # 3, depending on if it's a leapyear
+    # 3, depending on if it's a leap year
     my $checkDate = localtime($chosenDate);
 
-    if ($checkDate->mon != $month || $checkDate->mday != $day ||
+    if ($error || $checkDate->mon != $month || $checkDate->mday != $day ||
         $checkDate->year + 1900 != $year) {
+	unless (Apache::lonlocal::current_language()== ~/^en/) {
+	    $self->{ERROR_MSG} = &mt("Invalid date entry");
+	    return 0;
+	}
+	# LOCALIZATION FIXME: Needs to be parameterized
         $self->{ERROR_MSG} = "Can't use " . $months[$month] . " $day, $year as a "
             . "date because it doesn't exist. Please enter a valid date.";
+
         return 0;
     }
 
@@ -1987,7 +2027,7 @@ shown. Defaults to false.
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
-
+use Apache::lonlocal;
 
 
 BEGIN {
@@ -2061,16 +2101,17 @@ sub render {
     }
 </script>
 SCRIPT
+
+        my $selectAllStudents = &mt('Select All Students'); 
+	my $unselectAllStudents = &mt('Unselect All Students');
         $buttons = <<BUTTONS;
 <br />
 <input type="button" onclick="checkactive()" value="Select Only Current Students" />
-<input type="button" onclick="checkall(true, '$var')" value="Select All Students" />
-<input type="button" onclick="checkall(false, '$var')" value="Unselect All Students" />
-<br />
+<input type="button" onclick="checkall(true, '$var')" value="$selectAllStudents" />
+<input type="button" onclick="checkall(false, '$var')" value="$unselectAllStudents" />
 <input type="button" onclick="checksec(true)" value="Select for Section/Group">
 <input type="text" size="5" name="chksec">&nbsp;
 <input type="button" onclick="checksec(false)" value="Unselect for Section/Group">
-
 <br />
 BUTTONS
     }
@@ -2129,14 +2170,14 @@ BUTTONS
 	}
     }
 
-    my $name = $self->{'coursepersonnel'} ? 'Name' : 'Student Name';
+    my $name = &mt($self->{'coursepersonnel'} ? 'Name' : 'Student Name');
     my $type = 'radio';
     if ($self->{'multichoice'}) { $type = 'checkbox'; }
     $result .= "<table cellspacing='2' cellpadding='2' border='0'>\n";
     $result .= "<tr><td></td><td align='center'><b>$name</b></td>".
-        "<td align='center'><b>Section</b></td>" . 
+        "<td align='center'><b>" . &mt('Section') . "</b></td>" . 
 	"<td align='center'><b>Status</b></td>" . 
-	"<td align='center'><b>Role</b></td>" .
+	"<td align='center'><b>" . &mt("Role") . "</b></td></tr>" .
 	"<td align='center'><b>Username:Domain</b></td></tr>";
 
     my $checked = 0;
@@ -2174,8 +2215,8 @@ sub postprocess {
 
     my $result = $ENV{'form.' . $self->{'variable'} . '.forminput'};
     if (!$result) {
-        $self->{ERROR_MSG} = 'You must choose at least one student '.
-            'to continue.';
+        $self->{ERROR_MSG} = 
+	    &mt('You must choose at least one student to continue.');
         return 0;
     }
 
@@ -2241,6 +2282,7 @@ viewing the files.
 no strict;
 @ISA = ("Apache::lonhelper::element");
 use strict;
+use Apache::lonlocal;
 
 use Apache::lonpubdir; # for getTitleString
 
@@ -2359,16 +2401,20 @@ sub render {
     }
 </script>
 SCRIPT
+        my $selectAllFiles = &mt("Select All Files");
+	my $unselectAllFiles = &mt("Unselect All Files");
         $buttons = <<BUTTONS;
 <br /> &nbsp;
-<input type="button" onclick="checkall(true, '$var')" value="Select All Files" />
-<input type="button" onclick="checkall(false, '$var')" value="Unselect All Files" />
+<input type="button" onclick="checkall(true, '$var')" value="$selectAllFiles" />
+<input type="button" onclick="checkall(false, '$var')" value="$unselectAllFiles" />
 BUTTONS
 
+        my $selectAllPublished = &mt("Select All Published");
+	my $unselectAllPublished= &mt("UnselectAllPublished");
         if ($helper->{VARS}->{'construction'}) {
             $buttons .= <<BUTTONS;
-<input type="button" onclick="checkallclass(true, 'Published')" value="Select All Published" />
-<input type="button" onclick="checkallclass(false, 'Published')" value="Unselect All Published" />
+<input type="button" onclick="checkallclass(true, 'Published')" value="$selectAllPublished" />
+<input type="button" onclick="checkallclass(false, 'Published')" value="$unselectAllPublished" />
 <br /> &nbsp;
 BUTTONS
        }
@@ -2944,7 +2990,8 @@ sub render {
 	}
 	
 	if (!@results) {
-	    $result .= '    <li>No changes were made to current settings.</li>';
+	    $result .= '    <li>' . 
+		&mt('No changes were made to current settings.') . '</li>';
 	}
 	
 	$result .= '</ul>';
@@ -2955,13 +3002,16 @@ sub render {
 	if ($ENV{'course.'.$ENV{'request.course.id'}.'.clonedfrom'}) {
 	    $targetURL = '/adm/parmset?overview=1';
 	}
+	my $previous = HTML::Entities::encode(&mt("<- Previous"), '<>&"');
+	my $next = HTML::Entities::encode(&mt("Next ->"), '<>&"');
         $result .= "<center>\n" .
             "<form action='/adm/roles' method='post' target='loncapaclient'>\n" .
-            "<input type='button' onclick='history.go(-1)' value='&lt;- Previous' />" .
+            "<input type='button' onclick='history.go(-1)' value='$previous' />" .
             "<input type='hidden' name='orgurl' value='$targetURL' />" .
             "<input type='hidden' name='selectrole' value='1' />\n" .
             "<input type='hidden' name='" . $ENV{'request.role'} . 
-            "' value='1' />\n<input type='submit' value='Finish Course Initialization' />\n" .
+            "' value='1' />\n<input type='submit' value='" .
+	    &mt('Finish Course Initialization') . " />\n" .
             "</form></center>";
     }