#!/usr/bin/perl
#
# $Id: tqrs.pl,v 1.42 2006/11/08 21:40:29 ddoughty Exp $
#
# Source File: tqrs.pl

# Get config
require 'sitecfg.pl';
require 'testlib.pl';
require 'sbalib.pl';
require 'tstatlib.pl';

&app_initialize;

print "Content-Type: text/html\n\n";

if (&get_session($FORM{'tid'})) {
	################################################################
	# REMEDIATION FIX
	# Clear the remediation
	$FORM{'remediateonpost'} = "";
	################################################################
	$FORM{'submit'}=~ tr/+/ /;
	&LanguageSupportInit();

	## DED 2005-11-09
	#  Check for rotating IP
	&get_test_profile( $SESSION{'clid'}, $FORM{'tstid'});
	if ($TEST{'tstalwrotip'} ne 'Y' && $SESSION{'ipaddr'} ne $ENV{'REMOTE_ADDR'} ) {
	       &logger::logwarn("SESSION{'ipaddr'} ($SESSION{'ipaddr'}) !== ENV{'REMOTE_ADDR'} ($ENV{'REMOTE_ADDR'}) for session ID $FORM{'tid'} on test ID $FORM{'tstid'}");
		&show_illegal_access_warning("user");
		exit();
	}

	&get_test_sequence( $SESSION{'clid'}, $SESSION{'uid'}, $FORM{'tstid'});

# Test to see if the Pre-test Survey has been completed.
# It will not be given a second time.
# HBI - 2009/01/05
	my $trash3 = join($pathsep, $testcomplete, "$SESSION{'clid'}.$SESSION{'uid'}.$TEST_SESSION{'profb'}");
	if (-e $trash3) {
		$TEST_SESSION{'profb'} = "" ;
	}

	@tsbt = ( 	$TEST_SESSION{'dscl'}, $TEST_SESSION{'profb'}, $TEST_SESSION{'tstid'},
				$TEST_SESSION{'profa'}, $TEST_SESSION{'srvy'} );
	$tlastsubtest = 2;
	for (0 .. $#tsbt) {
		if ($tsbt[$_] ne '') {$tlastsubtest = $_ ;}
	}
	($tstate,$tsubtest,$tqno) = split(/\./, $TEST_SESSION{'state'});
#&dbgprint("Tstate= $tstate Tsubtest= $tsubtest \n");
        &log_test_stats();
	if (($FORM{'submit'} eq "$xlatphrase[6]") || ($FORM{'submit'} eq "$xlatphrase[5]")) {
		my $anonflags = join(';',$SESSION{'anonymity'},"$tsubtest.$tsbt[$tsubtest].$FORM{'anonsubmit'}");
		&set_session($SESSION{'tid'},"anonymity",$anonflags);
	}
####################################################
# TIME EXPIRED					   #
# This is no longer used, replaced by texp.pl      #
####################################################
	if ($tstate eq $TEST_STATES{'_TERMINATED'}) {
## TERMINATED BY ADMIN
		&terminated_by_administrator();
		&make_anonymous();
	} elsif ($tstate eq $TEST_STATES{'_PAUSED_BY_USER'}) {
		if ($FORM{'submit'} eq "$xlatphrase[547]") {
## RESUME BUTTON
			&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Resume $TEST{'id'}", $FORM{'tmreset'});
			($tstate,$tsubtest,$tqno) = split(/\./, $TEST_SESSION{'state'});
			&get_client_profile($TEST_SESSION{'clid'});
## v support for wilcard login
# (replaced)
#			&get_candidate_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'});
# (with)
			if ($SESSION{'taclid'} eq '') {
				&get_candidate_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'});
			} else {
				&get_tacl_profile();
			}
## ^ support for wilcard login
			$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
			&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
			my @resps = split('&', $SUBTEST_RESPONSES{$tsubtest});
			@stqids = split(/&/, $SUBTEST_QUESTIONS{$tsubtest});
			$TEST_SESSION{'noq'} = $#stqids;
			### DED 3/9/05 Check for review mode
			if ($#resps == $TEST_SESSION{'noq'}) {
				$FORM{'review'} = $tqno;
			}
			@resp = ();
			if ($TEST{'emlstartopt'} eq 'Y' && $TEST{'ntfy'} ne '') {
		                if ($FORM{'submit'} eq "$xlatphrase[547]") {
					&send_resume_notification();
				} else {
					&send_start_notification();
				}
			}
			if ($TEST{'emlstartropt'} eq 'Y' && &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "registrar") eq 'Y') {
				$registrareml = &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "eml");
				if ($registrareml ne '') {
					if ($FORM{'submit'} eq "$xlatphrase[547]") {
						&send_resume_notification($registrareml);
					} else {
						&send_start_notification($registrareml);
					}
				}
			}
			if (($TEST{'seq'} eq 'std') || ($TEST{'seq'} eq 'svy') || $TEST{'seq'} eq 'dmg') {
				$tstate = $TEST_STATES{'_IN_PROGRESS'};
				$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
				$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
				if ($TEST{'seq'} eq 'svy') {
					$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
					&show_single_form_test();
				} elsif ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y') {
						if ($TEST{'cnl'} eq '1') {
							$tqno=1;
						} else {
							$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
						}
						$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
						&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
						&show_group($tsubtest, $tqno);
				} else { 	# must be std
					if ($TEST{'cnl'} eq '1') {
						$tqno=1;
					} else {
						$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
					}
					$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
					&show_question($tsubtest, $tqno);
				}
			} elsif ($TEST{'seq'} eq 'cfa') {
				&resume_cfa();
			}
		} else {
			$TEST_SESSION{'navbuttons'}=&set_subtest_nav_buttons($tstate, $tsubtest);
			&show_template("illentry");
		}
	} else {
		&get_client_profile($TEST_SESSION{'clid'});
## v support for wilcard login
# (replaced)
#		&get_candidate_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'});
# (with)
		if ($SESSION{'taclid'} eq '') {
			&get_candidate_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'});
		} else {
			&get_tacl_profile();
		}
## ^ support for wilcard login
		### DED 11/1/2002 Changed from subtst to tstid so notify
		###		  check will work
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'tstid'});
		### DED 8/19/2002 Replaced following line to promote_test_seq
		###	when doing a survey before the test
		#if ($FORM{'submit'} eq "$xlatphrase[548]" || $FORM{'submit'} eq "$xlatphrase[550]" )
		if ($FORM{'submit'} eq "$xlatphrase[548]" || $FORM{'submit'} eq "$xlatphrase[550]" || $FORM{'submit'} eq "$xlatphrase[551]" || $FORM{'submit'} eq "$xlatphrase[547]") {
## START OR REVIEW CFA BUTTON OR RESUME
			&promote_test_sequence( $testpending, $testinprog, $TEST_STATES{'_PENDING'});
			if ($FORM{'submit'} eq "$xlatphrase[548]" || $FORM{'submit'} eq "$xlatphrase[551]") {
				$starttime = &format_date_time("dd-mmm-yyyy hh:nn:ss GMT", "1", "0");
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Start $TEST{'id'}", $starttime);
			} elsif ($FORM{'submit'} eq "$xlatphrase[547]") {
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Resume $TEST{'id'}");
			} else {
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Review CFA $TEST{'id'}");
			}
			if ($TEST{'emlstartopt'} eq 'Y' && $TEST{'ntfy'} ne '') {
                       		### hkh 03/04 differentiate start & resume bug#76
		              	if ($FORM{'submit'} eq "$xlatphrase[547]") {
					&send_resume_notification();
				} else {
					&send_start_notification();
				}
			}
			if ($TEST{'emlstartropt'} eq 'Y' && &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "registrar") eq 'Y') {
				$registrareml = &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "eml");
				if ($registrareml ne '') {
					if ($FORM{'submit'} eq "$xlatphrase[547]") {
						&send_resume_notification($registrareml);
					} else {
						&send_start_notification($registrareml);
					}
				}
			}
		}
		### DED 11/01/2002 Moved 2 lines from above so notify works
		$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
		($tstate,$tsubtest,$tqno) = split(/\./, $TEST_SESSION{'state'});
		if ($tstate eq $TEST_STATES{'_PENDING'}) {
			$tstate = $TEST_STATES{'_IN_PROGRESS'};
			$tsubtest = 0;
			while ($tsbt[$tsubtest] eq '' && $tsubtest < 5) {$tsubtest++;}
			$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
			if ($tsubtest < 5) {
				&get_subtest_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
				$TEST_SESSION{'tmreset'} = $SUBTEST{'maxtmfmt'};
			}
			$tstate = $TEST_STATES{'_IN_PROGRESS'};
			$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
			$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
			@stqids = split(/&/, $SUBTEST_QUESTIONS{$tsubtest});
			$TEST_SESSION{'noq'} = $#stqids;
			if ($tsubtest eq 0) {
				$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
				&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
				$TEST_SESSION{'navbuttons'}=&set_subtest_nav_buttons($tstate, $tsubtest);
				if ($SUBTEST{'cfa'} eq '') {
					@dscllines = &get_data("$TEST_SESSION{'subtest'}.$TEST_SESSION{'clid'}");
					$dscltext = "";
					foreach $dsclline (@dscllines) {
						$dsclline =~ s/\r//g;
						$dsclline =~ s/\n//g;
						$dscltext = join('<BR>', $dscltext, $dsclline);
					}
					$TEST_SESSION{'agreement'} = $dscltext;
				} else {
					$TEST_SESSION{'agreement'} = $SUBTEST{'cfa'};
				}
				&show_template("agreement");
			} else {
				&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
				if ($TEST{'seq'} eq 'svy') {
					$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
					&show_single_form_test();
				} elsif ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y') {
						$tqno=1; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
						$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
						&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
						&show_group($tsubtest, $tqno);
				} else {
#
# Worksheet printing support
#
					if ($TEST{'Ins'} ne '') {
						$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
						$QUESTION{'id'} = "0";
						&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
						&show_test_worksheets($TEST_SESSION{'clid'}, $TEST{'id'});
					} else {
						$tqno=1; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
						$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
						&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
						&show_question($tsubtest, $tqno);
					}
				}
			}
		} elsif ($tstate eq $TEST_STATES{'_IN_PROGRESS'}) {
			&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
################################################################
# REMEDIATION FIX
# do a little magic to remediate the last question if
# remediation is on posting of answer
#	if the done button was submitted, then change to next button
#	if the OK button was submitted and this is the last question
#		then change it to the done button.
################################################################
#&dbgprint("REMEDIATION FIX:tqrs:190 Done button\n");
			if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
				if (($FORM{'submit'} eq "$xlatphrase[5]") || ($FORM{'submit'} eq "$xlatphrase[6]")) {
## DONE : CONTINUE BUTTONS
					if ($FORM{'RemediationOKButton'} ne "") {
						$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
						&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
						$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
						&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
						&put_question_response($tsubtest, $tqno);

						$FORM{'remediateonpost'} = &remediate_question($tsubtest,$tqno);
						$FORM{'remediateonpost'} .= "<input type=hidden name=\"RemediationOKButton\" value=\"$FORM{'submit'}\">";
						if ($FORM{'remediated'} ne "Y") {
## CHANGE TO NEXT BUTTON
							$FORM{'submit'} = "$xlatphrase[3]";
#&dbgprint("REMEDIATION FIX:tqrs:206 Done button\n");
						}
						$FORM{'RemediationOKButton'} = "";
					}
				} else {
					if ($FORM{'submit'} eq "$xlatphrase[566]") {
## OK BUTTON - returning from remediation on posting of last question answer
						unless ($FORM{'RemediationOKButton'} eq "") {$FORM{'submit'} = $FORM{'RemediationOKButton'};}
#&dbgprint("REMEDIATION FIX:tqrs:214 $FORM{'submit'} $FORM{'RemediationOKButton'}\n");
					}
						$FORM{'RemediationOKButton'} = "";
				}
			}
################################################################
			if ($FORM{'submit'} eq "$xlatphrase[488]") {
## I DECLINE BUTTON
				$tstate=$TEST_STATES{'_IN_PROGRESS'};
				$tsubtest=0; $tqno=0;
				$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
				&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
				&promote_test_sequence($testinprog, $testcomplete, $TEST_STATES{'_DECLINED'});
				$TEST_SESSION{'navbuttons'} = &set_subtest_nav_buttons($tstate, $tsubtest);
				if ($TEST{'ntfy'} ne '') {
					&send_declined_notification();
				}
				&show_template("tdecline");
			} elsif ($FORM{'submit'} eq "$xlatphrase[542]") {
## PAUSE BUTTON
				### DED 11/27/04 Save question before pausing
				### DED 09/16/05 do put_several if dmg & group
				if ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y') {
					$tmptqno = $tqno;
					&put_several_questions($tqno);
					# Reload last ques info
					$tqno = $tmptqno;
					$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
					&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
				} else {
					$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
					&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
					&put_question_response($tsubtest, $tqno);
				}
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Pause $TEST{'id'}");
				$tstate=$TEST_STATES{'_PAUSED_BY_USER'};
				$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
				$SUBTEST_SUMMARY{$tsubtest} = "Paused By User\&$FORM{'tmreset'}";
				&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
				$TEST_SESSION{'navbuttons'} = &set_subtest_nav_buttons($tstate, $tsubtest);
				if ($TEST{'emlpauseopt'} eq 'Y' && $TEST{'ntfy'} ne '') {
                                	&send_pause_notification();
				}
				if ($TEST{'emlpauseropt'} eq 'Y' && &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "registrar") eq 'Y') {
					$registrareml = &get_a_key("cnd.$CLIENT{'clid'}", $CANDIDATE{'createdby'}, "eml");
					if ($registrareml ne '') {
						&send_pause_notification($registrareml);
					}
				}
				&show_template("tpause");
			} elsif ($FORM{'submit'} eq "$xlatphrase[5]") {
## DONE BUTTON
				$endtime = &format_date_time("dd-mmm-yyyy hh:nn:ss GMT", "1", "0");
				$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
				&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
				### DED 9/13/2005 Changed
				#if ( $tsubtest > 2 || $TEST{'scr'} eq '3' || $TEST{'emlcndopt'} ne 'Y') 
				### to
				if ( $tsubtest > 2 || $TEST{'scr'} eq '3' || !($TEST{'emlcndopt'} eq 'Y' || $TEST{'remt'} ne '0')) {
					if (($TEST{'seq'} eq 'svy') || ($TEST{'seq'} eq 'dmg')) {
						$TEST_SESSION{'message'} = "$xlatphrase[657]";
					} else {
						$TEST_SESSION{'message'} = "$xlatphrase[658]";
					}
					$tetmplt = "tend";
				} else {
					$tetmplt = "tsubend";
				}
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Complete $TEST{'id'}", "$endtime");
				if (($TEST{'seq'} eq 'svy') || ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y')) {
					$TEST{'bars'} = "N";
					&single_form_test_done();
				} else {
					if ($TEST{'emlcndopt'} ne 'Y') { $TEST{'bars'} = "N";}
					&test_is_done();
				}
				&make_anonymous();
			} elsif ($FORM{'submit'} eq "$xlatphrase[6]") {
## CONTINUE BUTTON
				$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
				&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
				&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Section $TEST{'id'} Complete");
				if ($TEST{'seq'} eq 'svy') {
					&single_form_test_continue();
				} else {
					&test_continue();
				}
			} else {
				if ($FORM{'submit'} eq "$xlatphrase[487]") {
## I ACCEPT BUTTON
#&dbgprint("I ACCEPT BUTTON\n");
					$SUBTEST_RESPONSES{'0'} = $FORM{'submit'};
#&dbgprint("\t$tsbt{'subtest'}:$tsubtest:$tqno\n");
					$tsubtest++;
					while ($tsbt[$tsubtest] eq '' && $tsubtest < 5) {$tsubtest++;}
					if ($tsubtest < 5) {
						$TEST_SESSION{'tmreset'} = $TEST{'maxtmfmt'};
					}
					$tqno=1;
#&dbgprint("\t$tsbt{'subtest'}:$tsubtest:$tqno\n");
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
					$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
					&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
					### DED 2/22/05 Have to log after 
					#   get_test_profile so will log 
					#   correct subtest
					&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Start $TEST{'id'}");
#&dbgprint("\tget_test_profile($TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'})\n");
				} elsif ($FORM{'submit'} eq "$xlatphrase[547]") {
## RESUME BUTTON
				my @resps = split('&', $SUBTEST_RESPONSES{$tsubtest});
				@stqids = split(/&/, $SUBTEST_QUESTIONS{$tsubtest});
				$TEST_SESSION{'noq'} = $#stqids;
				### DED 3/9/05 Check for review mode
				if ($#resps == $TEST_SESSION{'noq'}) {
					$FORM{'review'} = $tqno;
				}
				@resp = ();
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
					&show_question($tsubtest, $tqno, $ntqno);
				} else {
## ??? BUTTON
#print STDERR "BUTTON:$FORM{'submit'}\n";
					$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
					&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
					if ($tqno ne 0) {
						$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
						&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
################################################################
# REMEDIATION FIX
# don't do put_question_response
# if returning from remediation display
################################################################
#&dbgprint("REMEDIATION FIX:tqrs:305 tqno:$tqno FREM:$FORM{'remediated'}\n");
						if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
							if ($FORM{'remediated'} ne "Y") {
								&put_question_response($tsubtest, $tqno);
							}
						} else {
							if ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y') {
								&put_several_questions($tqno);
								# Reload last ques info
								$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
								&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
							} else {
								&put_question_response($tsubtest, $tqno);
							}
						}
################################################################
					}
					&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
				}
				if ($tsubtest < 5) {
					@stqids = split(/&/, $SUBTEST_QUESTIONS{$tsubtest});
					$TEST_SESSION{'noq'} = $#stqids;
					$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
					&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
					if (($TEST{'seq'} eq 'std') || ($TEST{'seq'} eq 'svy') || ($TEST{'seq'} eq 'dmg')) {
						if (($FORM{'submit'} eq $xlatphrase[543])
							|| ($FORM{'submit'} eq $xlatphrase[544])) {
## REVIEW BUTTON
							$tqno = &find_next_marked($tsubtest, $tqno);
							$ntqno = &find_next_marked($tsubtest, $tqno);
						} elsif ($FORM{'submit'} eq "$xlatphrase[93]") {
## BEGIN BUTTON
							$tqno++;
						} elsif ($FORM{'submit'} eq "$xlatphrase[566]") {
## OK BUTTON - returning from remediation on posting of answer
							$tqno++;
						} elsif ($FORM{'submit'} eq "$xlatphrase[3]") {
## NEXT BUTTON

							if (($TEST{'Ins'} ne '') && ($tsubtest == 2)
								&& ($TEST{'seq'} ne 'svy') && ($tqno == 0)) {
								#
								# Worksheet printing support
								#
								$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
								$QUESTION{'id'} = "0";
								&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
								&show_test_worksheets($TEST_SESSION{'clid'}, $TEST{'id'});
							} else {
								### DED 9/17/02  Support for Fork (mca) questions
								if ($QUESTION{'qtp'} eq 'mca') {
								@qnxt = split(/\;/, $QUESTION{'qnxt'});
								if ($TEST{'group'} eq 'Y') {
                                                               		$nextq = $qnxt[$FORM{"q$tqno-qrs"}];
				      				} else {
                                                               		$nextq = $qnxt[$FORM{'qrs'}];
                                                       		}
									for (1 .. $#stqids) {
										if ($stqids[$_] eq $nextq) {
											$tqno = $_;
#&dbgprint("MCA: nextq:$nextq tqno:$tqno\n");
										}
									}
								} else {
### Support for question grouping on dmg surveys
									if ($TEST{'group'} eq 'Y') {
                                                                        	$tqno=$FORM{'qno'};
                                                                	}


################################################################
# REMEDIATION FIX
# don't increment question_no unless
# returning from remediation display
################################################################
#									if ($tqno ne $TEST_SESSION{'noq'}) {$tqno++;}
#&dbgprint("REMEDIATION FIX:tqrs:360 nextq:$nextq tqno:$tqno FREM:$FORM{'remediated'}\n");
									if ($tqno ne $TEST_SESSION{'noq'}) {
										if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
											if ($FORM{'remediated'} eq "Y" || $tqno == 0) {
												$tqno++;
											} else {
												$FORM{'remediateonpost'} = &remediate_question($tsubtest,$tqno);
												if ($FORM{'remediated'} eq "Y") {
													$tqno++;
												}
											}
										} else { $tqno++; }
#my $remfixdbglen=length($FORM{'remediateonpost'});
#&dbgprint("REMEDIATION FIX:tqrs:371 tqno:$tqno FREM:$remfixdbglen\n");
									}
################################################################
								}
							}
						} elsif ($FORM{'submit'} eq "$xlatphrase[7]") {
## BACK BUTTON
							if ($tqno ne 1 ) {$tqno--;}
						} elsif ($FORM{'submit'} eq "$xlatphrase[779]") {
## JUMP TO BUTTON
							if ($FORM{'review'} eq "nextreview") {
								# Next in review list
								$tqno = &find_next_marked($tsubtest, $tqno);
								$ntqno = &find_next_marked($tsubtest, $tqno);
							} elsif ($FORM{'review'} eq "nextunanswered") {
								# Next unanswered
								$tqno = &find_next_unanswered($tsubtest, $tqno);
								$ntqno = &find_next_unanswered($tsubtest, $tqno);
							} else {
								$tqno=$FORM{'review'};
							}
						} elsif (($TEST{'Ins'} ne '') && ($tsubtest == 2)
								&& ($TEST{'seq'} ne 'svy')) {
						#
						# Worksheet printing support
						#
							$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
							$QUESTION{'id'} = "0";
							&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
							&show_test_worksheets($TEST_SESSION{'clid'}, $TEST{'id'});
						} else {
							$tqno=$tqno;
						}
#&dbgprint("Test State Info:$tstate.$tsubtest.$tqno\n");
						$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
						$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
						if ($TEST{'seq'} eq 'svy') {
							$tqno=0; $TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
							&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
							&show_single_form_test();
						} elsif ($TEST{'seq'} eq 'dmg' && $TEST{'group'} eq 'Y') {
							$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
                                                      	$SUBTEST_SUMMARY{$tsubtest} = "Time Remaining\&$FORM{'tmreset'}";
                                                       	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
                                                       	&show_group($tsubtest, $tqno, $ntqno);
                                               	} else {

							$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
#&dbgprint("show_question($tsubtest,$tqno,$ntqno\n");
################################################################
# REMEDIATION FIX
# do put_test_sequence and show question
# unless remediation on posting
################################################################
#							$SUBTEST_SUMMARY{$tsubtest} = "Time Remaining\&$FORM{'tmreset'}";
#							&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
#							&show_question($tsubtest, $tqno, $ntqno);
my $remfixdbglen=length($FORM{'remediateonpost'});
#&dbgprint("REMEDIATION FIX:tqrs:410 nextq:$nextq tqno:$tqno FSBMT:$FORM{'submit'} FREM:$remfixdbglen\n");
							if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
								if (($FORM{'submit'} eq $xlatphrase[566]) || ($FORM{'remediateonpost'} eq "")) {
									$SUBTEST_SUMMARY{$tsubtest} = "Time Remaining\&$FORM{'tmreset'}";
									&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
									&show_question($tsubtest, $tqno, $ntqno);
								} else {
									$QUESTION{'qno'} = $tqno;
									&show_template("qrem");
								}
							} else {
								$SUBTEST_SUMMARY{$tsubtest} = "Time Remaining\&$FORM{'tmreset'}";
								&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
								&show_question($tsubtest, $tqno, $ntqno);
							}
################################################################
						}
					} elsif ($TEST{'seq'} eq 'cfa') {
						&resume_cfa();
					}
				} else {
					$TEST_SESSION{'navbuttons'}=&set_subtest_nav_buttons($tstate, $tsubtest);
					&show_template("tend");
				}
			}
		} else {
			# test is completed
			$TEST_SESSION{'navbuttons'}=&set_subtest_nav_buttons($tstate, $tsubtest);
			&show_template("tend");
		}
	}
}

sub resume_cfa() {
	$tstate = $TEST_STATES{'_IN_PROGRESS'};
	$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
	$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	$TEST_SESSION{'navbuttons'}=&set_subtest_nav_buttons($tstate, $tsubtest);
	#&dbgprint("SubtCFA= $SUBTEST{'cfa'} TestCFA= $TEST{'cfa'} Tid= $TEST{'id'}\n");

	if ($TEST{'cfa'} eq '') {
		@dscllines = &get_data("$TEST_SESSION{'subtest'}.$TEST_SESSION{'clid'}");
		$dscltext = "";
		foreach $dsclline (@dscllines) {
			$dsclline =~ s/\r//g;
			$dsclline =~ s/\n//g;
			$dscltext = join('<BR>', $dscltext, $dsclline);
		}
		$TEST_SESSION{'agreement'} = $dscltext;
	} else {
		$TEST_SESSION{'agreement'} = $TEST{'cfa'};
	}
	&show_template("agreement");
}

# v sac anonymous submission support
# sub make_anonymous - moved to testlib.pl 1/10/04 DED
# ^ sac anonymous submission support

# sub single_form_test_done - moved to testlib.pl 06/24/2006 DED
# sub put_several_questions - moved to testlib.pl 06/24/2006 DED
# sub check_for_custom_exit_file - moved to testlib.pl 06/24/2006 DED

sub show_single_form_test {
	# show all questions on same page
	$notemplate = 1;
	$TEST{'heading'} = "<H1>$TEST{'desc'}</H1>";
	$TEST{'questions'} = "";
	$questhtml = "";
	$TEST_SESSION{'noq'}=$TEST{'noq'};
	for (1 .. $TEST{'noq'}) {
		$tqno = $_;
		$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
		&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
		$QUESTION{'anslist'}="";
		$qhtml = &show_question($tsubtest, $tqno);
		$question_row_html = "<TR>
<TD align=\"left\">
<HR>
$QUESTION{'illustration'}<BR>
<FONT SIZE=4>
$_. $QUESTION{'qtx'}
</FONT><BR>
\&nbsp\;<BR>
$QUESTION{'anslist'}<BR>
</TD>
</TR>\n";
		$qhtml=$QUESTION{'promptcomments'};
		$srch="=\"qcucmt";
		$repl="=\"q$_-qcucmt";
		$qhtml =~ s/$srch/$repl/g;
		if ($qhtml =~ /<TR>/) {
			$question_row_html = join('', $question_row_html, $qhtml, "\n");
		} else {
			$question_row_html = join('', $question_row_html, "<TR><TD>", $qhtml, "</TD></TR>\n");
		}
		$srch="=\"qrs";
		$repl="=\"q$_-qrs";
		$question_row_html =~ s/$srch/$repl/g;
		$questhtml = join('', $questhtml, $question_row_html);
	}
	$notemplate = 0;
	$question_row_html = "<TR>
<TD align=\"left\">
<HR>
\&nbsp\;<BR>
</TD>
</TR>\n";
	$questhtml = join('', $questhtml, $question_row_html);
	$TEST{'questions'} = $questhtml;
	%QUESTION={};
	&show_template("qsvy");
}

sub show_group {
	my $gtqno = $_[1];
	if ($#_ == 2) {
		my $gntqno = $_[2];
	}
	# group questions by subject area
	$notemplate = 1;
	# find subject area of current question
	&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
	($group_subj, $trash) = split(/\./, $QUESTION{'subj'});
	if ($TEST{'showsubj'} eq 'Y') {
		&get_subjarea($SESSION{'clid'}, $TEST{'id'}, $group_subj);
		$SUBJAREA{'desc'} =~ tr/+/ /;
		$TEST{'heading'} = "<H2>$TEST{'desc'}: $SUBJAREA{'desc'}</H2>";
	} else {
		$TEST{'heading'} = "<H2>$TEST{'desc'}</H2>";
	}
	# get question list based on subject area
	# ASSUME questions were grouped by subject area when testfile created
	$TEST{'questions'} = "";
	$questhtml = "";
	$TEST_SESSION{'noq'}=$TEST{'noq'};
	for $tqno ($gtqno .. $TEST{'noq'}) {
		$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
		&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
		($subj, $trash) = split(/\./, $QUESTION{'subj'});
		if ($subj ne $group_subj) { last; }  # Stop at end of subjarea
		$QUESTION{'anslist'}="";
		$qhtml = &show_question($tsubtest, $tqno);
		if ($CLIENT{'clid'} eq "tas") {
			$picalign = "right";
		}
		if ($picalign eq "right") {
			$question_row_html = "<TR>
<TD colspan=2>
<HR>
</TD>
</TR>
<TR>
<TD align=\"left\">";
		} else {
			$question_row_html = "<TR>
<TD align=\"left\">
<HR>
$QUESTION{'illustration'}<BR>";
		}
		if ($TEST{'showsubj'} eq 'Y') {
			$question_row_html .= "<FONT SIZE=2><B>Question: ".$tqno."</B><BR><BR></FONT>\n";
		}
		$question_row_html .= "
<FONT SIZE=4>
$QUESTION{'qtx'}
</FONT><BR>
\&nbsp\;<BR>
$QUESTION{'anslist'}<BR>
</TD>";
		if ($picalign eq "right") {
			$question_row_html .= "
<TD align=\"right\">
$QUESTION{'illustration'}
</TD>";
		}
		$question_row_html .= "
</TR>\n";
		$qhtml=$QUESTION{'promptcomments'};
		$srch="=\"qcucmt";
		$repl="=\"q$tqno-qcucmt";
		$qhtml =~ s/$srch/$repl/g;
		if ($qhtml =~ /<TR>/) {
			$question_row_html = join('', $question_row_html, $qhtml, "\n");
		} else {
			$question_row_html = join('', $question_row_html, "<TR><TD>", $qhtml, "</TD></TR>\n");
		}
		$srch="=\"qrs";
		$repl="=\"q$tqno-qrs";
		$question_row_html =~ s/$srch/$repl/g;
		$questhtml = join('', $questhtml, $question_row_html);
	}
	$notemplate = 0;
	$question_row_html = "<TR>";
	if ($picalign eq "right") {
		$question_row_html .= "<TD colspan=2>";
	} else {
		$question_row_html .= "<TD align=\"left\">";
	}
	$question_row_html .= "
<HR>
\&nbsp\;<BR>
</TD>
</TR>\n";
	$questhtml = join('', $questhtml, $question_row_html);
	$TEST{'questions'} = $questhtml;
	&show_template("qgrp");
}

sub test_continue {
	$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
	&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
	if (($TEST{'seq'} eq 'svy') || ($TEST{'seq'} eq 'dmg')) {
		$TEST_SESSION{'message'} = "$xlatphrase[657]";
		$tetmplt = "tend";
	} else {
		$tetmplt = "tsubend";
		if ( $tsubtest > 2 || $TEST{'scr'} eq '3' || $TEST{'emlcnd'} ne 'Y') {
			$TEST_SESSION{'message'} = "$xlatphrase[658]";
		}
	}
	$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
	&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
	if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
		if ($FORM{'remediated'} ne "Y") {
			&put_question_response($tsubtest, $tqno);
		}
	} else {
		&put_question_response($tsubtest, $tqno);
	}
	&get_subtest_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
	my $passfailflag=&summarize_test($tsubtest);
	$FORM{'remediation'} = &remediate_summary($tsubtest);
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	$TEST{'customexit'}=&check_for_custom_exit_file($passfailflag);
	$tqno=0; $tsubtest++;
	while ($tsbt[$tsubtest] eq '' && $tsubtest < 5) {$tsubtest++;}
	if ($tsubtest < 5) {
		$TEST_SESSION{'tmreset'} = $TEST{'maxtmfmt'};
	}
	$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
	$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
	&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	$TEST_SESSION{'navbuttons'}="<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[3]\">";
	&show_template($tetmplt);
}

sub single_form_test_continue {
	# all questions on same page
	&get_subtest_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
	$TEST_SESSION{'noq'}=$SUBTEST{'noq'};
	for (keys %FORM) {
		if ($_ =~ /q[0-9]/ ) {
			($tqno, $tqidx) = split(/\-/, $_);
			$tqno =~ s/q//g;
			if ($tqidx eq 'qrs') {
				$FORM{'qrs'} = $FORM{$_};
			} else {
				$tqidx =~ s/qrs//g;
			}
			$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
			&get_question_definition($SUBTEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
			&put_question_response($tsubtest, $tqno);
		}
	}
	$TEST_SESSION{'message'} = "$xlatphrase[655]<BR>$xlatphrase[656]<BR>\n";
	my $passfailflag="u";
	if ($SUBTEST{'seq'} eq 'svy') {
		&summarize_survey($tsubtest);
		$TEST{'bars'} = "N";
	} else {
		if ($TEST{'emlcndopt'} ne 'Y') { $TEST{'bars'} = "N";}
		$passfailflag=&summarize_test($tsubtest);
	}
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
# v sac support for custom exit message
	$TEST{'customexit'}=&check_for_custom_exit_file($passfailflag);
# ^ sac support for custom exit message
	$tqno=0; $tsubtest++;
	while ($tsbt[$tsubtest] eq '' && $tsubtest < 5) {$tsubtest++;}
	if ($tsubtest < 5) {
		$TEST_SESSION{'tmreset'} = $TEST{'maxtmfmt'};
	}
	$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
	$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
	&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	if ($TEST{'ntfy'} ne '') {
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
		&send_testresults("2","$endtime");
	}
	&send_custom_exit_email($passfailflag);
	$TEST_SESSION{'navbuttons'}="<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[3]\">";
	$tetmplt = "tsubend";
	&show_template($tetmplt);
}

sub test_is_done {
	$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
	&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
################################################################
# REMEDIATION FIX
# do put_question_response unless already 
# done for remediation on posting
################################################################
#	&put_question_response($tsubtest, $tqno);
	if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
		if ($FORM{'remediated'} ne "Y") {
			&put_question_response($tsubtest, $tqno);
		}
	} else {
		&put_question_response($tsubtest, $tqno);
	}
################################################################
	&get_subtest_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
#	&summarize_test($tsubtest);
	my $passfailflag=&summarize_test($tsubtest);
	$FORM{'remediation'} = &remediate_summary($tsubtest);
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
# v sac support for custom exit message
	$TEST{'customexit'}=&check_for_custom_exit_file($passfailflag);
# ^ sac support for custom exit message
	$tstate = $TEST_STATES{'_COMPLETED'};
	$tsubtest=0; $tqno=0;
	$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	&promote_test_sequence($testinprog, $testcomplete, $TEST_STATES{'_COMPLETED'});
	if ($TEST{'ntfy'} ne '') {
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
		&send_testresults("2","$endtime");
	}
	&send_custom_exit_email($passfailflag);
	$TEST_SESSION{'navbuttons'}="<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[769]\" onClick=\"cancel_test()\">";
	&show_template($tetmplt);
}

sub terminated_by_administrator {
	$tmsg = "$xlatphrase[659]<BR>\n";
	$tmsg = join('', $tmsg, "$xlatphrase[660]<BR>\n");
	&promote_test_sequence($testinprog, $testcomplete, "5");
	$TEST_SESSION{'message'} = $tmsg;
	$TEST_SESSION{'navbuttons'} = &set_subtest_nav_buttons($tstate, $tsubtest);
	&show_template("tend");
}

sub time_expired_ending_test {
	####################################################
	# This is no longer used, replaced by texp.pl      #
	####################################################
	$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
	&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
	if ( $tsubtest > 2 || $TEST{'scr'} eq '3' || $TEST{'emlcnd'} ne 'Y') {
		$TEST_SESSION{'message'} = "xlatphrase[658]";
		$tetmplt = "tend";
	} else {
		$tetmplt = "tsubend";
	}
	#$QUESTION{'id'} = &get_question_id($tsubtest, $tqno);
	#&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});
	#&put_question_response($tsubtest, $tqno);
	&get_subtest_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
	&summarize_test($tsubtest);
	&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
	$tqno=0; $tsubtest++;
	while ($tsbt[$tsubtest] eq '' && $tsubtest < 5) {$tsubtest++;}
	if ($tsubtest < 5) {
		$TEST_SESSION{'tmreset'} = $TEST{'maxtmfmt'};
		$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
		$TEST_SESSION{'subtest'} = $tsbt[$tsubtest];
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
		&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
		$TEST_SESSION{'navbuttons'}="<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[3]\">";
	} else {
		&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'subtest'});
		$tstate = $TEST_STATES{'_TIME_EXPIRED'};
		$tsubtest=0; $tqno=0;
		$TEST_SESSION{'state'} = "$tstate.$tsubtest.$tqno";
		&put_test_sequence($testinprog, $TEST_SESSION{'clid'}, $TEST_SESSION{'uid'}, $TEST_SESSION{'id'});
		&promote_test_sequence($testinprog, $testcomplete, $TEST_STATES{'_COMPLETED'});
		&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "3", "Test Complete $TEST{'id'}", $endtime);
		if ($TEST{'ntfy'} ne '') {
			&get_test_profile( $TEST_SESSION{'clid'}, $TEST_SESSION{'id'});
			&send_testresults("2","$endtime");
		}
		&send_custom_exit_email($passfailflag);
		$TEST_SESSION{'navbuttons'}="<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[769]\" onClick=\"cancel_test()\">";
	}
	$TEST_SESSION{'message'} = "$xlatphrase[654]";
	&show_template($tetmplt);
}

sub show_question {
	&log_entry($SESSION{'clid'}, $SESSION{'uid'}, "2", "Test Question $TEST{'id'} $QUESTION{'id'}");
	&get_question_definition($TEST{'id'}, $CLIENT{'clid'}, $QUESTION{'id'});

	$QUESTION{'qno'} = $tqno;
	$QUESTION{'qtx'} =~ s/\;/<BR>/g;
	$QUESTION{'qtx'} =~ s/\n/<BR>/g;
	$QUESTION{'qtx'}=&merg_exhibit_in_text($QUESTION{'qtx'});
	$QUESTION{'qrm'} =~ s/\;/<BR>/g;

# v sac added support for optional comments
# (replaced)
#	$prvresp=&get_previous_response($_[0], $_[1]);
# (with)
	my $trash=&get_previous_response($_[0], $_[1]);
	($prvresp,$prevcmts)=split(/::/, $trash);
	if ($prvresp =~ /^\'/ ) {
		$QUESTION{'marked'} = " CHECKED";
		$prvresp =~ s/\'//; 
	}
	my $srch="><\/TEXTAREA>";
	my $repl=">$prevcmts<\/TEXTAREA>";
	if ($QUESTION{'qcmtprmpt'} eq 'Y') {
		$QUESTION{'promptcomments'} =~ s/$srch/$repl/;
	}
# ^ sac added support for optional comments

	if ($TEST{'remt'} eq '3') {
		$QUESTION{'qrmwq'} = join('', "\&nbsp\;<BR>\n", $QUESTION{'qrm'});
	}
	if ($QUESTION{'qtp'} eq 'tf' ) {
		$optTrue = ($prvresp eq $QUESTION{'qca'}) ? "checked" : "" ;
		$optFalse = ($prvresp eq $QUESTION{'qia'}) ? "checked" : "" ;
##sac v added code to make TRUE/YES always the first answer
		if ((uc($QUESTION{'qca'}) eq 'TRUE') || (uc($QUESTION{'qca'}) eq 'YES')) {
			$outline = "<input type=\"radio\" name=\"qrs\" value=\"$QUESTION{'qca'}\" $optTrue>$QUESTION{'qca'}<BR>\n";
			$outline = join('', $outline, "<input type=\"radio\" name=\"qrs\" value=\"$QUESTION{'qia'}\" $optFalse>$QUESTION{'qia'}<BR>\n");
		} else {
			$outline = "<input type=\"radio\" name=\"qrs\" value=\"$QUESTION{'qia'}\" $optFalse>$QUESTION{'qia'}<BR>\n";
			$outline = join('', $outline, "<input type=\"radio\" name=\"qrs\" value=\"$QUESTION{'qca'}\" $optTrue>$QUESTION{'qca'}<BR>\n");
		}
##sac ^ added code to make TRUE/YES always the first answer

		$QUESTION{'anslist'} = $outline;
##wac v 01/03/02 T/F appears in answer list of MCM question, need to clear $outline
		$outline="";
##wac ^
		$tmpfile = "qtf";
	} elsif ($QUESTION{'qtp'} eq 'esa' ) {
## sac v 03/28/02 changed input box length calculation to the longest of the multiple options
# (replaced)
#		$anlen = (length($QUESTION{'qca'}) * 2);
#		$anlen = ($anlen < 5) ? 5 : $anlen;
# (with)
		my @esaanswers = split(/\;/,$QUESTION{'qca'});
		$anslen=5;
		foreach $anslist (@esaanswers) {
			if ($anslen < length($anslist)) {
				$anslen = length($anslist);
			}
		}
		$anslen += 5;
## sac ^ 03/28/02 changed input box length calculation to the longest of the multiple options
		$anslist = "<input type=\"text\" name=\"qrs\" VALUE=\"$prvresp\" SIZE=$anlen>";
		if ($QUESTION{'qtx'} =~ /<box>/ ) {
			$QUESTION{'qtx'} =~ s/<box>/$anslist/g;
			$QUESTION{'anslist'} = "";
		} else {
			$QUESTION{'anslist'} = "$anslist\n";
		}
		$tmpfile = "qesa";
	} elsif ($QUESTION{'qtp'} eq 'mch' ) {
		&build_matching_answer_list($_[0], $_[1], $prvresp);
		$tmpfile = "qmch";
	} elsif ($QUESTION{'qtp'} eq 'ord' ) {
		&build_ordered_answer_list($_[0], $_[1], $prvresp);
		$tmpfile = "qord";
	} elsif ($QUESTION{'qtp'} eq 'nrt' ) {
		$nrtmaxlen = $QUESTION{'qca'};
		$nrtcols = 50;
		$nrtrows = $nrtmaxlen/$nrtcols;
		$nrtrows = ($nrtrows > 5) ? 5 : $nrtrows;
		$QUESTION{'anslist'} = "<textarea name=\"qrs\" ROWS=\"$nrtrows\" COLS=\"$nrtcols\" onKeyPress=\"ta_onKeyPress(this.form)\" wrap=\"on\">$prvresp</TEXTAREA>\n";
		$tmpfile = "qnrt";
	} elsif ($QUESTION{'qtp'} eq 'mtx' ) {
		&build_matrix_answer_list($_[0], $_[1], $prvresp, "CHECKBOX");
		$tmpfile = "qmtx";
	} elsif ($QUESTION{'qtp'} eq 'mtr' ) {
		&build_matrix_answer_list($_[0], $_[1], $prvresp, "RANK");
		$tmpfile = "qmtr";
	} else {
		if (($QUESTION{'qtp'} eq 'mcs' ) || ($QUESTION{'qtp'} eq 'mca')) {
			$inptyp = "RADIO";
			$tmpfile = "qmcs";
		} elsif ($QUESTION{'qtp'} eq 'lik' ) {
			$inptyp = "RADIO";
			$tmpfile = "qlik";
		} elsif ($QUESTION{'qtp'} eq 'mcm' ) {
			$inptyp = "CHECKBOX";
			$tmpfile = "qmcm";
		} elsif ($QUESTION{'qtp'} eq 'plc' ) {
			$tmpfile = "qplc";
		} else{
			$Error = 1;
		}
		if ($QUESTION{'anslay'} eq "h") {
			$inptyp .= ":".$QUESTION{'anslay'};
		}
		&build_answer_list($_[0], $_[1], $inptyp, $prvresp);
	}
	$TEST_SESSION{'navbuttons'} = &set_nav_buttons($_[0], $_[1], $_[2]);
	unless ($notemplate) {
		@lines = &get_template($tmpfile);
		foreach $line (@lines) {
			$line = &xlatline($line);
		}
	}
}

sub set_subtest_nav_buttons {
	if ($_[0] eq $TEST_STATES{'_PENDING'}) {
		$navbuttons = "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[487]\" onClick=\"return btn_pause(this)\">";
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[488]\"> onClick=\"return btn_pause(this)\">");
        } elsif ($_[0] eq $TEST_STATES{'_IN_PROGRESS'}) {
		$btnvalue = ($_[1] eq $tlastsubtest) ? "$xlatphrase[545]" : "$xlatphrase[6]";
		$navbuttons = "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$btnvalue\" onClick=\"return btn_pause(this)\">";
		if ($TEST{'tpp'} eq 'Y') {
			$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[542]\" onClick=\"return btn_pause(this)\">");
		}
	} else {
		$TEST_SESSION{'cancel'} = "onSubmit='cancel_test()'";
		$navbuttons = "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[769]\">";
	}
	return $navbuttons;
}

sub set_nav_buttons {
	$navbuttons = "<INPUT TYPE=HIDDEN NAME=\"skipok\" VALUE=\"$TEST{'qsk'}\">\n";
	### If skip set, show "mark for review" checkbox
	if ($TEST{'qsk'} eq 'Y' && $_[1] !=0) {
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=CHECKBOX NAME=\"marked\"$QUESTION{'marked'}> <B>$xlatphrase[546]</B><BR>\&nbsp\;<BR>\n");
	}
	if ($TEST{'qpv'} eq 'Y' && $_[1] > 1) {
## BACK BUTTON
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[7]\" onClick=\"return btn_pause(this)\">");
	}
	if ($TEST{'tpp'} eq 'Y' && $_[1] != 0) {
## PAUSE BUTTON
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[542]\" onClick=\"return btn_pause(this)\">");
	}
	if ($_[1] > 0) {
		my $phrase = $xlatphrase[779];
		if ($_[1] eq $TEST_SESSION{'noq'} || $QUESTION{'exitpt'} eq 'Y') {
### LAST QUESTION
			if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
### REMEDIATION hidden indicator to let the OK button know which
### button to default to after remediation.
				$navbuttons .= "<input type=hidden name=\"RemediationOKButton\" value=\"$xlatphrase[3]\"> \&nbsp\;\&nbsp\;\&nbsp\;";
			}
## DONE : CONTINUE BUTTONS
			$btnvalue = ($_[0] eq $tlastsubtest) ? "$xlatphrase[5]" : "$xlatphrase[6]";
		} elsif ($FORM{'review'}) {
#print STDERR "REVIEW\n";
## REVIEW MODE 
			### If Previous, add NEXT button
			if ($TEST{'qpv'} eq 'Y') {
				$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[3]\" onClick=\"return btn_pause(this)\">");
			}
			### In Review mode, always a Done or Continue button
			$btnvalue = ($_[0] eq $tlastsubtest) ? "$xlatphrase[5]" : "$xlatphrase[6]";
		} else {
## NEXT BUTTON
			$btnvalue = "$xlatphrase[3]";
		}
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$btnvalue\" onClick=\"return btn_pause(this)\">");
	}
	### DED 6/28/04 Display Review dropdown if test is std 
	###     and (skip ok or previous button)
	###     and (end of test or dropdown with last question)
	if ($TEST{'seq'} eq 'std' && ($TEST{'qsk'} eq 'Y' || $TEST{'qpv'} eq 'Y') && ($_[1] eq $TEST_SESSION{'noq'} || $FORM{'review'})) {
## REVIEW DROPDOWN 
		my $dropdown = &build_review_dropdown($_[0]);
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, $dropdown);
	}
	return $navbuttons;
}

sub old_set_nav_buttons {
### DED 7/1/04 Rearranged nav button logic in new function to accomodate
###            review dropdown
	$navbuttons = "<INPUT TYPE=HIDDEN NAME=\"skipok\" VALUE=\"$TEST{'qsk'}\">\n";
	my $phrase = $xlatphrase[543];
	if ($FORM{submit} =~ /$phrase/) {
## REVIEW BUTTON
		if ($_[1] ne $TEST_SESSION{'noq'}) {
			$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=CHECKBOX NAME=\"marked\"> <B>$xlatphrase[546]</B><BR>\&nbsp\;<BR>\n");
		}
		if ($_[1] > 0 && $_[1] ne $_[2]) {
			if ($SUBTEST_RESPONSES{$_[0]} =~ /\&\'/ ) {
## REVIEW NEXT BUTTON
				$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[544]\" onClick=\"return btn_pause(this)\">");
			}
		}
		$btnvalue = ($_[0] eq $tlastsubtest) ? "$xlatphrase[5]" : "$xlatphrase[6]";
## DONE : CONTINUE BUTTONS
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$btnvalue\" onClick=\"return btn_pause(this)\">");
	} else {
		# didn't hit Review
		if ($TEST{'qsk'} eq 'Y' && $_[1] !=0) {
#hkh bug#37 do not display phrase 546 if DONE is the only button
			if ($_[1] eq $TEST_SESSION{'noq'}) {
				if ($TEST{'qpv'} eq 'Y' && $_[1] > 1) {
					$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=CHECKBOX NAME=\"marked\"> <B>$xlatphrase[546]</B><BR>\&nbsp\;<BR>\n");
				} else {
#hkh bug#37 if user did not leave any questions unanswered and did not click to review any questions
					if ($SUBTEST_RESPONSES{$_[0]} =~ /\&\'/ ) {
						$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=CHECKBOX NAME=\"marked\"> <B>$xlatphrase[546]</B><BR>\&nbsp\;<BR>\n");
					}
				}
			} else {
				$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=CHECKBOX NAME=\"marked\"> <B>$xlatphrase[546]</B><BR>\&nbsp\;<BR>\n");
				}
		}
		if ($TEST{'qpv'} eq 'Y' && $_[1] > 1) {
## BACK BUTTON
			$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[7]\" onClick=\"return btn_pause(this)\">");
		}
		if ($TEST{'tpp'} eq 'Y' && $_[1] != 0) {
## PAUSE BUTTON
			$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[542]\" onClick=\"return btn_pause(this)\">");
		}
		if ($_[1] > 0) {
## DONE : CONTINUE BUTTONS
			$btnvaluetrue = ($_[0] eq $tlastsubtest) ? "$xlatphrase[5]" : "$xlatphrase[6]";
## NEXT BUTTON
			$btnvalue = ($_[1] eq $TEST_SESSION{'noq'}) ? $btnvaluetrue : "$xlatphrase[3]";
			if ($btnvalue eq $btnvaluetrue) {
################################################################
# REMEDIATION FIX
# Add the hidden indicator to let the OK button know which
# button to default to after remediation.
################################################################
				if (($TEST{'seq'} eq 'std') && ($TEST{'remt'} eq '1')) {
					$navbuttons .= "<input type=hidden name=\"RemediationOKButton\" value=\"$xlatphrase[3]\"> \&nbsp\;\&nbsp\;\&nbsp\;";
#&dbgprint("REMEDIATION FIX:tqrs:1057 navbuttons:$navbuttons\n");
				}
################################################################
			}
		} else {
## NEXT BUTTON
			$btnvalue = "$xlatphrase[3]";
		}
		$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$btnvalue\" onClick=\"return btn_pause(this)\">");
		### DED 6/28/04 Display Review dropdown if skip ok
		###     and (end of test or jumped to question from dropdown)
		if (($TEST{'qsk'} eq 'Y') && ((($_[1] eq $TEST_SESSION{'noq'}) && ($TEST{'seq'} ne 'dmg')) || $FORM{'review'})) {
## REVIEW DROPDOWN 
			my $dropdown = &build_review_dropdown($_[0]);
			$navbuttons = join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp', $navbuttons, $dropdown);
		}
	}
	return $navbuttons;
}

sub build_review_dropdown {
	my $tsubtest = $_[0];
	my $dropdown = "<nobr>";
	my ($marked, $unanswered) = &find_marked_unanswered($tsubtest);
#print STDERR "tsubtest: $tsubtest marked: $marked unanswered: $unanswered questionlist: $TEST{'questionlist'} tqno: $tqno\n";
	### DED 12/08/04 Activate Jump to button on selection
	$dropdown .= "<SELECT name=\"review\" onChange=\"this.form.submit[this.form.submit.length-1].click()\">\n";
	if ($marked && ($marked =~ /:.:.:/ || (":$tqno:" ne $marked))) {
			$dropdown .= "<OPTION value=\"nextreview\">$xlatphrase[780]</OPTION>\n";
	}
	if ($unanswered && ($unanswered =~ /:.:.:/ || (":$tqno:" ne $unanswered))) {
		$dropdown .= "<OPTION value=\"nextunanswered\">$xlatphrase[781]</OPTION>\n";
	}
	$dropdown .= &build_question_dropdown_list($tsubtest, $marked, $unanswered);
	$dropdown .= "</SELECT>\n";
	$dropdown .= "<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"$xlatphrase[779]\" onClick=\"return btn_pause(this)\"></nobr>\n";
	
}

sub build_answer_list {
	@albls = set_answer_labels($QUESTION{'qalb'});
	$qca = $QUESTION{'qca'};
	$qca =~ s/\r/\n/g;
	$qca =~ s/\n\n/\n/g;
	@qansopt = split(/\n/, $qca);
	$qia = $QUESTION{'qia'};
	$qia =~ s/\r/\n/g;
	$qia =~ s/\n\n/\n/g;
	@qia = split(/\n/, $qia);
	foreach $qia (@qia) { push @qansopt, $qia; }
	@qia=();

	@qans=split(/&/, $SUBTEST_ANSWERS{$_[0]});
	($cans, $scoring) = split(/::/, $qans[$_[1]]);
	@qansord=split(/\?/, $cans);
	@qans=();
	shift @qansord;
	$outline="";
	$iord=0;
	$counter=0;
	if ($_[2] eq 'RADIO:h') {
		$colspan = $#qansord+3;
		$outline  = "<TABLE cellspacing=10>\n";
		$outline .= "	<TR><TD colspan=$colspan>\n";
		$outline .= "		<TABLE width=100%>\n";
		$outline .= "			<TR><TD align=left>$QUESTION{'left_be'}</TD>";
		$outline .= "<TD align=right>$QUESTION{'right_be'}</TD></TR>\n";
		$outline .= "		</TABLE>\n";
		$outline .= "	</TD></TR>\n";
		$outline .= "	<TR><TD>&nbsp</TD>";
		foreach $qansord (@qansord) {
			($qidx, $trash)=split(/=/, $qansord);
			$qans = $qansopt[$qidx];
			if ($QUESTION{'qalb'} ne "x") {
				$qlbl = $albls[$iord++].")";
			} else {
				$qlbl = "";
			}
			$outline .= "<TD align=center>$qlbl $qans</TD>";
		}
		$outline .= "<TD>&nbsp</TD></TR>\n";
		$outline .= "	<TR><TD>&nbsp</TD>";
	} else {
		# setup table to format answers
		$outline .= "<TABLE>\n";
	}
	foreach $qansord (@qansord) {
		($qidx, $trash)=split(/=/, $qansord);
		$qans = $qansopt[$qidx];
		if ($QUESTION{'qalb'} ne "x") {
			$qlbl = $albls[$iord++].")";
		}
		$akey = "qrs$counter";
		if ($_[2] eq 'RADIO') {
			$optselected = ($_[3] =~ /$counter/ ) ? "CHECKED" : "";
			$repl = "<TR valign=top><TD align=right><INPUT TYPE=$inptyp NAME=\"qrs\" VALUE=\"$counter\" $optselected></TD><TD align=center>$qlbl</TD><TD align=left>$qans</TD></TR>\n";
		} elsif ($_[2] eq 'RADIO:h') {
			$optselected = ($_[3] =~ /$counter/ ) ? "CHECKED" : "";
			$repl = "<TD align=center><INPUT TYPE=RADIO NAME=\"qrs\" VALUE=\"$counter\" $optselected></TD>";
		} else {
			$optselected = ($_[3] =~ /$counter/ ) ? "CHECKED" : "";
			$repl = "<TR><TD align=right><INPUT TYPE=$inptyp NAME=\"qrs$counter\" VALUE=\"$counter\" $optselected></TD><TD align=center>$qlbl</TD><TD align=left>$qans</TD></TR>\n";
		}
		$outline = join('', $outline, $repl);
		$counter++;
	}
	if ($_[2] eq 'RADIO:h') {
		$outline .= "<TD>&nbsp</TD></TR>\n";
		$outline .= "<TR><TD colspan=$colspan>\n";
		$outline .= "	<TABLE width=100%>\n";
		$outline .= "		<TR>";
		my @sub_text = split('::', $QUESTION{'sub_text'});
		foreach (@sub_text) {
			my $width = 100 / ($#sub_text + 1);
			$outline .= "		<TD width=$width% align=center>$_</TD>";
		}
		$outline .= "		</TR>";
		$outline .= "	</TABLE>\n";
		$outline .= "</TD></TR>\n";
		@subtext=();
	}
	$outline .= "</TABLE>\n"; 
	$QUESTION{'anslist'} = $outline;
	$outline="";
}

sub build_matrix_answer_list {
	$outline="";

	# Split qia into row and col headers
	$qia = $QUESTION{'qia'};
	$qia =~ s/\r/\n/g;
	$qia =~ s/\n\n/\n/g;
	@qia = split(/::/, $qia);
	if ($qia[0] =~ /\n/) {
		@qrowhdr = split(/\n/, $qia[0]);
		@qcolhdr = split(/\n/, $qia[3]);
		$qrowcount = $qia[1];
		$qcolcount = $qia[2];
	} else {
		$qrowcount = $qia[0];
		$qcolcount = $qia[1];
		@qlbllist = split(/\n/, $qia[2]);
	}
	@qia = ();

	if ($_[3] eq "CHECKBOX") {

		# Mark previous selections with "CHECKED"
        	@optvalues = split(/\?/, $_[2]);
		shift @optvalues;
		$i=0;
		foreach $row (0 .. $qrowcount-1)
		{
			foreach $col (0 .. $qcolcount-1)
			{
				if ($optvalues[$i] != "xxx")
				{
					$chmatrix[$row][$col]="CHECKED";
				}
				else
				{
					$chmatrix[$row][$col]="";
				}
				$i++;
			}
		}
	} else {
		# Mark previous selections with "SELECTED"
        	@optvalues = split(/\?/, $_[2]);
		shift @optvalues;
		$i=0;
		foreach $row (0 .. $qrowcount-1)
		{
			foreach $col (0 .. $qcolcount-1)
			{
				$rank = $optvalues[$i];
				foreach $irank (0 .. $QUESTION{'ranknum'}) 
				{
					if ($irank eq $rank)
					{
						$chmatrix[$i][$irank]="SELECTED";
					}
					else
					{
						$chmatrix[$i][$irank]="";
					}
				}
				$i++;
			}
		}
	}

	# Build matrix html
	$outline="<table border=2>\n";
	if ($#qlbllist == -1) {
		$outline .= "  <tr>\n  <td>&nbsp;</td>";
		foreach (0 .. $#qcolhdr) {
			$outline .= "<td>$qcolhdr[$_]</td>";
		}
		$outline .= "</tr>\n";
	}
	$i=0;
	foreach $row (0 .. $qrowcount-1) {
		$outline .= "<tr>";
		if ($#qlbllist == -1) {
			$outline .= "<td>$qrowhdr[$row]</td>";
		}
		foreach $col (0 .. $qcolcount-1) {
			if ($#qlbllist == -1) {
				$outline .= "<td align=center>";
			} else {
				$outline .= "<td>";
				$outline .= "<table border=0 width=100%><tr><td align=left>$qlbllist[$i]</td><td align=right>";
			}
			if ($_[3] eq "CHECKBOX") {
				$outline .= "<input type=checkbox name=\"qrs$row$col\" value=\"1\" $chmatrix[$row][$col]>";
			} else {
				$outline .= "<select name=\"qrs$row$col\">";
				$outline .= "<option value='' $chmatrix[$i][0]>\&nbsp\;</option>";
				$outline .= &build_number_select_list($QUESTION{'rankmin'},$QUESTION{'rankmax'},$QUESTION{'rankstep'});
				$outline .= "</select>";
			}
			if ($#qlbllist != -1) {
				$outline .= "</td></tr></table>";
			}
			$outline .= "</td>";
			$i++;
		}
		$outline .= "</tr>\n";
	}
	$outline .= "</table>\n";
	@qrowhdr = ();
	@qcolhdr = ();
	@qlbllist = ();
	@chmatrix = ();

	$QUESTION{'anslist'} = $outline;
	$QUESTION{'numans'} = $i;
	$QUESTION{'rowcount'} = $qrowcount;
	$QUESTION{'colcount'} = $qcolcount;
}

sub build_ordered_answer_list {
	$qca = $QUESTION{'qca'};
	$qca =~ s/\r/\n/g;
	$qca =~ s/\n\n/\n/g;
	@qansopt = split(/\n/, $qca);

	@qans=split(/&/, $SUBTEST_ANSWERS{$_[0]});
	($cans, $scoring) = split(/::/, $qans[$_[1]]);
	@qansord=split(/\./, $cans);
	@qans=();
	shift @qansord;
	$iord=0;
	foreach $qansord (@qansord) {
		push @qlblans, $qansopt[$qansord];
	}

        @optvalues = split(/\?/, $_[2]);
	shift @optvalues;
	$counter=0;
	$outline = "<TABLE>\n";
	foreach $qans (@qlblans) {
		$optvalue = $optvalues[$counter];
		if ($optvalue eq 'xxx') { $optvalue="";}
		$repl = "<TR valign=top><TD align=right><INPUT TYPE=TEXT SIZE=\"2\" NAME=\"qrs$counter\" VALUE=\"$optvalue\"></TD><TD align=left>$qans</TD></TR>\n";
		$outline = join('', $outline, $repl);
		$counter++;
	}
	$outline .= "</TABLE>\n";
	@qlblans=(); @qans=(); @qresps=();
	$QUESTION{'anslist'} = $outline;
	$outline="";
}

sub build_matching_answer_list {
	@albls = set_answer_labels($QUESTION{'qalb'});
	$qca = $QUESTION{'qca'};
	$qca =~ s/\r/\n/g;
	$qca =~ s/\n\n/\n/g;
	@qansopt = split(/\n/, $qca);
	$qia = $QUESTION{'qia'};
	$qia =~ s/\r/\n/g;
	$qia =~ s/\n\n/\n/g;
	@qia = split(/\n/, $qia);

	@qans=split(/&/, $SUBTEST_ANSWERS{$_[0]});
	($cans, $scoring) = split(/::/, $qans[$_[1]]);
	@qansord=split(/\./, $cans);
	@qans=();
	shift @qansord;
	$iord=0;

        @optvalues = split(/\?/, $_[2]);
	shift @optvalues;
	$counter=0;
	$outline = "<TABLE border=0>\n";
	foreach $qansord (@qansord) {
		$qlbl = "<B>".$albls[$iord++].")</B> ";
		$qans = $qia[$qansord];
		$optvalue = $optvalues[$counter];
		if ($optvalue eq 'xxx') { $optvalue="";}
		$repl = "<TR valign=top>
<TD align=\"left\">
	<INPUT TYPE=TEXT SIZE=\"2\" NAME=\"qrs$counter\" VALUE=\"$optvalue\">\&nbsp\;</TD><TD>$qansopt[$counter]</TD>
<TD align=\"left\" width=80>\&nbsp\;\&nbsp\;</TD>
<TD align=\"right\">$qlbl</TD>
<TD align=\"left\">
	$qans
</TD>
</TR>\n";
		$outline = join('', $outline, $repl);
		$counter++;
	}
	$outline = join('', $outline, "</TABLE>\n");
	@qlblans=(); @qans=();
	$QUESTION{'anslist'} = $outline;
	$outline="";

}