--- loncom/homework/bridgetask.pm	2006/11/09 21:31:11	1.200
+++ loncom/homework/bridgetask.pm	2007/01/13 06:11:17	1.219
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.200 2006/11/09 21:31:11 albertel Exp $
+# $Id: bridgetask.pm,v 1.219 2007/01/13 06:11:17 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -98,6 +98,7 @@ sub check_in {
 	&check_in_sequence($user,$domain,$slot_name);
     } else {
 	&create_new_version($type,$user,$domain,$slot_name);
+	&Apache::structuretags::finalize_storage();
     }
     return 1;
 }
@@ -380,6 +381,13 @@ sub nest {
     }
 }
 
+sub start_delay {
+    push(@delay,1);
+}
+sub end_delay {
+    pop(@delay);
+}
+
 sub nested_parse {
     my ($str,$env,$args) = @_;
     my @old_env = @Apache::scripttag::parser_env;
@@ -583,7 +591,6 @@ sub start_Task {
 	    &Apache::structuretags::page_start($target,$token,$tagstack,
 					       $parstack,$parser,$safeeval,
 					       $name,&style($target));
-	$result .= '<div class="LC_task">'."\n";
     }
 
     if ($target eq 'web' && $env{'request.state'} ne 'construct') {
@@ -632,6 +639,11 @@ sub start_Task {
 					  'slot' => $slot_name});
 	    ($version,$previous)=&get_version();
 	}
+	
+	my $status_id = 
+	    ($previous || $status eq 'SHOW_ANSWER') ? 'LC_task_feedback'
+	                                            : 'LC_task_take';
+	$result .= '<div class="LC_task" id="'.$status_id.'">'."\n";
 
 	push(@Apache::inputtags::status,$status);
 	$Apache::inputtags::slot_name=$slot_name;
@@ -699,6 +711,7 @@ sub start_Task {
 	      $target eq 'webgrade') {
 	my $webgrade='yes';
 	if ($target eq 'webgrade') {
+	    $result .= '<div class="LC_task">'."\n";
 	    $result.= "\n".'<div class="LC_GRADING_task">'."\n".
 		'<script type="text/javascript" 
                          src="/res/adm/includes/task_grading.js"></script>';
@@ -791,6 +804,9 @@ sub start_Task {
 	if ($target eq 'webgrade') {
 	    $result.="\n".'<div id="LC_GRADING_criterialist">';
 	    &Apache::lonxml::startredirection();
+	    &start_delay();
+	    $dimension{$top}{'result'}=$result;
+	    undef($result);
 	}
     } elsif ($target eq 'edit') {
 	$result.=$form_tag_start.
@@ -1051,27 +1067,30 @@ DONEBUTTON
 		    $start_time=&Apache::lonlocal::locallocaltime($start_time);
 
 		    my $status = 
-			"\n<div class='LC_$bt_status LC_criteria'>\n\t";
+			"\n<div class='LC_$bt_status LC_criteria LC_task_overall_status'>\n\t";
 		    
+		    my $dim = $top;
+		    my %counts = &get_counts($dim,undef,$parstack,
+					     $safeeval);
+		    my $question_status ="\n\t<p>".
+			&question_status_message(\%counts,-1).
+			"</p>\n";
+
 		    if ($bt_status eq 'pass')  {
 			$status.='<h2>You passed the '.$title.' given on '.
 			    $start_time.'</h2>';
+			$status.=$question_status;
 		    }
 		    if ($bt_status eq 'fail')  {
 			$status.='<h2>You did not pass the '.$title.' given on '.
 			    $start_time.'</h2>';
+			$status.=$question_status;
 			if (!$previous) {
 			    $status.=&add_request_another_attempt_button();
 			}
 		    }
-		    $status.="\n".'</div>'."\n";
-		    my $dim = $top;
-		    my %counts = &get_counts($dim,undef,$parstack,
-					     $safeeval);
-		    $status.="\n<div class='LC_$bt_status LC_criteria LC_task_overall_status'>\n\t<p>".
-			&question_status_message(\%counts,-1).
-			"</p>\n</div>\n";
 		    
+		    $status.="\n".'</div>'."\n";
 
 		    foreach my $id (@{$dimension{$dim}{'criterias'}}) {
 			my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
@@ -1103,7 +1122,8 @@ DONEBUTTON
 	}
 	
 
-	if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous) {
+	if ($target eq 'grade' && !$env{'form.webgrade'} && !$previous
+	    && $status eq 'CAN_ANSWER') {
 	    my $award='SUBMITTED';
 	    &Apache::essayresponse::file_submission("$version.0",'bridgetask',
 						    'portfiles',\$award);
@@ -1257,7 +1277,13 @@ DONEBUTTON
 	    &Apache::structuretags::finalize_storage();
 	}
     } elsif ($target eq 'webgrade') {
-	$result.=&Apache::lonxml::endredirection();
+	if (&nest()) {
+	    &Apache::lonxml::endredirection();
+	    &end_delay();
+	    $result.=$dimension{$top}{'result'};
+	} else {
+	    $result.=&Apache::lonxml::endredirection();
+	}
 	my $dim = $top;
 	foreach my $id (@{$dimension{$dim}{'criterias'}} ) {
 	    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
@@ -1269,7 +1295,12 @@ DONEBUTTON
 					     [@_]);
 		$criteria = &layout_webgrade_Criteria($dim,$id,$criteria);
 		my $internal_location=&internal_location($id);
-		$result=~s/\Q$internal_location\E/$criteria/;
+		if ($result =~ m/\Q$internal_location\E/) {
+		    $result=~s/\Q$internal_location\E/$criteria/;
+		} else {
+		    $result.=$criteria;
+		}
+
 	    }
 	}
         $result.="</div>";
@@ -1553,9 +1584,16 @@ sub show_queue {
 		my $ekey=&escape($key);
 		my ($action,$description,$status)=('select',&mt('Select'));
 		if (exists($queue{"$key\0locked"})) {
+		    my ($locker,$time) = 
+			&get_lock_info($queue{"$key\0locked"});
+		    if ($time) {
+			$time = 
+			    &Apache::lonnavmaps::timeToHumanString($time,
+								   'start');
+		    }
 		    my $me=$env{'user.name'}.':'.$env{'user.domain'};
-		    $status=&mt('Locked by <tt>[_1]</tt>',$queue{"$key\0locked"});
-		    if ($me eq $queue{"$key\0locked"}) {
+		    $status=&mt('Locked by <tt>[_1]</tt> [_2]',$locker,$time);
+		    if ($me eq $locker) {
 			($action,$description)=('resume',&mt('Resume'));
 		    } else {
 			($action,$description)=('unlock',&mt('Unlock'));
@@ -1665,7 +1703,7 @@ sub queue_key_locked {
     my ($key_locked,$value)=
 	&Apache::lonnet::get($queue,["$key\0locked"],$cdom,$cnum);
     if ($key_locked eq "$key\0locked") {
-	return $value;
+	return &get_lock_info($value);
     }
     return undef;
 }
@@ -1746,6 +1784,24 @@ sub pick_from_queue_data {
     return undef;
 }
 
+sub get_lock_info {
+    my ($lock_info) = @_;
+    if (wantarray) {
+	if (ref($lock_info) eq 'ARRAY') {
+	    return @{$lock_info};
+	} else {
+	    return ($lock_info);
+	}
+    } else {
+	if (ref($lock_info) eq 'ARRAY') {
+	    return $lock_info->[0];
+	} else {
+	    return $lock_info;
+	}
+    }
+    return;
+}
+
 sub find_mid_grade {
     my ($queue,$symb,$cdom,$cnum)=@_;
     my $todo=&unescape($env{'form.gradingkey'});
@@ -1757,7 +1813,7 @@ sub find_mid_grade {
     my $regexp="^$symb\0.*\0locked\$";
     my %locks=&Apache::lonnet::dump($queue,$cdom,$cnum,$regexp);
     foreach my $key (keys(%locks)) {
-	my $who=$locks{$key};
+	my $who= &get_lock_info($locks{$key});
 	if ($who eq $me) {
 	    $todo=$key;
 	    $todo=~s/\0locked$//;
@@ -1773,7 +1829,7 @@ sub lock_key {
     my (undef,$cid)=&Apache::lonnet::whichuser();
     my $cnum=$env{'course.'.$cid.'.num'};
     my $cdom=$env{'course.'.$cid.'.domain'};
-    my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> $me},
+    my $success=&Apache::lonnet::newput($queue,{"$todo\0locked"=> [$me,time]},
 					$cdom,$cnum);
     &Apache::lonxml::debug("success $success $todo");
     if ($success eq 'ok') {
@@ -2049,7 +2105,7 @@ sub start_Setup {
     my $dim = &get_id($parstack,$safeeval);
     push(@Apache::bridgetask::dimension,$dim);
     &Apache::lonxml::startredirection();
-    return &internal_location($dim);
+    return;# &internal_location($dim);
 }
 
 {
@@ -2101,11 +2157,14 @@ sub start_Dimension {
 	$dimension{$top}{'criteria.'.$dim.'.mandatory'}=
 	    &Apache::lonxml::get_param('Mandatory',$parstack,$safeeval);
 	push(@{$dimension{$top}{'criterias'}},$dim);
+	$dimension{$dim}{'nested'}=$top;
     }
     push(@Apache::bridgetask::dimension,$dim);
     &Apache::lonxml::startredirection();
-    &enable_dimension_parsing($dim);
-    return &internal_location($dim);
+    if (!&skip_dimension_parsing($dim)) {
+	&enable_dimension_parsing($dim);
+    }
+    return;# &internal_location($dim);
 }
 
 sub start_QuestionText {
@@ -2226,13 +2285,15 @@ sub end_Dimension {
 		}
 		my $dim_info=
 		    "\n<div class='LC_$dim_status LC_question_grade'>\n\t";
-		my $question = ('sub' x $dimension{$dim}{'depth'}).'question';
-		$question =~ s/^(.)/uc($1)/e;
+		my $ucquestion = 
+		    my $question = 
+		    ('sub' x $dimension{$dim}{'depth'}).'question';
+		$ucquestion =~ s/^(.)/uc($1)/e;
 		if ($dim_status eq 'pass') {
-		    $dim_info.='<h3>'.$question.' : you passed this '.$mandatory.' question</h3>';
+		    $dim_info.='<h3>'.$ucquestion.' : you passed the above '.$mandatory.' '.$question.'</h3>';
 		}
 		if ($dim_status eq 'fail') {
-		    $dim_info.='<h3>'.$question.' : you did not pass this '.$mandatory.' question</h3>';
+		    $dim_info.='<h3>'.$ucquestion.' : you did not pass the above '.$mandatory.' '.$question.'</h3>';
 		}
 		my %counts = &get_counts($dim,$instance,$parstack,
 					 $safeeval);
@@ -2246,18 +2307,44 @@ sub end_Dimension {
 				@{$dimension{$dim}{'criterias'}}) {
 		    my $type = $dimension{$dim}{'criteria.'.$id.'.type'};
 		    if ($type eq 'dimension') {
-			$result.=$dimension{$id}{'result'};
-			next;
+			if (defined($dimension{$id}{'result'})) {
+			    $result.=$dimension{$id}{'result'};
+			    next;
+			} else {
+			    $dim_info .=
+				&nested_parse(\$dimension{$dim}{'criteria.'.$id},
+					      [@_],{'set_dim_id' => $id});
+			}
+		    } else {
+			my $criteria =
+			    &nested_parse(\$dimension{$dim}{'criteria.'.$id},
+					  [@_]);
+			$dim_info .= &layout_web_Criteria($dim,$id,$criteria);
 		    }
-		    my $criteria = 
-			&nested_parse(\$dimension{$dim}{'criteria.'.$id},
-				      [@_]);
-		    $dim_info .= &layout_web_Criteria($dim,$id,$criteria);
 		}
+		# puts the results at the end of the dimension
+		$result .= $dim_info;
 
-		my $internal_location=&internal_location($dim);
-		$result=~s/\Q$internal_location\E/$dim_info/;
+		# puts the results at the beginning of the dimension
+		# my $internal_location=&internal_location($dim);
+		# $result=~s/\Q$internal_location\E/$dim_info/;
+	    }
+	}
+	if ($result !~ /^\s*$/s) {
+	    # FIXME? this maybe unneccssary in the future, (CSE101 BT
+	    # from Fall 2006 geenrate a div that attempts to hide some
+	    # of the output in an odd way, this is a workaround so
+	    # those old ones will continue to work.  # It puts the
+	    # LC_question div to come after any starting closie div
+	    # that the dimension produces
+	    if ($result =~ m{^\s*</div>}) {
+		$result =~ s{^(\s*</div>)}
+		            {$1\n<div id="$dim" class="LC_question">};
+	    } else {
+		$result = "\n".'<div id="'.$dim.'" class="LC_question">'.
+		    "\n".$result;
 	    }
+	    $result .= "\n</div>\n";
 	}
     } elsif ($target eq 'webgrade') {
 	# in case of any side effects that we need
@@ -2281,7 +2368,11 @@ sub end_Dimension {
 					     [@_]);
 		$criteria = &layout_webgrade_Criteria($dim,$id,$criteria);
 		my $internal_location=&internal_location($id);
-		$result=~s/\Q$internal_location\E/$criteria/;
+		if ($result =~ m/\Q$internal_location\E/) {
+		    $result =~ s/\Q$internal_location\E/$criteria/;
+		} else {
+		    $result.=$criteria ;
+		}
 	    }
 	}
 	if (&nest()) {
@@ -2375,7 +2466,7 @@ sub question_status_message {
 	foreach my $type ('cri','dim') {
 	    if ($counts->{$req.'_'.$type}) {
 		push(@sections,
-		     $counts->{$req.'_'.$type.'_passed'}.' of '.
+		     $counts->{$req.'_'.$type.'_passed'}.' of the '.
 		     $counts->{$req.'_'.$type}.' '.
 		     $req{$req}.' '.$type{$type});
 	    }
@@ -2395,7 +2486,15 @@ sub question_status_message {
     $status .= '.';
     if ($counts->{'opt'}) {
 	$status .= ' You were required to pass '.$counts->{'opt_req'}.
-	    ' optional component'.($counts->{'opt_req'} == 1?'':'s');
+	    'optional ';
+	if ($counts->{'opt_dim'} + $counts->{'man_dim'} < 1) {
+	    $status .=
+		' component'.($counts->{'opt_req'} == 1?'':'s');
+	} else {
+	    $status .=
+		($counts->{'opt_req'} == 1?'criterion':'criteria');
+	}
+	$status .= '.';
     }
     return $status;
 }
@@ -2590,12 +2689,12 @@ sub start_Criteria {
 	my $dim = &get_dim_id();
 	my $id=&get_id($parstack,$safeeval);
 	if ($target eq 'web' || $target eq 'webgrade') {
-	    if ($target eq 'webgrade' && $dim ne 'top') {
+	    if ($target eq 'webgrade') {
 		&Apache::lonxml::debug(" for $dim $id stashing results into $dim ");
 		$dimension{$dim}{'result'} .= &internal_location($id);
 	    } else {
 		&Apache::lonxml::debug(" not stashing $dim $id");
-		$result .= &internal_location($id);
+		#$result .= &internal_location($id);
 	    }
 	}
 	&Apache::lonxml::debug("Criteria $id with $dim");
@@ -2633,7 +2732,10 @@ sub layout_web_Criteria {
     $status_display=~s/^([a-z])/uc($1)/e;
     my $criteria_info.=
 	'<div class="LC_'.$status.' LC_criteria">'."\n\t".'<h4>'
-	.$mandatory.' Criteria</h4>'."\n\t".'<p>'."\n";
+	.$mandatory.' Criteria</h4>'."\n\t".'<p class="LC_criteria_text">'
+	."\n";
+    $criteria =~ s/^\s*//s;
+    $criteria =~ s/\s*$//s;
     $criteria_info.= $criteria;
     $criteria_info.="\n\t".'</p>'.
 	"\n\t".'<p class="LC_grade">'.$status_display.'</p>';
@@ -2666,35 +2768,30 @@ sub layout_webgrade_Criteria {
 	if ($status eq $which) { $checked{$which} = 'checked="checked"'; }
     }
     if (!%checked) { $checked{'ungraded'} = 'checked="checked"'; }
-    
+    my $buttons;
+    foreach my $which  ('ungraded','fail','pass','review') {
+	$buttons .= <<END_BUTTON;
+		<label class="LC_GRADING_$which">
+			<input type="radio" name="HWVAL_$link" value="$which" $checked{$which} />
+			$lt{$which}
+		</label>
+END_BUTTON
+    }
+    $criteria =~ s/^\s*//s;
+    $criteria =~ s/\s*$//s;
     my $result = <<END_CRITERIA;
-  <div class="LC_GRADING_criteria">
-     <div class="LC_GRADING_criteriatext">
-	$criteria
-     </div>
-     <div class="LC_GRADING_grade">
-       <label class="LC_GRADING_ungraded">
-         <input type="radio" name="HWVAL_$link" value="ungraded" $checked{'ungraded'} />
-	 $lt{'ungraded'}
-       </label>
-       <label class="LC_GRADING_fail">
-         <input type="radio" name="HWVAL_$link" value="fail" $checked{'fail'} />
-	 $lt{'fail'}
-       </label>
-       <label class="LC_GRADING_pass">
-         <input type="radio" name="HWVAL_$link" value="pass" $checked{'pass'} />
-	 $lt{'pass'}
-       </label>
-       <label class="LC_GRADING_review">
-         <input type="radio" name="HWVAL_$link" value="review" $checked{'review'} />
-	 $lt{'review'}
-       </label>
-     </div>
-     <label class="LC_GRADING_comment">
-       $lt{'comment'}
-       <textarea class="LC_GRADING_comment_area" name="HWVAL_comment_$link">$comment</textarea>
-     </label>
-  </div>
+<div class="LC_GRADING_criteria">
+	<div class="LC_GRADING_criteriatext">
+		$criteria
+	</div>
+	<div class="LC_GRADING_grade">
+$buttons
+	</div>
+	<label class="LC_GRADING_comment">
+		$lt{'comment'}
+		<textarea class="LC_GRADING_comment_area" name="HWVAL_comment_$link">$comment</textarea>
+	</label>
+</div>
 END_CRITERIA
     $result .= &grading_history($version,$dim,$id);
     return $result;