--- loncom/homework/radiobuttonresponse.pm	2012/01/20 11:41:31	1.153.6.1
+++ loncom/homework/radiobuttonresponse.pm	2012/01/25 12:00:33	1.153.6.7
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # mutliple choice style responses
 #
-# $Id: radiobuttonresponse.pm,v 1.153.6.1 2012/01/20 11:41:31 foxr Exp $
+# $Id: radiobuttonresponse.pm,v 1.153.6.7 2012/01/25 12:00:33 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -31,8 +31,12 @@ use HTML::Entities();
 use Apache::lonlocal;
 use Apache::lonnet;
 use Apache::response;
+use Apache::caparesponse;
 
 my $default_bubbles_per_line = 10;
+my @alphabet      = ( 'A' .. 'Z' ); # Foil labels.
+
+
 
 BEGIN {
     &Apache::lonxml::register( 'Apache::radiobuttonresponse',
@@ -118,14 +122,7 @@ sub start_radiobuttonresponse {
         else {
             $result .= ' \renewcommand{\labelenumi}{\Alph{enumi}.}';
         }
-        if (   $env{'form.pdfFormFields'} eq 'yes'
-            && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
-        {
-            $result .= '\begin{itemize}';
-        }
-        else {
-            $result .= '\begin{enumerate}';
-        }
+
     }
     elsif ( $target eq 'analyze' ) {
         my $part_id = "$Apache::inputtags::part.$id";
@@ -140,16 +137,7 @@ sub end_radiobuttonresponse {
       @_;
     my $result;
     if ( $target eq 'edit' ) { $result = &Apache::edit::end_table(); }
-    if ( $target eq 'tex' ) {
-        if (    $env{'form.pdfFormFields'} eq 'yes'
-            and $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
-        {
-            $result .= '\end{itemize}';
-        }
-        else {
-            $result .= '\end{enumerate}';
-        }
-    }
+
     &Apache::response::end_response;
     pop @Apache::lonxml::namespace;
     &Apache::lonxml::deregister( 'Apache::radiobuttonresponse',
@@ -388,7 +376,7 @@ sub format_prior_answer {
 }
 
 ##
-sub displayallfoils {
+sub displayallfoils{
     my ( $direction, $target ) = @_;
     my $result;
     &Apache::lonxml::debug("survey style display");
@@ -397,6 +385,31 @@ sub displayallfoils {
         @names = @{ $Apache::response::foilgroup{'names'} };
     }
 
+    # Figure out how to bracket the list of foils for
+    # the TeX target:
+    #
+
+    my $begin_environment;
+    my $end_environment;
+    
+    if ($target eq 'tex') {
+
+	# Decide how to bracket the list of foils:
+
+
+        if (   $env{'form.pdfFormFields'} eq 'yes'
+            && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
+        {
+            $begin_environment = '\begin{itemize}';
+	    $end_environment   = '\end{itemize}';
+        }
+        else {
+            $begin_environment = '\begin{enumerate}';
+	    $end_environment   = '\end{enumerate}';
+        }	
+	$result .= $begin_environment;
+    }
+
     my $temp = 0;
     my $i    = 0;
     my $id   = $Apache::inputtags::response['-1'];
@@ -436,7 +449,9 @@ sub displayallfoils {
         $lastresponse =
           $Apache::lonhomework::history{"resource.$part.$id.submission"};
     }
-    if ( $direction eq 'horizontal' ) { $result .= '<table><tr>'; }
+    if ( $direction eq 'horizontal' && $target ne 'tex') { 
+	$result .= '<table><tr>'; 
+    }
     my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
     if ($showanswer) {
         foreach my $name (@names) {
@@ -475,7 +490,7 @@ sub displayallfoils {
         foreach my $name (@names) {
             if ( $Apache::response::foilgroup{ $name . '.value' } ne 'unused' )
             {
-                if ( $direction eq 'horizontal' ) {
+                if ( $direction eq 'horizontal' && $target ne 'tex' ) {
                     $result .= "<td>";
                 }
                 else {
@@ -549,9 +564,17 @@ sub displayallfoils {
     if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
         $result .= '</tr></table>';
     }
+
+    # Close tex bracketing:
+
+    if ($target eq 'tex') {
+	$result .= $end_environment;
+    }
     return $result;
 }
 
+
+
 sub whichfoils {
     my ( $max, $randomize ) = @_;
 
@@ -768,8 +791,97 @@ sub whichfoils {
     &Apache::lonxml::debug("Answer is $answer");
     return ( $answer, @whichfalse );
 }
+
+## 
+#  Return a list  of foil texts given foil names.
+#  
+# @param $whichfoils - Reference to a list of foil names.
+#
+# @return array
+# @retval foil texts
+#
+sub get_foil_texts {
+    my ($whichfoils) = @_;
+    my @foil_texts;
+
+    foreach my $name (@{$whichfoils}) {
+	push(@foil_texts, $Apache::response::foilgroup{$name . '.text'});
+    }
+    return @foil_texts;
+}
+
+##
+# Generate the HTML for a single html foil.
+# @param $part           - The part for which the response is being generated.
+# @param $fieldname      - The basename of the radiobutton field
+# @param $name           - The foilname.
+# @param $last_responses - Reference to a hash that holds the most recent
+#                          responses.
+# @param $value          - radiobutton value.
+# 
+# @return text
+# @retval The generated html.
+#
+sub html_radiobutton {
+    my ($part, $fieldname, $name, $last_responses, $value) = @_;
+
+    my $result='<label>';
+    
+    $result .= '<input type="radio"
+                onchange="javascript:setSubmittedPart(' . "'$part');\""
+		. 'name="HWVAL_' . $fieldname . '"'
+		. "value='$value'";
+
+    if (defined($last_responses->{$name})) {
+	$result .= '  checked="checked" ';
+    }
+    $result .= ' />';
+    $result .= $Apache::response::foilgroup{$name . '.text'};
+    $result .= '</label>';
+
+    return $result;
+
+}
 ##
-# Display foils in html rendition:
+# Return a reference to the last response hash. This hash has exactly
+# one or zero entries.  The one entry is keyed by the foil 'name' of
+# the prior response
+#
+# @param $part - Number of the problem part.
+# 
+# @return reference to a hash.
+# @retval see above.
+#
+sub get_last_response {
+    my ($part) = @_;
+
+    my $id = $Apache::inputtags::response['-1'];
+    my ( $lastresponse, $newvariation );
+    
+    if ((( $Apache::lonhomework::history{"resource.$part.type"} eq  'randomizetry')
+	 || ( $Apache::lonhomework::type eq 'randomizetry' )
+	)
+	&& ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
+	)
+    {
+	
+	if ( $env{ 'form.' . $part . '.rndseed' } ne
+	     $Apache::lonhomework::history{"resource.$part.rndseed"} )
+	{
+	    $newvariation = 1;
+	}
+    }
+    unless ($newvariation) {
+	$lastresponse =
+	    $Apache::lonhomework::history{"resource.$part.$id.submission"};
+    }
+    my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
+
+    return \%lastresponse;
+}
+
+##
+# Display foils in html rendition.:
 #
 # @param $whichfoils - Set of foils to display.
 # @param $target     - Rendition target...there are several html targets.
@@ -838,10 +950,210 @@ sub display_foils_html {
 	$result .= $finalclose;
 
     } else {
+	$result .= '<br />';	# end line prior to foilgroup:
+
 	#  Not showing the answers, we need to generate the HTML appropriate
 	#  to allowing the student to respond.
 	
+	my $item_pretext;
+	my $item_posttext;
+	my $lastresponse = &get_last_response($part);
+
+	if ( $direction eq 'horizontal' ) {
+	    $item_pretext  = '<td>';
+	    $item_posttext = '</td>';
+	}
+	else {
+	    $item_pretext = '<br/>';
+	}
+	my $item_no = 0;
+	foreach my $name (@{$whichfoils}) {
+	    $result .= $item_pretext;
+	    $result .= &html_radiobutton(
+		$part, $Apache::inputtags::response[-1],
+		$name, $lastresponse, $item_no
+		);
+	    $result .= $item_posttext;
+	    $item_no++;
+	}
 
+	if ($direction eq 'horizontal' ) {
+            $result .= "</tr></table>";
+        } else {
+	     $result .= "<br />"; 
+	}	
+    }
+
+    return $result;
+}
+##
+#  Display foils in exam mode for latex
+#
+# @param $whichfoils       - Reference to an array that contains the foil names to display
+# @param $bubbles_per_line - Number of bubbles on a line.
+# @param $direction        - Rendering direction 'horizontal' is what we're looking for.
+# @param $vbegin           - Start latex fragment in vertical rendering.
+# @param $vend             - End latex fragmentin vertical rendering.
+#
+# @return string
+# @return the latex rendering of the exam problem.
+#
+#
+sub display_latex_exam {
+    my ($whichfoils, $bubbles_per_line, $direction, $vbegin, $vend) = @_;
+    my $result;
+    my $numlines;
+    my $bubble_number = 0;
+    my $line          = 0;
+    my $i             = 0;
+
+
+    if ($direction eq  'horizontal') {
+
+	# Marshall the display text for each foil and turn things over to
+	# Apache::response::make_horizontal_bubbles:
+
+	my @foil_texts = &get_foil_texts($whichfoils);
+	$result .= &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $whichfoils, \@foil_texts, '$\bigcirc$');
+
+
+    } else {
+	$result .= $vbegin;
+	
+	# This section puts out the prefix that tells the user
+	# (if necessary) to only choose one bubble in the next n lines
+	# for problems with more than one line worth of bubbles in the grid sheet:
+	
+	my $numitems = scalar( @{$whichfoils} );
+	$numlines = int( $numitems / $bubbles_per_line );
+	if ( ( $numitems % $bubbles_per_line ) != 0 ) {
+	    $numlines++;
+	}
+	if ( $numlines < 1 ) {
+	    $numlines = 1;
+	}
+	if ( $numlines > 1 ) {
+	    my $linetext;
+	    for ( my $i = 0 ; $i < $numlines ; $i++ ) {
+		$linetext .= $Apache::lonxml::counter + $i . ', ';
+	    }
+	    $linetext =~ s/,\s$//;
+	    $result .=
+		'\item[\small {\textbf{'
+		. $linetext . '}}]'
+		. ' {\footnotesize '
+		. &mt( '(Bubble once in [_1] lines)', $numlines )
+		. '} \hspace*{\fill} \\\\';
+	}
+	else {
+	    $result .= '\item[\textbf{' . $Apache::lonxml::counter . '}.]';
+	}
+	
+	# Now output the bubbles themselves:
+	
+	foreach my $name (@{$whichfoils}) {
+	    if ( $bubble_number >= $bubbles_per_line ) {
+		$line++;
+		$i             = 0;
+		$bubble_number = 0;
+	    }
+	    my $identifier;
+	    if ( $numlines > 1 ) {
+		$identifier = $Apache::lonxml::counter + $line;
+	    }
+	    $result .=
+		'{\small \textbf{'
+		. $identifier
+		. $alphabet[$i]
+		. '}}$\bigcirc$'
+		. $Apache::response::foilgroup{ $name . '.text' }
+	    . '\\\\';    #' stupid emacs -- it thinks it needs that apostrophe to close the quote
+	    
+	    $i++;
+	    $bubble_number++;
+	}
+	$result .= $vend
+
+    }	
+
+    return $result;
+    
+}
+
+##
+#  Display latex when exam mode is not on.
+#
+#  @param $whichfoils - The foils to display
+#  @param $direction  - Display direction ('horizontal' is what matters to us).
+#  @param $vbegin     - Begin the vertical environment being used.
+#  @param  $vend      - End the vertical environment being used.
+#
+#  @return string
+#  @retval - The LaTeX rendering of the resource.'
+#
+sub display_latex {
+    my ($whichfoils, $direction, $vbegin, $vend) = @_;
+    my $result;
+
+    # how we render depends on the direction.
+    # Vertical is some kind of list environment determined by vbegin/vend.
+    # Horizontal is a table that is generated by 
+    # Apache::caparesponse::make_horizontal_latex_bubbles with an empty string
+    # for the actual bubble text.
+
+    if ($direction eq 'horizontal') {
+	my @foil_texts = &get_foil_texts($whichfoils);
+	$result .= &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $whichfoils, \@foil_texts, '');
+    } else {
+	$result .= $vbegin;
+	foreach my $name (@{$whichfoils}) {
+	    $result .=  '\vspace*{-2 mm}\item '
+		. $Apache::response::foilgroup{ $name . '.text' };
+	}
+	
+	$result .= $vend;
+    }
+    return $result;
+}
+
+
+##
+#  Render foils for a PDF form. This is a variant of tex rednering that provides
+#  sufficient markup that the final PDF is a form that can be filled in online,
+#  or offline.
+#
+# @param $whichfoils - References an array of foils to display in the order in which
+#                     they should be displayed.
+# @param $direction  - Rendering direction.  'horiztonal' means inputs are laid out
+#                      horizontally otherwise they are stacked vertically.
+#
+# @return string
+# @retval String containing the rendering of the resource.
+#
+sub display_pdf_form {
+    my ($whichfoils) = @_;
+    my $temp = 0;
+    my $result;
+
+    foreach my $name ( @{$whichfoils} ) {
+	
+	my $fieldname =
+	    $env{'request.symb'} 
+	. '&part_'
+	    . $Apache::inputtags::part
+	    . '&radiobuttonresponse'
+	    . '&HWVAL_'
+	    . $Apache::inputtags::response['-1'];
+	$result .= '\item[{'
+	    . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
+						      $temp )
+	    . '}]'
+	    . $Apache::response::foilgroup{ $name . '.text' }
+	. "\n";
+	
+	$temp++;
     }
 
     return $result;
@@ -849,6 +1161,18 @@ sub display_foils_html {
 
 
 ##
+# Display selected foils:  This is really just a dispatchter to appropriate renderers
+#  
+# @param $target   - Target (e.g. 'tex'...).
+# @param $answer   - True if answers should be shown.
+# @param $whichfoils - Array of foil selectors that indicate which foils shouild be
+#                      rendered, in rendering order.
+# @param $direction- Rendering direction ('horizontal' is the one we look for,
+#                    otherwise foils are rendered one per line vertically.
+# @param $bubbles_per_line - number of exam bubbles per line.
+#
+# @return string
+# @retval The rendered problem.
 
 sub displayfoils {
     my ( $target, $answer, $whichfoils, $direction, $bubbles_per_line ) = @_;
@@ -856,200 +1180,84 @@ sub displayfoils {
 
     my $part   = $Apache::inputtags::part;
     my $solved = $Apache::lonhomework::history{"resource.$part.solved"};
+
+    # Show answers html.
+
     if ( ( $target ne 'tex' )
         && &Apache::response::show_answer() )
     {
 
 	$result = &display_foils_html(
 	    $whichfoils, $target, $direction, $part, $solved, 1);
+	
+	# other html
+    }  elsif ($target ne 'tex') {
+	    $result = &display_foils_html($whichfoils, $target, $direction, $part,
+					  0, 0);
+
+       # LaTeX rendering:
+    } else {
 
-#        if ( $direction eq 'horizontal' ) {
-#            if ( $target ne 'tex' ) {
-#                $result .= '<table><tr>';
-#            }
-#        }
-#        foreach my $name ( @{$whichfoils} ) {
-#            if ( $direction eq 'horizontal' ) {
-#                if ( $target ne 'tex' ) { $result .= '<td>'; }
-#            }
-#            if ( $target ne 'tex' ) {
-#                $result .= "<br />";
-#            }
-#            else {
-#                $result .= '\item \vskip -2 mm  ';
-#            }
-#            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
-#                if ( $target ne 'tex' ) {
-#                    $result .= &mt('Correct:') . '<b>';
-#                }
-#                else {
-#                    $result .= &mt('Correct:') . ' \textbf{';
-#                }
-#            }
-#            else {
-#                $result .= &mt('Incorrect:');
-#            }
-#            if ( $target eq 'web' ) { $result .= "<label>"; }
-#            $result .= $Apache::response::foilgroup{ $name . '.text' };
-#            if ( $target eq 'web' ) { $result .= "</label>"; }
-#            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
-#                if   ( $target ne 'tex' ) { $result .= '</b>'; }
-#                else                      { $result .= '}'; }
-#            }
-#            if ( $direction eq 'horizontal' ) {
-#                if ( $target ne 'tex' ) { $result .= '</td>'; }
-#            }
-#        }
-#        if ( $direction eq 'horizontal' ) {
-#            if ( $target ne 'tex' ) {
-#                $result .= '</tr></table>';
-#            }
-#        }
-    }
-    else {
-        my @alphabet      = ( 'A' .. 'Z' );
         my $i             = 0;
         my $bubble_number = 0;
         my $line          = 0;
         my $temp          = 0;
         my $id            = $Apache::inputtags::response['-1'];
         my $part          = $Apache::inputtags::part;
-        my ( $lastresponse, $newvariation );
 
-        if (
-            (
-                (
-                    $Apache::lonhomework::history{"resource.$part.type"} eq
-                    'randomizetry'
-                )
-                || ( $Apache::lonhomework::type eq 'randomizetry' )
-            )
-            && ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
-          )
-        {
+	
+	
+	my $numlines;
+	
+	# Decide how to bracket the list of foils:
 
-            if ( $env{ 'form.' . $part . '.rndseed' } ne
-                $Apache::lonhomework::history{"resource.$part.rndseed"} )
-            {
-                $newvariation = 1;
-            }
-        }
-        unless ($newvariation) {
-            $lastresponse =
-              $Apache::lonhomework::history{"resource.$part.$id.submission"};
-        }
-        my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
-        if ( $target ne 'tex' && $direction eq 'horizontal' ) {
-            $result .= "<table><tr>";
-        }
-        my $numlines;
-        if ( ( $target eq 'tex' ) && ( $Apache::lonhomework::type eq 'exam' ) )
+	my $begin_environment;
+	my $end_environment;
+
+        if (   $env{'form.pdfFormFields'} eq 'yes'
+            && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
         {
-            my $numitems = scalar( @{$whichfoils} );
-            $numlines = int( $numitems / $bubbles_per_line );
-            if ( ( $numitems % $bubbles_per_line ) != 0 ) {
-                $numlines++;
-            }
-            if ( $numlines < 1 ) {
-                $numlines = 1;
-            }
-            if ( $numlines > 1 ) {
-                my $linetext;
-                for ( my $i = 0 ; $i < $numlines ; $i++ ) {
-                    $linetext .= $Apache::lonxml::counter + $i . ', ';
-                }
-                $linetext =~ s/,\s$//;
-                $result .=
-                    '\item[\small {\textbf{'
-                  . $linetext . '}}]'
-                  . ' {\footnotesize '
-                  . &mt( '(Bubble once in [_1] lines)', $numlines )
-                  . '} \hspace*{\fill} \\\\';
-            }
-            else {
-                $result .= '\item[\textbf{' . $Apache::lonxml::counter . '}.]';
-            }
-        }
-        foreach my $name ( @{$whichfoils} ) {
-            if ( $target ne 'tex' ) {
-                if ( $direction eq 'horizontal' ) {
-                    $result .= "<td>";
-                }
-                else {
-                    $result .= "<br />";
-                }
-            }
-            if ( $target ne 'tex' ) {
-                $result .= '<label>';
-                $result .= "<input type=\"radio\"
-                            onchange=\"javascript:setSubmittedPart('$part');\"
-                            name=\"HWVAL_$Apache::inputtags::response['-1']\"
-                            value=\"$temp\"";
-                if ( defined( $lastresponse{$name} ) ) {
-                    $result .= ' checked="checked"';
-                }
-                $result .= ' />'
-                  . $Apache::response::foilgroup{ $name . '.text' }
-                  . "</label>";
-            }
-            else {
-                if ( $Apache::lonhomework::type eq 'exam' ) {
-                    if ( $bubble_number >= $bubbles_per_line ) {
-                        $line++;
-                        $i             = 0;
-                        $bubble_number = 0;
-                    }
-                    my $identifier;
-                    if ( $numlines > 1 ) {
-                        $identifier = $Apache::lonxml::counter + $line;
-                    }
-                    $result .=
-                        '{\small \textbf{'
-                      . $identifier
-                      . $alphabet[$i]
-                      . '}}$\bigcirc$'
-                      . $Apache::response::foilgroup{ $name . '.text' }
-                      . '\\\\';    #' stupid emacs
-                    $i++;
-                    $bubble_number++;
-                }
-                else {
-                    if (   $env{'form.pdfFormFields'} eq 'yes'
-                        && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
-                    {
-                        my $fieldname =
-                            $env{'request.symb'} 
-                          . '&part_'
-                          . $Apache::inputtags::part
-                          . '&radiobuttonresponse'
-                          . '&HWVAL_'
-                          . $Apache::inputtags::response['-1'];
-                        $result .= '\item[{'
-                          . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
-                            $temp )
-                          . '}]'
-                          . $Apache::response::foilgroup{ $name . '.text' }
-                          . "\n";
-                    }
-                    else {
-                        $result .= '\vspace*{-2 mm}\item '
-                          . $Apache::response::foilgroup{ $name . '.text' };
-                    }
-                }
-            }
-            if ( $target ne 'tex' && $direction eq 'horizontal' ) {
-                $result .= "</td>";
-            }
-            $temp++;
-        }
-        if ( $target ne 'tex' && $direction eq 'horizontal' ) {
-            $result .= "</tr></table>";
+            $begin_environment = '\begin{itemize}';
+	    $end_environment   = '\end{itemize}';
         }
+        else {
+            $begin_environment = '\begin{enumerate}';
+	    $end_environment   = '\end{enumerate}';
+        }	
+	
+	# Rendering for latex exams.
+	
+	if ( ( $Apache::lonhomework::type eq 'exam' ) )
+	{
+	    $result .= &display_latex_exam(
+		$whichfoils, $bubbles_per_line, $direction, $begin_environment, 
+		$end_environment);
+
+	    $result .= '\vskip 0mm ';
+	    
+	} else {	    
+
+	    # Different rendering for PDF form than for a
+	    # 'regular' answer direction is honored in both of those
+	    #
+
+	    if ( ($env{'form.pdfFormFields'} eq 'yes')
+		    && ($Apache::inputtags::status[-1] eq 'CAN_ANSWER'))
+	    {
+		$result .= $begin_environment;
+		$result .= &display_pdf_form($whichfoils, $direction);
+		$result .= $end_environment;
+	    } else {
+		$result .= &display_latex(
+		     $whichfoils,  $direction, $begin_environment, $end_environment
+		    );
+	    }
+	    $result .= '\vskip 0 mm '; 
+       
+	}
+
+
     }
-    if ( $target ne 'tex' ) {
-        if ( $direction ne 'horizontal' ) { $result .= "<br />"; }
-    }
-    else { $result .= '\vskip 0 mm '; }
     return $result;
 }