--- loncom/homework/radiobuttonresponse.pm	2012/01/20 11:41:31	1.153.6.1
+++ loncom/homework/radiobuttonresponse.pm	2015/01/19 15:35:53	1.158
@@ -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.158 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -25,81 +25,86 @@
 # http://www.lon-capa.org/
 #
 
+
+
 package Apache::radiobuttonresponse;
 use strict;
 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',
-        ('radiobuttonresponse') );
+    &Apache::lonxml::register('Apache::radiobuttonresponse',('radiobuttonresponse'));
 }
 
+#---------------------------------------------------------------------------
+#
+#  Generic utility subs.
+
 sub bubble_line_count {
-    my ( $numfoils, $bubbles_per_line ) = @_;
+    my ($numfoils, $bubbles_per_line) = @_;
     my $bubble_lines;
-    $bubble_lines = int( $numfoils / $bubbles_per_line );
-    if ( ( $numfoils % $bubbles_per_line ) != 0 ) {
-        $bubble_lines++;
+    $bubble_lines = int($numfoils / $bubbles_per_line);
+    if (($numfoils % $bubbles_per_line) != 0) {
+	$bubble_lines++;
     }
     return $bubble_lines;
-
+    
 }
 
+
+
+#------------------------------------------------------------------------------
+#
+#  XML handlers.
 sub start_radiobuttonresponse {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     my $result;
 
     #when in a radiobutton response use these
-    &Apache::lonxml::register( 'Apache::radiobuttonresponse',
-        ( 'foilgroup', 'foil', 'conceptgroup' ) );
-    push( @Apache::lonxml::namespace, 'radiobuttonresponse' );
-    my $id = &Apache::response::start_response( $parstack, $safeeval );
+    &Apache::lonxml::register('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
+    push (@Apache::lonxml::namespace,'radiobuttonresponse');
+    my $id = &Apache::response::start_response($parstack,$safeeval);
 
-    %Apache::hint::radiobutton = ();
+    %Apache::hint::radiobutton=();
     undef(%Apache::response::foilnames);
-    if ( $target eq 'meta' ) {
-        $result = &Apache::response::meta_package_write('radiobuttonresponse');
-    }
-    elsif ( $target eq 'edit' ) {
-        $result .=
-            &Apache::edit::start_table($token)
-          . '<tr><td>'
-          . &Apache::lonxml::description($token)
-          . &Apache::loncommon::help_open_topic('Radio_Response_Problems')
-          . '</td>'
-          . '<td><span class="LC_nobreak">'
-          . &mt('Delete?') . ' '
-          . &Apache::edit::deletelist( $target, $token )
-          . '</span></td>'
-          . '<td>&nbsp;'
-          . &Apache::edit::end_row()
-          . &Apache::edit::start_spanning_row();
-        $result .= &Apache::edit::text_arg( 'Max Number Of Shown Foils:',
-            'max', $token, '4' )
-          . '&nbsp;' x 3
-          . &Apache::edit::select_arg( 'Randomize Foil Order:',
-            'randomize', [ 'yes', 'no' ], $token )
-          . '&nbsp;' x 3
-          . &Apache::edit::select_arg(
-            'Display Direction:', 'direction',
-            [ 'vertical', 'horizontal' ], $token
-          )
-          . &Apache::edit::end_row()
-          . &Apache::edit::start_spanning_row() . "\n";
-    }
-    elsif ( $target eq 'modified' ) {
-        my $constructtag =
-          &Apache::edit::get_new_args( $token, $parstack, $safeeval, 'max',
-            'randomize', 'direction' );
-        if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
-    }
-    elsif ( $target eq 'tex' ) {
+    if ($target eq 'meta') {
+	$result=&Apache::response::meta_package_write('radiobuttonresponse');
+    } elsif ($target eq 'edit' ) {
+	$result.=&Apache::edit::start_table($token)
+           .'<tr><td>'.&Apache::loncommon::insert_folding_button()
+           .&Apache::lonxml::description($token)
+           .&Apache::loncommon::help_open_topic('Radio_Response_Problems')
+           .'</td>'
+           .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
+           .&Apache::edit::deletelist($target,$token)
+           .'</span></td>'
+           .'<td>&nbsp;'.&Apache::edit::end_row()
+           .&Apache::edit::start_spanning_row();
+	$result.=
+	    &Apache::edit::text_arg('Max Number Of Shown Foils:','max',
+				    $token,'4').
+	    &Apache::edit::select_arg('Randomize Foil Order:','randomize',
+				      ['yes','no'],$token).
+	    &Apache::edit::select_arg('Display Direction:','direction',
+				      ['vertical','horizontal'],$token).
+				      &Apache::edit::end_row().
+				      &Apache::edit::start_spanning_row()."\n";
+    } elsif ($target eq 'modified') {
+	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
+						     $safeeval,'max',
+						     'randomize','direction');
+	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
+
+   } elsif ( $target eq 'tex' ) {
         my $type =
           &Apache::lonxml::get_param( 'TeXtype', $parstack, $safeeval, undef,
             0 );
@@ -118,290 +123,242 @@ 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";
         $Apache::lonhomework::analyze{"$part_id.type"} = 'radiobuttonresponse';
-        push( @{ $Apache::lonhomework::analyze{"parts"} }, $part_id );
+	push (@{ $Apache::lonhomework::analyze{"parts"} },$part_id);
     }
     return $result;
 }
 
 sub end_radiobuttonresponse {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
     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}';
-        }
+    if ( $target eq 'edit' ) { 
+	$result = &Apache::edit::end_table(); 
     }
     &Apache::response::end_response;
     pop @Apache::lonxml::namespace;
-    &Apache::lonxml::deregister( 'Apache::radiobuttonresponse',
-        ( 'foilgroup', 'foil', 'conceptgroup' ) );
+    &Apache::lonxml::deregister('Apache::radiobuttonresponse',('foilgroup','foil','conceptgroup'));
     undef(%Apache::response::foilnames);
     return $result;
 }
 
-%Apache::response::foilgroup = ();
-
+%Apache::response::foilgroup=();
 sub start_foilgroup {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
-    %Apache::response::foilgroup               = ();
-    $Apache::radiobuttonresponse::conceptgroup = 0;
-    &Apache::response::pushrandomnumber( undef, $target );
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    %Apache::response::foilgroup=();
+    $Apache::radiobuttonresponse::conceptgroup=0;
+    &Apache::response::pushrandomnumber(undef,$target);
     return;
 }
 
 sub storesurvey {
     my ($style) = @_;
     if ( !&Apache::response::submitted() ) { return ''; }
-    my $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
+    my $response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
     &Apache::lonxml::debug("Here I am!:$response:");
-    if ( $response !~ /[0-9]+/ ) { return ''; }
-    my $part       = $Apache::inputtags::part;
-    my $id         = $Apache::inputtags::response['-1'];
-    my @whichfoils = @{ $Apache::response::foilgroup{'names'} };
+    if ( $response !~ /[0-9]+/) { return ''; }
+    my $part = $Apache::inputtags::part;
+    my $id = $Apache::inputtags::response['-1'];
+    my @whichfoils=@{ $Apache::response::foilgroup{'names'} };
     my %responsehash;
-    $responsehash{ $whichfoils[$response] } = $response;
-    my $responsestr = &Apache::lonnet::hash2str(%responsehash);
-    $Apache::lonhomework::results{"resource.$part.$id.submission"} =
-      $responsestr;
-    my %previous =
-      &Apache::response::check_for_previous( $responsestr, $part, $id );
+    $responsehash{$whichfoils[$response]}=$response;
+    my $responsestr=&Apache::lonnet::hash2str(%responsehash);
+    $Apache::lonhomework::results{"resource.$part.$id.submission"}=
+	$responsestr;
+    my %previous=&Apache::response::check_for_previous($responsestr,$part,$id);
     my $ad;
-
-    if ( $style eq 'anonsurvey' ) {
-        $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
-          'ANONYMOUS';
-    }
-    elsif ( $style eq 'anonsurveycred' ) {
-        $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
-          'ANONYMOUS_CREDIT';
-    }
-    elsif ( $style eq 'surveycred' ) {
-        $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
-          'SUBMITTED_CREDIT';
-    }
-    else {
-        $ad = $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} =
-          'SUBMITTED';
+    if ($style eq 'anonsurvey') {
+        $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='ANONYMOUS';
+    } elsif ($style eq 'anonsurveycred') {
+        $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='ANONYMOUS_CREDIT';
+    } elsif ($style eq 'surveycred') {
+        $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='SUBMITTED_CREDIT';
+    } else {
+        $ad=$Apache::lonhomework::results{"resource.$part.$id.awarddetail"}='SUBMITTED';
     }
-    &Apache::response::handle_previous( \%previous, $ad );
+    &Apache::response::handle_previous(\%previous,$ad);
     &Apache::lonxml::debug("submitted a $response<br />\n");
     return '';
 }
 
+
 sub grade_response {
-    my ( $answer, $whichfoils, $bubbles_per_line ) = @_;
+    my ($answer, $whichfoils, $bubbles_per_line)=@_;
 
     if ( !&Apache::response::submitted() ) { return; }
     my $response;
+    
+    if ($env{'form.submitted'} eq 'scantron') {
+	$response = &Apache::response::getresponse(1,undef,
+						   &bubble_line_count(scalar(@{ $whichfoils}),
+								      $bubbles_per_line),
+						   $bubbles_per_line);
 
-    if ( $env{'form.submitted'} eq 'scantron' ) {
-        $response =
-          &Apache::response::getresponse( 1, undef,
-            &bubble_line_count( scalar( @{$whichfoils} ), $bubbles_per_line ),
-            $bubbles_per_line );
-
-    }
-    else {
-        $response = $env{ 'form.HWVAL_' . $Apache::inputtags::response['-1'] };
+    } else {
+	$response = $env{'form.HWVAL_'.$Apache::inputtags::response['-1']};
     }
 
-    if ( $response !~ /[0-9]+/ ) { return; }
-    my $part = $Apache::inputtags::part;
-    my $id   = $Apache::inputtags::response['-1'];
+
+    if ( $response !~ /[0-9]+/) { return; }
+    my $part=$Apache::inputtags::part;
+    my $id = $Apache::inputtags::response['-1'];
     my %responsehash;
-    $responsehash{ $whichfoils->[$response] } = $response;
-    my $responsestr = &Apache::lonnet::hash2str(%responsehash);
-    my %previous =
-      &Apache::response::check_for_previous( $responsestr, $part, $id );
-    $Apache::lonhomework::results{"resource.$part.$id.submission"} =
-      $responsestr;
+    $responsehash{$whichfoils->[$response]}=$response;
+    my $responsestr=&Apache::lonnet::hash2str(%responsehash);
+    my %previous=&Apache::response::check_for_previous($responsestr,
+						       $part,$id);
+    $Apache::lonhomework::results{"resource.$part.$id.submission"}=
+	$responsestr;
     &Apache::lonxml::debug("submitted a $response<br />\n");
     my $ad;
-
-    if ( $response == $answer ) {
-        $ad = 'EXACT_ANS';
-    }
-    else {
-        $ad = 'INCORRECT';
+    if ($response == $answer) {
+	$ad='EXACT_ANS';
+    } else {
+	$ad='INCORRECT';
     }
-    $Apache::lonhomework::results{"resource.$part.$id.awarddetail"} = $ad;
-    &Apache::response::handle_previous( \%previous, $ad );
+    $Apache::lonhomework::results{"resource.$part.$id.awarddetail"}=$ad;
+    &Apache::response::handle_previous(\%previous,$ad);
 }
 
 sub end_foilgroup {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
 
     my $result;
     my $bubble_lines;
     my $answer_count;
-    my $id               = $Apache::inputtags::response['-1'];
-    my $part             = $Apache::inputtags::part;
-    my $bubbles_per_line = &getbubblesnum( $part, $id );
-
-    if (   $target eq 'grade'
-        || $target eq 'web'
-        || $target eq 'answer'
-        || $target eq 'tex'
-        || $target eq 'analyze' )
-    {
-        my $style = $Apache::lonhomework::type;
-        my $direction =
-          &Apache::lonxml::get_param( 'direction', $parstack, $safeeval, '-2' );
-        if (
-            (
-                   ( $style eq 'survey' )
-                || ( $style eq 'surveycred' )
-                || ( $style eq 'anonsurvey' )
-                || ( $style eq 'anonsurveycred' )
-            )
-            && ( $target ne 'analyze' )
-          )
-        {
-            if ( $target eq 'web' || $target eq 'tex' ) {
-                $result = &displayallfoils( $direction, $target );
-            }
-            elsif ( $target eq 'answer' ) {
-                $result = &displayallanswers();
-            }
-            elsif ( $target eq 'grade' ) {
-                $result = &storesurvey($style);
-            }
-            $answer_count =
-              scalar( @{ $Apache::response::foilgroup{'names'} } );
+    my $id   = $Apache::inputtags::response['-1'];
+    my $part = $Apache::inputtags::part;
+    my $bubbles_per_line = &getbubblesnum($part,$id);
 
-        }
-        else {
 
-            my $name;
-            my $max =
-              &Apache::lonxml::get_param( 'max', $parstack, $safeeval, '-2' );
-            my $randomize =
-              &Apache::lonxml::get_param( 'randomize', $parstack, $safeeval,
-                '-2' );
-            my ( $answer, @shown ) = &whichfoils( $max, $randomize );
-            $answer_count = scalar(@shown);
-
-            if ( $target eq 'web' || $target eq 'tex' ) {
-                $result =
-                  &displayfoils( $target, $answer, \@shown, $direction,
-                    $bubbles_per_line );
-            }
-            elsif ( $target eq 'answer' ) {
-                $result =
-                  &displayanswers( $answer, \@shown, $bubbles_per_line );
-            }
-            elsif ( $target eq 'grade' ) {
-                &grade_response( $answer, \@shown, $bubbles_per_line );
-            }
-            elsif ( $target eq 'analyze' ) {
-                my $bubble_lines =
-                  &bubble_line_count( $answer_count, $bubbles_per_line );
-                &Apache::response::analyze_store_foilgroup( \@shown,
-                    [ 'text', 'value', 'location' ] );
-                my $part_id = "$part.$id";
-                push(
-                    @{ $Apache::lonhomework::analyze{"$part_id.options"} },
-                    ( 'true', 'false' )
-                );
+    if ($target eq 'grade' || $target eq 'web' || $target eq 'answer' ||
+	$target eq 'tex' || $target eq 'analyze') {
+	my $style = $Apache::lonhomework::type;
+	my $direction = &Apache::lonxml::get_param('direction',$parstack,
+						   $safeeval,'-2');
+	if ( (($style eq 'survey') || ($style eq 'surveycred') || 
+              ($style eq 'anonsurvey') || ($style eq 'anonsurveycred')) 
+             && ($target ne 'analyze')) {
+	    if ($target eq 'web' || $target eq 'tex') {
+		$result=&displayallfoils($direction, $target);
+	    } elsif ( $target eq 'answer' ) {
+		$result=&displayallanswers();
+	    } elsif ( $target eq 'grade' ) {
+		$result=&storesurvey($style);
+	    }
+	    $answer_count = scalar(@{$Apache::response::foilgroup{'names'}});
 
-            }
-        }
-        $Apache::lonxml::post_evaluate = 0;
+	} else {
+
+	    my $name;
+	    my $max = &Apache::lonxml::get_param('max',$parstack,$safeeval,
+						 '-2');
+	    my $randomize = &Apache::lonxml::get_param('randomize',$parstack,
+						       $safeeval,'-2');
+	    my ($answer, @shown) = &whichfoils($max, $randomize);
+	    $answer_count = scalar(@shown);
+
+	    if ($target eq 'web' || $target eq 'tex') {
+                $result=&displayfoils($target,
+				      $answer, \@shown,
+				      $direction,
+				      $bubbles_per_line);
+	    } elsif ($target eq 'answer' ) {
+		$result=&displayanswers($answer, \@shown, $bubbles_per_line);
+	    } elsif ( $target eq 'grade') {
+		&grade_response($answer, \@shown, $bubbles_per_line);
+	    }  elsif ( $target eq 'analyze') {
+		my $bubble_lines = &bubble_line_count($answer_count, 
+						      $bubbles_per_line);
+		&Apache::response::analyze_store_foilgroup(\@shown,
+							   ['text','value','location']);
+		my $part_id="$part.$id";
+		push (@{ $Apache::lonhomework::analyze{"$part_id.options"} },
+		      ('true','false'));
+
+	    }
+	}
+	$Apache::lonxml::post_evaluate=0;
     }
-    if ( $target eq 'web' ) {
-        &Apache::response::setup_prior_tries_hash( \&format_prior_answer,
-            [ \%Apache::response::foilgroup ] );
+    if ($target eq 'web') {
+	&Apache::response::setup_prior_tries_hash(\&format_prior_answer,
+						  [\%Apache::response::foilgroup]);
     }
     &Apache::response::poprandomnumber();
-    $bubble_lines = &bubble_line_count( $answer_count, $bubbles_per_line );
-    &Apache::lonxml::increment_counter( $bubble_lines, "$part.$id" );
-    if ( $target eq 'analyze' ) {
-        &Apache::lonhomework::set_bubble_lines();
+    $bubble_lines = &bubble_line_count($answer_count, $bubbles_per_line);
+    &Apache::lonxml::increment_counter($bubble_lines,
+				       "$part.$id");
+    if ($target eq 'analyze') {
+	&Apache::lonhomework::set_bubble_lines();
     }
     return $result;
 }
-
 sub getbubblesnum {
-    my ( $part, $id ) = @_;
+    my ($part,$id) = @_;
     my $bubbles_per_line;
     my $default_numbubbles = $default_bubbles_per_line;
-    if (   ( $env{'form.bubbles_per_row'} =~ /^\d+$/ )
-        && ( $env{'form.bubbles_per_row'} > 0 ) )
-    {
+    if (($env{'form.bubbles_per_row'} =~ /^\d+$/) &&
+        ($env{'form.bubbles_per_row'} > 0)) {
         $default_numbubbles = $env{'form.bubbles_per_row'};
     }
-    $bubbles_per_line = &Apache::response::get_response_param( $part . "_$id",
-        'numbubbles', $default_numbubbles );
+    $bubbles_per_line =
+        &Apache::response::get_response_param($part."_$id",'numbubbles',
+                                              $default_numbubbles);
     return $bubbles_per_line;
 }
 
 sub getfoilcounts {
     my @names;
-    my $truecnt  = 0;
-    my $falsecnt = 0;
+    my $truecnt=0;
+    my $falsecnt=0;
     my $name;
     if ( $Apache::response::foilgroup{'names'} ) {
-        @names = @{ $Apache::response::foilgroup{'names'} };
+	@names= @{ $Apache::response::foilgroup{'names'} };
     }
     foreach $name (@names) {
-        if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
-            $truecnt++;
-        }
-        elsif ( $Apache::response::foilgroup{ $name . '.value' } eq 'false' ) {
-            $falsecnt++;
-        }
+	if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
+	    $truecnt++;
+	} elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
+	    $falsecnt++;
+	}
     }
-    return ( $truecnt, $falsecnt );
+    return ($truecnt,$falsecnt);
 }
 
 sub format_prior_answer {
-    my ( $mode, $answer, $other_data ) = @_;
+    my ($mode,$answer,$other_data) = @_;
     my $foil_data = $other_data->[0];
-    my %response  = &Apache::lonnet::str2hash($answer);
-    my ($name)    = keys(%response);
-    return
-        '<span class="LC_prior_radiobutton">'
-      . $foil_data->{ $name . '.text' }
-      . '</span>';
+    my %response = &Apache::lonnet::str2hash($answer);
+    my ($name)   = keys(%response);
+    return '<span class="LC_prior_radiobutton">'.
+	$foil_data->{$name.'.text'}.'</span>';
 
 }
 
-##
-sub displayallfoils {
-    my ( $direction, $target ) = @_;
-    my $result;
-    &Apache::lonxml::debug("survey style display");
-    my @names;
-    if ( $Apache::response::foilgroup{'names'} ) {
-        @names = @{ $Apache::response::foilgroup{'names'} };
-    }
 
-    my $temp = 0;
-    my $i    = 0;
-    my $id   = $Apache::inputtags::response['-1'];
-    my $part = $Apache::inputtags::part;
-    my ( $lastresponse, $newvariation, $showanswer );
+## 
+# Return the last survey response.  The logic is slightly different than that of 
+# get_last_responses.  TODO: See if there are chunks of code betweenthis and
+# get_last_reponses that are common and can be factored.
+#
+# @param $part - Problem part under consideration.
+# @param $showanswer - True if answers should be shown.
+# @param $id         - Problem id.
+#
+# @return hash reference.
+# @retval reference to the has indexed by answer selection that 
+#         indicates the most recent answer.
+#
+sub get_last_survey_response {
+    my ($part, $showanswer, $id) = @_;
+
+    my $newvariation;
+    my $lastresponse;		# stringified last response.
+
     if (
         (
             (
@@ -420,388 +377,546 @@ sub displayallfoils {
         }
     }
     $showanswer = &Apache::response::show_answer();
-    unless (
-        (
-            (
-                $Apache::lonhomework::history{"resource.$part.type"} eq
-                'anonsurvey'
-            )
-            || ( $Apache::lonhomework::history{"resource.$part.type"} eq
-                'anonsurveycred' )
-        )
-        && ( defined( $env{'form.grade_symb'} ) )
-        || ( $newvariation && !$showanswer )
-      )
-    {
-        $lastresponse =
-          $Apache::lonhomework::history{"resource.$part.$id.submission"};
+    unless ($newvariation && !$showanswer) {
+        if ((($env{'form.grade_username'} eq '') && ($env{'form.grade_domain'} eq '')) ||
+            (($env{'form.grade_username'} eq $env{'user.name'}) &&
+             ($env{'form.grade_domain'} eq $env{'user.domain'}))) {
+            $lastresponse = $Apache::lonhomework::history{"resource.$part.$id.submission"};
+        } else {
+            unless (($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurvey') ||
+                    ($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurveycred')) {
+                $lastresponse = $Apache::lonhomework::history{"resource.$part.$id.submission"};
+            }
+        }
     }
-    if ( $direction eq 'horizontal' ) { $result .= '<table><tr>'; }
     my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
+
+    return \%lastresponse;
+
+}
+##
+# Removes the names from a foil group that are marked as unused.
+#
+# @param $names - reference to the array of names to filter.
+#
+# @return arrayref
+# @retval reference to the filtered array.
+#
+sub remove_unused {
+    my ($names) = @_;
+    my @result;
+
+    foreach my $name (@{$names}) {
+	if ($Apache::response::foilgroup{$name . '.value'} ne 'unused') {
+	    push(@result, $name);
+	}
+    }
+    return \@result;
+}
+## 
+# Displays all foils in a survey type problem for HTML rendition.
+# TODO: See if there is any logic in this sub that can be shared
+#      with display_foils_html
+#
+# @param $names        - ref to array of names of the foils to display.
+# @param $part         - Problem part number.
+# @param $showanswer   - If true, show the answers.
+# @param $lastresponse - Ref to the last response hash.
+# @param $direction    - Display direction of the radiobuttons.
+#
+# @return string
+# @retval HTML required to display the resource in a browser.
+#
+sub display_survey_html {
+    my ($names, $part, $showanswer, $lastresponse, $direction) = @_;
+    my $result;
+
+    # Figure out a few fragments of html that depend onthe 
+    # orientation of the radiobuttons:
+    # closing_html - HTML to emit at the end of the resource.
+    # pre_foil     - HTML to emit prior to each foil.
+    # post_foil    - HTML to emit following each foil.
+    #
+    #  The opening HTML is just added to the $result now
+    #
+    #  Figuring these outin advance compresses the loop over foils into something
+    #  pretty simple:
+    #
+    # NOTE: There's probably a really cool way to do this with style sheets
+    #       and picking the selector based on the orientation, if someone wants to puzzle
+    #       that out.  In that case, probably the whole thing lives in a <div> and each
+    #       foil lives in a <p>
+    #
+
+
+    my ($opening_html, $closing_html, $pre_foil, $post_foil) = 
+	&html_direction_fragments($direction);
+
+    $result = $opening_html;
+
+    # Different rendering depending on whether answers are shown:
+    # I played with different factorings but this seems the most concise/clear...
+    # although I don't like the $showanswer conditino inside the loop.  Other things I tried
+    #  - two loops..much longer code..no gain in clarity.
+    #  - Using a visitor patttern passing it the rendering code chunklets and
+    #    an anonymous hash reference for state data etc. Very cool but
+    #    quite a bit more code and quite a bit less clear.
+    
+    my $temp = 0;
+    foreach my $name (@{$names}) {
+	$result .= $pre_foil;
+
+	if ($showanswer) {
+	    my $foiltext =  $Apache::response::foilgroup{$name . '.text'};
+
+	    # Bold the prior  response:
+
+	    if (defined($lastresponse->{$name})) {
+		$result .= '<b>' . $foiltext . '</b>';
+	    } else {
+		$result .= $foiltext;
+	    }
+	} else {
+	    $result .= &html_radiobutton(
+		$part, $Apache::inputtags::response['-1'], $name, $lastresponse, $temp
+	     );
+	}
+
+	$result .= $post_foil;
+	$temp++;
+    }
+
+
+    $result .= $closing_html;
+    return $result;
+
+}
+
+##
+#  Generate LaTeX for surveys.
+#  
+#   @param $names - names of the foils to display.
+#   @param $showanswer - flag that is true to display answers.
+#   @param $lastresponse - Reference to a hash the indicates the last response.
+#   @param $direction    - Orientation of foils ('horiztonal' or otherwise).
+#   @param $venv         - LaTeX name for vertical env.
+#
+#   @return string
+#   @retval LaTeX rendering of the survey question.
+
+sub latex_survey {
+    my ($names, $showanswer, $lastresponse, $direction, $venv) = @_;
+
+    my $result;
     if ($showanswer) {
-        foreach my $name (@names) {
-            if ( $Apache::response::foilgroup{ $name . '.value' } ne 'unused' )
-            {
-                if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
-                    $result .= "<td>";
-                }
-                else {
-                    if ( $target eq 'tex' ) {
-                        $result .= '\item \vskip -2mm ';
-                    }
-                    else {
-                        $result .= "<br />";
-                    }
-                }
-                if ( defined( $lastresponse{$name} ) ) {
-                    if ( $target eq 'tex' ) {
-                        $result .= '}';
-                    }
-                    else {
-                        $result .= '<b>';
-                    }
-                }
-                $result .= $Apache::response::foilgroup{ $name . '.text' };
-                if ( defined( $lastresponse{$name} ) && ( $target ne 'tex' ) ) {
-                    $result .= '</b>';
-                }
-                if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
-                    $result .= "</td>";
-                }
-            }
-        }
+	$result .= "\\begin{$venv}";
+	foreach my $name (@{$names}) {
+	    
+	    
+	    $result .= '\item \vskip -2mm ';
+	    
+	    if ( defined( $lastresponse->{$name} ) ) {
+		$result .= '}';
+	    }
+	    $result .= $Apache::response::foilgroup{ $name . '.text' } . ' ';
+	}
+	$result .= "\\end{$venv}";
+
+    } elsif ( $env{'form.pdfFormFields'} eq 'yes'
+	      && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+	$result .= &display_pdf_form($names, $direction, $venv);
+    } else {
+	if ($direction eq 'horizontal') {
+	    my @foil_texts = &get_foil_texts($names);
+	    $result .=  &Apache::caparesponse::make_horizontal_latex_bubbles(
+	    $names, \@foil_texts, '$\bigcirc$');
+	} else {
+	    $result .= "\\begin{$venv}";
+
+	    my $temp = 0;
+	    my $i    = 0;
+	    foreach my $name (@{$names}) {
+
+		$result .= '\item \vskip -2mm ';
+		
+		if ($env{'form.pdfFormFields'} ne 'yes'
+		    or $Apache::inputtags::status[-1] ne 'CAN_ANSWER' )
+		{
+		    $result .=
+			'$\bigcirc$'
+			. $Apache::response::foilgroup{ $name . '.text' }
+		    . '\\\\';    #' stupid emacs
+		}
+		
+		$i++;	    
+		$temp++;
+		
+		$result .= '\vskip 0 mm ';
+	    }
+	    $result .= "\\end{$venv}";
+	}	
     }
-    else {
-        foreach my $name (@names) {
-            if ( $Apache::response::foilgroup{ $name . '.value' } ne 'unused' )
-            {
-                if ( $direction eq 'horizontal' ) {
-                    $result .= "<td>";
-                }
-                else {
-                    if ( $target eq 'tex' ) {
-                        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 .= '\item \vskip -2mm ';
-                        }
-                    }
-                    else {
-                        $result .= "<br />";
-                    }
-                }
-                if ( $target eq 'tex' ) {
-                    if (   $env{'form.pdfFormFields'} ne 'yes'
-                        or $Apache::inputtags::status[-1] ne 'CAN_ANSWER' )
-                    {
-                        $result .=
-                            '$\bigcirc$'
-                          . $Apache::response::foilgroup{ $name . '.text' }
-                          . '\\\\';    #' stupid emacs
-                    }
-                    $i++;
-                }
-                else {
-                    $result .= '<label>';
-                    $result .= "<input
-                       onchange=\"javascript:setSubmittedPart('$part');\"
-                       type=\"radio\"
-                       name=\"HWVAL_$Apache::inputtags::response['-1']\"
-                       value=\"$temp\"";
-
-                    if ( defined( $lastresponse{$name} ) ) {
-                        $result .= ' checked="checked"';
-                    }
-                    $result .= ' />'
-                      . $Apache::response::foilgroup{ $name . '.text' }
-                      . '</label>';
-                }
-                $temp++;
-                if ( $target ne 'tex' ) {
-                    if (   ( $direction eq 'horizontal' )
-                        && ( $target ne 'tex' ) )
-                    {
-                        $result .= "</td>";
-                    }
-                }
-                else {
-                    $result .= '\vskip 0 mm ';
-                }
-            }
-        }
+    return $result;
+}
+##
+#  Figure out the LaTeX environment in which to wrap the LaTeX vertical output.
+#
+# @return string
+# @retval the environment name.  The LaTeX should be wrapped a 
+#    \begin{retval} \end{retval} pair.
+#
+sub latex_vertical_environment {
+    if ($env{'form.pdfFormFields'} eq 'yes'
+	&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+	return 'itemize';
+    } else {
+	return 'enumerate';
+    }
+}
+
+##
+# Figure out the key html fragments that depend on the rendering direction:
+#
+# @param $direction - 'horizontal' for horizontal direction.
+#
+# @return list
+# @retval (part_start, part_end, foil_start, foil_end)
+# Where:
+#   - part_start is the HTML to emit at the start of the part.
+#   - part_end   is the HTML to emit at the end of the part.
+#   - foil_start is the HTML to emit prior to each foil.
+#   - foil_end is the HTML to emit after each foil
+#
+sub html_direction_fragments {
+    my $direction = shift;
+    if ($direction eq 'horizontal') {
+	return ('<table><tr>', '</tr></table>', '<td>', '</td>');
+    } else {
+	return ('', '<br />', '<br />', '');
+    }
+}
+
+##
+#
+#  Displays all the foils of a problem in a format suitable for
+#   surveys, surveys for credit, anonymous surveys and anonymous surveys for credit.
+#
+#  @param $direction - Display direction of the choices ('horiztonal' or not).
+#  @param $target    - Rendering target.
+#
+#  @return string
+#  @retval Text that renders for the selected target.
+# 
+sub displayallfoils{
+    my ( $direction, $target ) = @_;
+    my $result;
+    &Apache::lonxml::debug("survey style display");
+
+    my @names;
+
+    if ( $Apache::response::foilgroup{'names'} ) {
+        @names = @{ $Apache::response::foilgroup{'names'} };
     }
 
-    if ( ( $direction eq 'horizontal' ) && ( $target ne 'tex' ) ) {
-        $result .= '</tr></table>';
+
+    my $id   = $Apache::inputtags::response['-1'];
+    my $part = $Apache::inputtags::part;
+    
+    my $showanswer = &Apache::response::show_answer();
+    my $lastresponse = &get_last_survey_response($part, $showanswer, $id);
+    my $used_names = &remove_unused(\@names);
+
+
+    if ($target ne 'tex') {
+	$result .= &display_survey_html(
+	    $used_names, $part, $showanswer, $lastresponse, $direction
+	);
+    } else {	
+
+	my $vertical_env = &latex_vertical_environment();
+	$result .= &latex_survey(
+	    $used_names, $showanswer, $lastresponse, $direction, $vertical_env
+	);
+
     }
     return $result;
 }
 
 sub whichfoils {
-    my ( $max, $randomize ) = @_;
+    my ($max,$randomize)=@_;
 
     my @truelist;
     my @falselist;
-    my @whichfalse = ();
-    my ( $truecnt, $falsecnt ) = &getfoilcounts();
-    my $count = 0;
-
+    my @whichfalse =();
+    my ($truecnt,$falsecnt) = &getfoilcounts();
+    my $count=0;
     # we will add in 1 of the true statements
-    if ( $max > 0 && ( $falsecnt + 1 ) > $max ) { $count = $max }
-    else { $count = $falsecnt + 1; $max = $count; }
-    my $answer = int( &Math::Random::random_uniform() * ($count) );
+    if ( $max>0 && ($falsecnt+1)>$max) { $count=$max } else { $count=$falsecnt+1; $max=$count; }
+    my $answer=int(&Math::Random::random_uniform() * ($count));
     &Apache::lonxml::debug("Count is $count, $answer is $answer");
     my @names;
     if ( $Apache::response::foilgroup{'names'} ) {
-        @names = @{ $Apache::response::foilgroup{'names'} };
-    }
-    if ( &Apache::response::showallfoils() ) {
-        @whichfalse = @names;
+	@names= @{ $Apache::response::foilgroup{'names'} };
     }
-    elsif ( $randomize eq 'no' ) {
-        &Apache::lonxml::debug("No randomization");
-        my $havetrue = 0;
-        foreach my $name (@names) {
-            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
-                if ( !$havetrue ) {
-                    push( @whichfalse, $name );
-                    $havetrue++;
-                    $answer = $#whichfalse;
+    if (&Apache::response::showallfoils()) {
+	@whichfalse=@names;
+    } elsif ($randomize eq 'no') {
+	&Apache::lonxml::debug("No randomization");
+	my $havetrue=0;
+	foreach my $name (@names) {
+	    if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
+		if (!$havetrue ) {
+		    push(@whichfalse,$name); $havetrue++; $answer=$#whichfalse;
+		}
+	    } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
+		push (@whichfalse,$name);
+	    } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'unused') {
+	    } else {
+		&Apache::lonxml::error(&HTML::Entities::encode("No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",'<>&"'));
+	    }
+	}
+	if ((!$havetrue) && 
+            ($Apache::lonhomework::type ne 'survey') && 
+            ($Apache::lonhomework::type ne 'surveycred') &&
+            ($Apache::lonhomework::type ne 'anonsurvey') &&
+            ($Apache::lonhomework::type ne 'anonsurveycred')) {
+	    &Apache::lonxml::error(&mt('There are no true statements available.').'<br />');
+	}
+    } else {
+	my $current=0;
+	&Apache::lonhomework::showhash(%Apache::response::foilgroup);
+	my (%top,%bottom);
+	#first find out where everyone wants to be
+	foreach my $name (@names) {
+	    $current++;
+	    if ($Apache::response::foilgroup{$name.'.value'} eq 'true') {
+		push (@truelist,$name);
+		if ($Apache::response::foilgroup{$name.'.location'} eq 'top') {
+		    $top{$name}=$current;
+		} elsif ($Apache::response::foilgroup{$name.'.location'} eq 'bottom') {
+		    $bottom{$name}=$current;
+		}
+	    } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'false') {
+		push (@falselist,$name);
+		if ($Apache::response::foilgroup{$name.'.location'} eq 'top') {
+		    $top{$name}=$current;
+		} elsif ($Apache::response::foilgroup{$name.'.location'} eq 'bottom') {
+		    $bottom{$name}=$current;
+		}
+	    } elsif ($Apache::response::foilgroup{$name.'.value'} eq 'unused') {
+	    } else {
+		&Apache::lonxml::error(&HTML::Entities::encode("No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",'<>&"'));
+	    }
+	}
+	#pick a true statement
+	my $notrue=0;
+	if (scalar(@truelist) == 0) { $notrue=1; }
+	my $whichtrue = int(&Math::Random::random_uniform() * ($#truelist+1));
+	&Apache::lonxml::debug("Max is $max, From $#truelist elms, picking $whichtrue");
+	my (@toplist, @bottomlist);
+	my $topcount=0;
+	my $bottomcount=0;
+	# assign everyone to either toplist/bottomlist or whichfalse
+	# which false is randomized, toplist bottomlist are in order
+	while ((($#whichfalse+$topcount+$bottomcount) < $max-2) && ($#falselist > -1)) {
+	    &Apache::lonxml::debug("Have $#whichfalse max is $max");
+	    my $afalse=int(&Math::Random::random_uniform() * ($#falselist+1));
+	    &Apache::lonxml::debug("From $#falselist elms, picking $afalse");
+	    $afalse=splice(@falselist,$afalse,1);
+	    &Apache::lonxml::debug("Picked $afalse");
+	    &Apache::lonhomework::showhash(('names'=>\@names));
+	    &Apache::lonhomework::showhash(%top);
+	    if ($top{$afalse}) {
+		$toplist[$top{$afalse}]=$afalse;
+		$topcount++;
+	    } elsif ($bottom{$afalse}) {
+		$bottomlist[$bottom{$afalse}]=$afalse;
+		$bottomcount++;
+	    } else {
+		push (@whichfalse,$afalse);
+	    }
+	}
+	&Apache::lonxml::debug("Answer wants $answer");
+	my $truename=$truelist[$whichtrue];
+	my $dosplice=1;
+	if (($notrue) && 
+            ($Apache::lonhomework::type ne 'survey') &&
+            ($Apache::lonhomework::type ne 'surveycred') &&
+            ($Apache::lonhomework::type ne 'anonsurvey') &&
+            ($Apache::lonhomework::type ne 'anonsurveycred')) {
+	    $dosplice=0;
+	    &Apache::lonxml::error(&mt('There are no true statements available.').'<br />');
+	}
+	#insert the true statement, keeping track of where it wants to be
+	if ($Apache::response::foilgroup{$truename.'.location'} eq 'top' && $dosplice) {
+	    $toplist[$top{$truename}]=$truename;
+	    $answer=-1;
+	    foreach my $top (reverse(@toplist)) {
+		if ($top) { $answer++;}
+		if ($top eq $truename) { last; }
+	    }
+	    $dosplice=0;
+	} elsif ($Apache::response::foilgroup{$truename.'.location'} eq 'bottom' && $dosplice) {
+	    $bottomlist[$bottom{$truename}]=$truename;
+	    $answer=-1;
+	    foreach my $bot (@bottomlist) {
+		if ($bot) { $answer++;}
+		if ($bot eq $truename) { last; }
+	    }
+	    $answer+=$topcount+$#whichfalse+1;
+	    $dosplice=0;
+	} else {
+	    if ($topcount>0 || $bottomcount>0) {
+                my $inc = 1;
+                if (($bottomcount > 0) && ($Apache::lonhomework::type ne 'exam')) {
+                    $inc = 2;
                 }
-            }
-            elsif (
-                $Apache::response::foilgroup{ $name . '.value' } eq 'false' )
-            {
-                push( @whichfalse, $name );
-            }
-            elsif (
-                $Apache::response::foilgroup{ $name . '.value' } eq 'unused' )
-            {
-            }
-            else {
-                &Apache::lonxml::error(
-                    &HTML::Entities::encode(
-"No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",
-                        '<>&"'
-                    )
-                );
-            }
-        }
-        if (   ( !$havetrue )
-            && ( $Apache::lonhomework::type ne 'survey' )
-            && ( $Apache::lonhomework::type ne 'surveycred' )
-            && ( $Apache::lonhomework::type ne 'anonsurvey' )
-            && ( $Apache::lonhomework::type ne 'anonsurveycred' ) )
-        {
-            &Apache::lonxml::error(
-                &mt('There are no true statements available.') . '<br />' );
-        }
+                $answer=int(&Math::Random::random_uniform() * ($#whichfalse+$inc))
+                        + $topcount;
+	    }
+	}
+	&Apache::lonxml::debug("Answer now wants $answer");
+	#add the top items to the top, bottom items to the bottom
+	for (my $i=0;$i<=$#toplist;$i++) {
+	    if ($toplist[$i]) { unshift(@whichfalse,$toplist[$i]) }
+	}
+	for (my $i=0;$i<=$#bottomlist;$i++) {
+	    if ($bottomlist[$i]) { push(@whichfalse,$bottomlist[$i]) }
+	}
+	#if the true statement is randomized insert it into the list
+	if ($dosplice) { splice(@whichfalse,$answer,0,$truelist[$whichtrue]); }
     }
-    else {
-        my $current = 0;
-        &Apache::lonhomework::showhash(%Apache::response::foilgroup);
-        my ( %top, %bottom );
-
-        #first find out where everyone wants to be
-        foreach my $name (@names) {
-            $current++;
-            if ( $Apache::response::foilgroup{ $name . '.value' } eq 'true' ) {
-                push( @truelist, $name );
-                if ( $Apache::response::foilgroup{ $name . '.location' } eq
-                    'top' )
-                {
-                    $top{$name} = $current;
-                }
-                elsif ( $Apache::response::foilgroup{ $name . '.location' } eq
-                    'bottom' )
-                {
-                    $bottom{$name} = $current;
-                }
-            }
-            elsif (
-                $Apache::response::foilgroup{ $name . '.value' } eq 'false' )
-            {
-                push( @falselist, $name );
-                if ( $Apache::response::foilgroup{ $name . '.location' } eq
-                    'top' )
-                {
-                    $top{$name} = $current;
-                }
-                elsif ( $Apache::response::foilgroup{ $name . '.location' } eq
-                    'bottom' )
-                {
-                    $bottom{$name} = $current;
-                }
-            }
-            elsif (
-                $Apache::response::foilgroup{ $name . '.value' } eq 'unused' )
-            {
-            }
-            else {
-                &Apache::lonxml::error(
-                    &HTML::Entities::encode(
-"No valid value assigned ($Apache::response::foilgroup{$name.'.value'}) for foil $name in <foilgroup>",
-                        '<>&"'
-                    )
-                );
-            }
-        }
+    &Apache::lonxml::debug("Answer is $answer");
+    return ($answer,@whichfalse);
+}
 
-        #pick a true statement
-        my $notrue = 0;
-        if ( scalar(@truelist) == 0 ) { $notrue = 1; }
-        my $whichtrue =
-          int( &Math::Random::random_uniform() * ( $#truelist + 1 ) );
-        &Apache::lonxml::debug(
-            "Max is $max, From $#truelist elms, picking $whichtrue");
-        my ( @toplist, @bottomlist );
-        my $topcount    = 0;
-        my $bottomcount = 0;
-
-        # assign everyone to either toplist/bottomlist or whichfalse
-        # which false is randomized, toplist bottomlist are in order
-        while (( ( $#whichfalse + $topcount + $bottomcount ) < $max - 2 )
-            && ( $#falselist > -1 ) )
-        {
-            &Apache::lonxml::debug("Have $#whichfalse max is $max");
-            my $afalse =
-              int( &Math::Random::random_uniform() * ( $#falselist + 1 ) );
-            &Apache::lonxml::debug("From $#falselist elms, picking $afalse");
-            $afalse = splice( @falselist, $afalse, 1 );
-            &Apache::lonxml::debug("Picked $afalse");
-            &Apache::lonhomework::showhash( ( 'names' => \@names ) );
-            &Apache::lonhomework::showhash(%top);
-            if ( $top{$afalse} ) {
-                $toplist[ $top{$afalse} ] = $afalse;
-                $topcount++;
-            }
-            elsif ( $bottom{$afalse} ) {
-                $bottomlist[ $bottom{$afalse} ] = $afalse;
-                $bottomcount++;
-            }
-            else {
-                push( @whichfalse, $afalse );
-            }
-        }
-        &Apache::lonxml::debug("Answer wants $answer");
-        my $truename = $truelist[$whichtrue];
-        my $dosplice = 1;
-        if (   ($notrue)
-            && ( $Apache::lonhomework::type ne 'survey' )
-            && ( $Apache::lonhomework::type ne 'surveycred' )
-            && ( $Apache::lonhomework::type ne 'anonsurvey' )
-            && ( $Apache::lonhomework::type ne 'anonsurveycred' ) )
-        {
-            $dosplice = 0;
-            &Apache::lonxml::error(
-                &mt('There are no true statements available.') . '<br />' );
-        }
+## 
+#  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;
 
-        #insert the true statement, keeping track of where it wants to be
-        if (   $Apache::response::foilgroup{ $truename . '.location' } eq 'top'
-            && $dosplice )
-        {
-            $toplist[ $top{$truename} ] = $truename;
-            $answer = -1;
-            foreach my $top ( reverse(@toplist) ) {
-                if ($top) { $answer++; }
-                if ( $top eq $truename ) { last; }
-            }
-            $dosplice = 0;
-        }
-        elsif (
-            $Apache::response::foilgroup{ $truename . '.location' } eq 'bottom'
-            && $dosplice )
-        {
-            $bottomlist[ $bottom{$truename} ] = $truename;
-            $answer = -1;
-            foreach my $bot (@bottomlist) {
-                if ($bot) { $answer++; }
-                if ( $bot eq $truename ) { last; }
-            }
-            $answer += $topcount + $#whichfalse + 1;
-            $dosplice = 0;
-        }
-        else {
-            if ( $topcount > 0 || $bottomcount > 0 ) {
-                my $inc = 1;
-                if (   ( $bottomcount > 0 )
-                    && ( $Apache::lonhomework::type ne 'exam' ) )
-                {
-                    $inc = 2;
-                }
-                $answer = int(
-                    &Math::Random::random_uniform() * ( $#whichfalse + $inc ) )
-                  + $topcount;
-            }
-        }
-        &Apache::lonxml::debug("Answer now wants $answer");
+    foreach my $name (@{$whichfoils}) {
+	push(@foil_texts, $Apache::response::foilgroup{$name . '.text'});
+    }
+    return @foil_texts;
+}
 
-        #add the top items to the top, bottom items to the bottom
-        for ( my $i = 0 ; $i <= $#toplist ; $i++ ) {
-            if ( $toplist[$i] ) { unshift( @whichfalse, $toplist[$i] ) }
-        }
-        for ( my $i = 0 ; $i <= $#bottomlist ; $i++ ) {
-            if ( $bottomlist[$i] ) { push( @whichfalse, $bottomlist[$i] ) }
-        }
+##
+# 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>';
 
-        #if the true statement is randomized insert it into the list
-        if ($dosplice) {
-            splice( @whichfalse, $answer, 0, $truelist[$whichtrue] );
+    return $result;
+
+}
+##
+# 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) {
+        if ((($env{'form.grade_username'} eq '') && ($env{'form.grade_domain'} eq '')) ||
+            (($env{'form.grade_username'} eq $env{'user.name'}) &&
+             ($env{'form.grade_domain'} eq $env{'user.domain'}))) {
+            $lastresponse =
+                $Apache::lonhomework::history{"resource.$part.$id.submission"};
+        } else {
+            unless (($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurvey') ||
+                    ($Apache::lonhomework::history{"resource.$part.type"} eq 'anonsurveycred')) {
+                $lastresponse =
+                    $Apache::lonhomework::history{"resource.$part.$id.submission"};
+
+            }
         }
     }
-    &Apache::lonxml::debug("Answer is $answer");
-    return ( $answer, @whichfalse );
+
+    my %lastresponse = &Apache::lonnet::str2hash($lastresponse);
+
+    return \%lastresponse;
 }
+
 ##
-# Display foils in html rendition:
+# Display foils in html rendition.:
 #
 # @param $whichfoils - Set of foils to display.
 # @param $target     - Rendition target...there are several html targets.
 # @param $direction  - 'horizontal' if layout is horizontal.
 # @param $part       - Part of the problem that's being displayed.
-# @param $solved     - Solution state of the problem.
 # @param $show_answer- True if answers should be shown.
 #
 # @return string
 # @retval generated html.
 #
 sub display_foils_html {
-    my ($whichfoils, $target, $direction, $part, $solved, $show_answer) = @_;
+    my ($whichfoils, $target, $direction, $part, $show_answer) = @_;
     my $result;
 
+
     # if the answers get shown, we need to label each item as correct or
     # incorrect.
 
-    if ($show_answer) {
-	my $item_pretext     = '<br />'; # html prior to each item
-	my $item_posttext    = '';	 # html after each item.
-	my $finalclose       = '';	 # html to close off the whole shebang
+    my ($opening_html, $finalclose, $item_pretext, $item_posttext) = 
+	&html_direction_fragments($direction);
 
+    $result .= $opening_html;
 
-	# Horizontal layout is a table with each foil in a cell
 
-	if ($direction eq 'horizontal') {
-	    $result        = '<table><tr>';
-	    $item_pretext  = '<td>' . $item_pretext;
-	    $item_posttext = '</td>';
-	    $finalclose    = '</tr></table>';
-	} 
+    if ($show_answer) {
 
 	foreach my $name (@{$whichfoils}) {
 
@@ -835,402 +950,423 @@ sub display_foils_html {
 	    $result .= "\n";	# make the html a bit more readable.
 	}
 
-	$result .= $finalclose;
 
     } else {
-	#  Not showing the answers, we need to generate the HTML appropriate
-	#  to allowing the student to respond.
+	my $lastresponse = &get_last_response($part);
+	
+	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++;
+	}
+	
+    }
+    $result .= $finalclose;
+
+    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 $venv             - Name of LaTeX environment to use for vertical rendering.
+#
+# @return string
+# @return the latex rendering of the exam problem.
+#
+#
+sub display_latex_exam {
+    my ($whichfoils, $bubbles_per_line, $direction, $venv) = @_;
+    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 .= '\vskip 2mm \noindent';
 
+	# 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 .=
+		'\small {\textbf{'
+		. $linetext . '}} '
+		. ' {\footnotesize '
+		. &mt( '(Bubble once in [_1] lines)', $numlines )
+		. '} \hspace*{\fill} \\\\';
+	}
+	else {
+	    $result .= '\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;
+	    }
+	    my $preindent;
+	    if ($bubble_number > 0) {
+		$preindent = '\hspace*{3 mm}';
+	    }
+	    my $foiltext = $Apache::response::foilgroup{$name . '.text'};
+	    $foiltext =~ s/\\noindent//; # forgive me for I have sinned..
+	    $result .= '{\small \textbf{'
+		. $identifier  .$preindent
+		. $alphabet[$i]
+		. '}}$\bigcirc$'
+		. $foiltext
+	    . '\\\\';    #' stupid emacs -- it thinks it needs that apostrophe to close the quote
+	    
+	    $i++;
+	    $bubble_number++;
+	}
+
+    }	
+
+    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 $venv       - Vertical env. to use for vertical rendering.
+#  @param  $vend      - End the vertical environment being used.
+#
+#  @return string
+#  @retval - The LaTeX rendering of the resource.'
+#
+sub display_latex {
+    my ($whichfoils, $direction, $venv) = @_;
+    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 .= "\\begin{$venv}";
+	foreach my $name (@{$whichfoils}) {
+	    $result .=  '\vspace*{-2 mm}\item '
+		. $Apache::response::foilgroup{ $name . '.text' };
+	}
+	
+	$result .= "\\end{$venv}";
+    }
+    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.
+# @param $venv       - Vertical environment in which to wrap the foils.
+#
+# @return string
+# @retval String containing the rendering of the resource.
+#
+# TODO: Take into account direction!!!
+#
+sub display_pdf_form {
+    my ($whichfoils, $direction, $venv) = @_;
+    my $temp = 0;
+    my $result;
+
+    $result .= "\\begin{$venv}";
+    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++;
     }
+    $result .= "\\end{$venv}";
 
     return $result;
 }
 
 
 ##
+# 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 ) = @_;
+    my ($target,$answer,$whichfoils,$direction, $bubbles_per_line)=@_;
     my $result;
 
+
     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);
+	    $whichfoils, $target, $direction, $part,  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 );
+	my $numlines;
+	
+	# Decide how to bracket the list of foils:
 
-        if (
-            (
-                (
-                    $Apache::lonhomework::history{"resource.$part.type"} eq
-                    'randomizetry'
-                )
-                || ( $Apache::lonhomework::type eq 'randomizetry' )
-            )
-            && ( $Apache::inputtags::status[-1] eq 'CAN_ANSWER' )
-          )
-        {
+	my $vertical_env = &latex_vertical_environment();
 
-            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 $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>";
-        }
-    }
-    if ( $target ne 'tex' ) {
-        if ( $direction ne 'horizontal' ) { $result .= "<br />"; }
+	# Rendering for latex exams.
+	
+	if ( ( $Apache::lonhomework::type eq 'exam' ) )
+	{
+	    $result .= &display_latex_exam(
+		$whichfoils, $bubbles_per_line, $direction, $vertical_env);
+
+	    $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 .= &display_pdf_form($whichfoils, $direction, $vertical_env);
+	    } else {
+		$result .= &display_latex($whichfoils,  $direction, $vertical_env );
+	    }
+	    $result .= '\vskip 0 mm '; 
+       
+	}
     }
-    else { $result .= '\vskip 0 mm '; }
     return $result;
 }
 
 sub displayallanswers {
     my @names;
     if ( $Apache::response::foilgroup{'names'} ) {
-        @names = @{ $Apache::response::foilgroup{'names'} };
+	@names= @{ $Apache::response::foilgroup{'names'} };
     }
-    my $result = &Apache::response::answer_header('radiobuttonresponse');
+    my $result=&Apache::response::answer_header('radiobuttonresponse');
     foreach my $name (@names) {
-        $result .=
-          &Apache::response::answer_part( 'radiobuttonresponse',
-            $Apache::response::foilgroup{ $name . '.value' } );
+	$result.=&Apache::response::answer_part('radiobuttonresponse',
+				$Apache::response::foilgroup{$name.'.value'});
     }
-    $result .= &Apache::response::answer_footer('radiobuttonresponse');
+    $result.=&Apache::response::answer_footer('radiobuttonresponse');
     return $result;
 }
 
 sub displayanswers {
-    my ( $answer, $whichopt, $bubbles_per_line ) = @_;
+    my ($answer, $whichopt, $bubbles_per_line)=@_;
     my $result;
 
-    if ( $Apache::lonhomework::type eq 'exam' ) {
-        my $line    = int( $answer / $bubbles_per_line );
-        my $correct = ( 'A' .. 'Z' )[ $answer % $bubbles_per_line ];
-        $result .=
-          &Apache::response::answer_header( 'radiobuttonresponse', $line );
-        $result .=
-          &Apache::response::answer_part( 'radiobuttonresponse', $correct );
-    }
-    else {
-        $result .= &Apache::response::answer_header('radiobuttonresponse');
-    }
-    foreach my $name ( @{$whichopt} ) {
-        $result .=
-          &Apache::response::answer_part( 'radiobuttonresponse',
-            $Apache::response::foilgroup{ $name . '.value' } );
+    if ($Apache::lonhomework::type eq 'exam') {
+	my $line = int($answer/$bubbles_per_line);
+	my $correct = ('A'..'Z')[$answer%$bubbles_per_line];
+	$result .= &Apache::response::answer_header('radiobuttonresponse',
+						    $line);
+	$result .= &Apache::response::answer_part('radiobuttonresponse',
+						  $correct);
+    } else {
+	$result .= &Apache::response::answer_header('radiobuttonresponse');
     }
-    $result .= &Apache::response::answer_footer('radiobuttonresponse');
+    foreach my $name (@{ $whichopt }) {
+	$result.=&Apache::response::answer_part('radiobuttonresponse',
+						$Apache::response::foilgroup{$name.'.value'});
+    }
+    $result.=&Apache::response::answer_footer('radiobuttonresponse');
     return $result;
 }
 
 sub start_conceptgroup {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
-    $Apache::radiobuttonresponse::conceptgroup = 1;
-    %Apache::response::conceptgroup            = ();
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    $Apache::radiobuttonresponse::conceptgroup=1;
+    %Apache::response::conceptgroup=();
     my $result;
-    if ( $target eq 'edit' ) {
-        $result .= &Apache::edit::tag_start( $target, $token );
-        $result .=
-            &Apache::edit::text_arg( 'Concept:', 'concept', $token, '50' )
-          . &Apache::edit::end_row()
-          . &Apache::edit::start_spanning_row();
-    }
-    elsif ( $target eq 'modified' ) {
-        my $constructtag =
-          &Apache::edit::get_new_args( $token, $parstack, $safeeval,
-            'concept' );
-        if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
+    if ($target eq 'edit') {
+	$result.=&Apache::edit::tag_start($target,$token);
+	$result.=&Apache::edit::text_arg('Concept:','concept',$token,'50').
+	    &Apache::edit::end_row().&Apache::edit::start_spanning_row();
+    } elsif ($target eq 'modified') {
+	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
+						     $safeeval,'concept');
+	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
     }
     return $result;
 }
 
 sub end_conceptgroup {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
-    $Apache::radiobuttonresponse::conceptgroup = 0;
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    $Apache::radiobuttonresponse::conceptgroup=0;
     my $result;
-    if (   $target eq 'web'
-        || $target eq 'grade'
-        || $target eq 'answer'
-        || $target eq 'tex'
-        || $target eq 'analyze' )
-    {
-        &Apache::response::pick_foil_for_concept( $target,
-            [ 'value', 'text', 'location' ],
-            \%Apache::hint::radiobutton, $parstack, $safeeval );
-    }
-    elsif ( $target eq 'edit' ) {
-        $result = &Apache::edit::end_table();
+    if ($target eq 'web' || $target eq 'grade' || $target eq 'answer'  ||
+	$target eq 'tex' || $target eq 'analyze') {
+	&Apache::response::pick_foil_for_concept($target,
+						 ['value','text','location'],
+						 \%Apache::hint::radiobutton,
+						 $parstack,$safeeval);
+    } elsif ($target eq 'edit') {
+	$result=&Apache::edit::end_table();
     }
     return $result;
 }
 
 sub insert_conceptgroup {
-    my $result =
-        "\n\t\t<conceptgroup concept=\"\">"
-      . &insert_foil()
-      . "\n\t\t</conceptgroup>\n";
+    my $result="\n\t\t<conceptgroup concept=\"\">".&insert_foil()."\n\t\t</conceptgroup>\n";
     return $result;
 }
 
 sub start_foil {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
-    my $result = '';
-    if ( $target eq 'web' || $target eq 'tex' || $target eq 'analyze' ) {
-        &Apache::lonxml::startredirection;
-        if ( $target eq 'analyze' ) {
-            &Apache::response::check_if_computed( $token, $parstack, $safeeval,
-                'value' );
-        }
-    }
-    elsif ( $target eq 'edit' ) {
-        $result = &Apache::edit::tag_start( $target, $token );
-        $result .= &Apache::edit::text_arg( 'Name:', 'name', $token );
-        $result .= &Apache::edit::select_or_text_arg(
-            'Correct Option:', 'value',
-            [ 'unused', 'true', 'false' ], $token
-        );
-        my $randomize =
-          &Apache::lonxml::get_param( 'randomize', $parstack, $safeeval, '-3' );
-        if ( $randomize ne 'no' ) {
-            $result .=
-              &Apache::edit::select_arg( 'Location:', 'location',
-                [ 'random', 'top', 'bottom' ], $token );
-        }
-        $result .=
-          &Apache::edit::end_row() . &Apache::edit::start_spanning_row();
-    }
-    elsif ( $target eq 'modified' ) {
-        my $constructtag =
-          &Apache::edit::get_new_args( $token, $parstack, $safeeval, 'value',
-            'name', 'location' );
-        if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
-    }
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    my $result='';
+    if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
+	&Apache::lonxml::startredirection;
+	if ($target eq 'analyze') {
+	    &Apache::response::check_if_computed($token,$parstack,$safeeval,'value');
+	}
+    } elsif ($target eq 'edit') {
+	$result=&Apache::edit::tag_start($target,$token);
+	$result.=&Apache::edit::text_arg('Name:','name',$token);
+	$result.=&Apache::edit::select_or_text_arg('Correct Option:','value',
+						   ['unused','true','false'],
+						   $token);
+	my $randomize=&Apache::lonxml::get_param('randomize',$parstack,
+						 $safeeval,'-3');
+	if ($randomize ne 'no') {
+	    $result.=&Apache::edit::select_arg('Location:','location',
+					       ['random','top','bottom'],$token);
+	}
+	$result.=&Apache::edit::end_row().&Apache::edit::start_spanning_row();
+    } elsif ($target eq 'modified') {
+	my $constructtag=&Apache::edit::get_new_args($token,$parstack,
+						     $safeeval,'value','name',
+						     'location');
+	if ($constructtag) { $result = &Apache::edit::rebuild_tag($token); }
+    } 
     return $result;
 }
 
 sub end_foil {
-    my ( $target, $token, $tagstack, $parstack, $parser, $safeeval, $style ) =
-      @_;
-    my $text = '';
-    if ( $target eq 'web' || $target eq 'tex' || $target eq 'analyze' ) {
-        $text = &Apache::lonxml::endredirection;
-    }
-    if (   $target eq 'web'
-        || $target eq 'grade'
-        || $target eq 'answer'
-        || $target eq 'tex'
-        || $target eq 'analyze' )
-    {
-        my $value = &Apache::lonxml::get_param( 'value', $parstack, $safeeval );
-        if ( $value ne 'unused' ) {
-            my $name =
-              &Apache::lonxml::get_param( 'name', $parstack, $safeeval );
-            if ( $name eq "" ) {
-                &Apache::lonxml::warning(
-                    &mt(
-'Foils without names exist. This can cause problems to malfunction.'
-                    )
-                );
-                $name = $Apache::lonxml::curdepth;
-            }
-            if ( defined( $Apache::response::foilnames{$name} ) ) {
-                &Apache::lonxml::error(
-                    &mt(
-'Foil name [_1] appears more than once. Foil names need to be unique.',
-                        '<b><tt>' . $name . '</tt></b>'
-                    )
-                );
-            }
-            $Apache::response::foilnames{$name}++;
-            my $location =
-              &Apache::lonxml::get_param( 'location', $parstack, $safeeval );
-            if ( $Apache::radiobuttonresponse::conceptgroup
-                && !&Apache::response::showallfoils() )
-            {
-                push @{ $Apache::response::conceptgroup{'names'} }, $name;
-                $Apache::response::conceptgroup{"$name.value"}    = $value;
-                $Apache::response::conceptgroup{"$name.text"}     = $text;
-                $Apache::response::conceptgroup{"$name.location"} = $location;
-            }
-            else {
-                push @{ $Apache::response::foilgroup{'names'} }, $name;
-                $Apache::response::foilgroup{"$name.value"}    = $value;
-                $Apache::response::foilgroup{"$name.text"}     = $text;
-                $Apache::response::foilgroup{"$name.location"} = $location;
-            }
-        }
+    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
+    my $text='';
+    if ($target eq 'web' || $target eq 'tex' || $target eq 'analyze') {
+	$text=&Apache::lonxml::endredirection;
+    }
+    if ($target eq 'web' || $target eq 'grade' || $target eq 'answer'
+	|| $target eq 'tex' || $target eq 'analyze') {
+	my $value = &Apache::lonxml::get_param('value',$parstack,$safeeval);
+	if ($value ne 'unused') {
+	    my $name = &Apache::lonxml::get_param('name',$parstack,$safeeval);
+	    if ($name eq "") {
+		&Apache::lonxml::warning(&mt('Foils without names exist. This can cause problems to malfunction.'));
+		$name=$Apache::lonxml::curdepth;
+	    }
+	    if (defined($Apache::response::foilnames{$name})) {
+		&Apache::lonxml::error(&mt('Foil name [_1] appears more than once. Foil names need to be unique.','<b><tt>'.$name.'</tt></b>'));
+	    }
+	    $Apache::response::foilnames{$name}++;
+	    my $location =&Apache::lonxml::get_param('location',$parstack,
+						     $safeeval);
+	    if ( $Apache::radiobuttonresponse::conceptgroup
+		 && !&Apache::response::showallfoils() ) {
+		push @{ $Apache::response::conceptgroup{'names'} }, $name;
+		$Apache::response::conceptgroup{"$name.value"} = $value;
+		$Apache::response::conceptgroup{"$name.text"} = $text;	
+		$Apache::response::conceptgroup{"$name.location"} = $location;
+	    } else {
+		push @{ $Apache::response::foilgroup{'names'} }, $name;
+		$Apache::response::foilgroup{"$name.value"} = $value;
+		$Apache::response::foilgroup{"$name.text"} = $text;
+		$Apache::response::foilgroup{"$name.location"} = $location;
+	    }
+	}
     }
     return '';
 }