#!/usr/bin/perl
#
# BNCweb: A user-friendly interface to the British National Corpus - Version 4.3
# Copyright (C) 2005-10 Hoffmann/Evert/Lehmann
#
# Updates and information available at http://www.bncweb.info
#
# This file is part of BNCweb.
# 
# BNCweb is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# 
# BNCweb is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

#
# based on BNCweb Version 2.0:
# © 1996/2004 Lehmann/Hoffmann/Schneider
#

use DBI;

use lib "../lib_files";
use bncLibCQPXML;

	
unless (getParams($ENV{'QUERY_STRING'})) {
	barkFull("incomplete transmition of URL<BR>This problem is likely to occur in combination with proxy servers<BR>turn off your web-proxy and try again");
}

# set defaults
setParam("type", "INIT") unless ($params{type});
setParam("type2", "INIT") unless ($params{type2});
setParam("type2", "INIT") if ($params{type}=~/(INIT|FREQ)/);
setParam("urlTest", "");

print "Content-type: text/html\n\n";
print <<HTML;
	<HEAD>
		<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
		<META NAME="GENERATOR" Content="Symantec Visual Page Mac 1.1">
		<TITLE>Distribution results</TITLE>

	</HEAD>

	<BODY BGCOLOR="#FFFFFF">
HTML

# connect to mysql
$bncHandle = DBI->connect("DBI:mysql:$bwMYSQLtable:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd") or bark("Can't connect to mysql on $bwMYSQLhost at port: $bwMysqlPort <BR>$userHandle::errstr\n");
$userHandle = DBI->connect("DBI:mysql:$bwMYSQLusertable:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd") or bark("Can't connect to mysql on $bwMYSQLhost at port: $bwMysqlPort <BR>$userHandle::errstr\n");

$username = $ENV{'REMOTE_USER'};

# get default view from settings database (for main.pl)
$sqlQuery = "SELECT view FROM settings where user='$username'";
$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
$sth->execute or bark("Can't execute $sql: $sth::errstr");
@rowArray=$sth->fetchrow_array;
$view = $rowArray[0];

$theData=$params{theData};
$check = $theData=~m/ª/;
if ($check) {
	$theData = $`;
	$theRestrictions = $';
}

$theDataL = $theData;
$theDataL =~ s/</&lt;/g;
$theDataL =~ s/>/&gt;/g;

# calculate factor "original query" vs. "thinned query" - for extrapolation of frequency per million figures
$hit=$params{thMode}=~m/M(\d+)#\d+#[^#]+#+T\d#(\d+)/;

if ($hit) {
	$full=$1;
	$thinned=$2;
	$thinning=($thinned / $full);
} else {
	$thinning=1;
}
@history=split(/##/, $params{thMode});
# add something that makes sure of singular if there is only one hit
foreach $history (@history) {
	if ($history=~m/F(\d+)#(\d+)/g) {
		$thinning = $thinning * ($2 / $1);
	}		
}

$theURL = getURLparams();

$timeTaken = $params{timeTaken};
setParam("timeTaken","");

if ($timeTaken) {
	$timeInfo = "<font color=\"#AAAAAA\" size=\"1\"> [$timeTaken seconds]</font>";
}
if ($timeTaken eq "cache") {
	$timeInfo = "<font color=\"#AAAAAA\" size=\"1\"> [data retrieved from cache]</font>";
}


$selected{$params{type}}="SELECTED";
$selected2{$params{type2}}="SELECTED";

$hit=$params{thMode}=~m/M(\d+)#\d+#([^#]+)#/;
if ($hit) {
	$subcorpus = $2;
	$subcorpusQuote = $bncHandle->quote($SQsubcorpus);
	$sqlQuery = "SELECT spowri FROM subcorpora WHERE subcorpus = $subcorpusQuote";
	$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$sth->execute or bark("Can't execute $sqlQuery: $sth::errstr");
	$res = $sth->rows;
	if ($res) {
		@rowArray=$sth->fetchrow_array;
		$spowri=$rowArray[0];
	}
} else {
	$subcorpus="no_subcorpus";
}
($categorySQL, $nothing) = &freqCalculate2($params{theData}, $subcorpus, $username, "dist");

$hit=$params{thMode}=~m/##D(F|O|C)(.*?)#/;
if ($hit) {
	$thePreviousCat = $2;
} else {
	$thePreviousCat = "";
}

if ($params{type} eq "INIT") {
	# change this for further categories to be displayed
	if ($thePreviousCat) {
		if ($thePreviousCat=~m/(age|sex|class|firstLanguage|dialect|education|role)=/) {
			@categories=('age7','sex3','class5');
		} elsif ($thePreviousCat=~m/(scgdom|sdeage|sdecla|sdesex|spolog|sporeg)=/) {
			@categories=('spowri2','spolog3','scgdom5');
		} else {
			@categories=('spowri2', 'derivedtexttype9', 'alltyp6', 'wridom10','wriaag7','wriase4','wriaud5','wrilev4','spolog3','scgdom5');
		}
	} else {
		if ($subcorpus=~m/(age|sex|class|firstLanguage|dialect|education|role)=\'/) {
			@categories=('age7','sex3','class5');
		} elsif ($subcorpus=~m/(scgdom|sdeage|sdecla|sdesex|spolog|sporeg)=/) {
			@categories=('spowri2','spolog3','scgdom5');
		} else {
			@categories=('spowri2','derivedtexttype9', 'alltyp6', 'wridom10','wriaag7','wriase4','wriaud5','wrilev4','spolog3','scgdom5');
		}
	}
} else {
	$categories[0]=$params{type};
}

$sqlQuery = "SELECT count(fname) FROM $params{dbname}";


$sth= $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr); 
@rowArray=$sth->fetchrow_array;
$res=$rowArray[0];

if ($thinning < 1) {
	$colspan = 7;
} else {
	$colspan = 5;
}

# user selected "frequency information"
if ($params{type} eq "FREQ" ) {
	$sqlQuery = "SELECT DISTINCT fname FROM $params{dbname}";
	$sth= $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$countTheFiles = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);

	$sqlQuery = "SELECT count($bwMYSQLusertable.$params{dbname}.fname), numwords, $bwMYSQLusertable.$params{dbname}.fname,
			(count($bwMYSQLusertable.$params{dbname}.fname)/numwords) * 1000000 AS value FROM $bwMYSQLusertable.$params{dbname}, 
			$bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.fname = $bwMYSQLtable.headerInfo.fname GROUP BY 
			fname ORDER BY value DESC";
			
	$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$numOfSolutions = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	$resArray=$sth->fetchall_arrayref;
	$information = "";
	
	$check = $params{thMode}=~m/\AM(\d+)#?/;
	$numRes = $1 if ($check);

	$information = &createTitle($params{thMode}, $theDataL, $numRes);
	$information=~m/returned \d+ matches in (\d+) different texts/;
	$countTheFilesOrig = $1;
	unless ($countTheFilesOrig == $countTheFiles) {
		$information .= ". The current solution set was found in $countTheFiles texts.";
	}

	$information .= $timeInfo;
	
	&printForms();
	print <<HTML;
	<BR><TABLE BORDER="0" CELLPADDING="3" WIDTH="100%">
	<TR>
		<TD HEIGHT="21" COLSPAN="4" BGCOLOR="#FF9999">
			<B>It was most frequently found in the following files 
			(only texts with at least three occurrences are considered)</B>
		</TD>
	</TR>
	<TR>
		<TD BGCOLOR=\"#DDDDDD\"><B>&nbsp;Name of Text</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Number of words</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Number of hits</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per<BR>million words</B></TD>
	</TR>
HTML
	
	$countMax=0;
	for ($i = 0; $i < $numOfSolutions; $i++) {
    	$numInstances=$resArray->[$i][0];
		next if ($numInstances < 3);
		$countMax++;
		$numOfWords=$resArray->[$i][1];
		$text=$resArray->[$i][2];
		$theFrequency=$resArray->[$i][3];
		
		$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.fname = '$text'";
		$queryLink =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
		
		$link = '<A HREF="/' . $bwCGIalias . '/fileInfo.pl?text=' . $text .'&urlTest=yes">' . $text . '</A>';
		print "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$link</TD>";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($numOfWords) . "</TD>\n";
		$theNumber = &makeDecimals($numInstances);
		
		$history=$params{thMode};
		$oldHistory = $history;
		$history .= "##DF$text#$numInstances";
		setParam("thMode", "$history");		
		
		$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$queryLink&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
		setParam("thMode", "$oldHistory");	

		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" .  $theLink . "</TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theFrequency</TD></TR>\n";
		last if ($countMax == 20);
    }
    
	print <<HTML;
	<TR><TD HEIGHT="11" BGCOLOR="#FFFFFF">&nbsp;</TD></TR>
	<TR>
		<TD HEIGHT="21" COLSPAN="4" BGCOLOR="#FF9999">
			<B>Your query was least frequently found in the following files 
			(only texts with at least one occurrence are considered)</B>
		</TD>
	</TR>
	<TR>
		<TD BGCOLOR="#DDDDDD"><B>&nbsp;Name of Text</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Number of words</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Number of hits</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Frequency per<BR>million words</B></TD>
	</TR>
HTML

	#minimum information
	$countMin=0;
	$numOfSolutions--;
	for ($i = $numOfSolutions; $i >= 0; $i--) {
    	$countMin++;
		$numInstances=$resArray->[$i][0];
		$numOfWords=$resArray->[$i][1];
		$text=$resArray->[$i][2];
		$theFrequency=$resArray->[$i][3];
		$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.fname = '$text'";
		$queryLink =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
		
		$link = '<A HREF="/' . $bwCGIalias . '/fileInfo.pl?text=' . $text .'&urlTest=yes">' . $text . '</A>';
		print "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$link</TD>";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($numOfWords) . "</TD>\n";
		$theNumber = &makeDecimals($numInstances);

		$history=$params{thMode};
		$oldHistory = $history;
		$history .= "##DF$text#$numInstances";
		setParam("thMode", "$history");	

		$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$queryLink&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
		setParam("thMode", "$oldHistory");	

		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" .  $theLink . "</TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theFrequency</TD></TR>\n";
		last if ($countMin == 20);
    	}
	print "</TABLE>\n";
	
	&printFooter();

} elsif ($params{type} eq "FREQS" ) {
	# speaker frequency
	$sqlQuery = "SELECT DISTINCT spid FROM $params{dbname}";
	$sth= $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$countTheFiles = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);

	$sqlQuery = "SELECT count($bwMYSQLusertable.$params{dbname}.spid), speakerWords, $bwMYSQLusertable.$params{dbname}.spid,
			(count($bwMYSQLusertable.$params{dbname}.spid)/speakerWords) * 1000000 AS value, fname FROM $bwMYSQLusertable.$params{dbname}, 
			$bwMYSQLtable.speakers WHERE $bwMYSQLusertable.$params{dbname}.spid = $bwMYSQLtable.speakers.spid GROUP BY 
			spid ORDER BY value DESC";
	$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$numOfSolutions = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	$resArray=$sth->fetchall_arrayref;
	$information = "";
	
	$check = $params{thMode}=~m/\AM(\d+)#?/;
	$numRes = $1 if ($check);

	$information = &createTitle($params{thMode}, $theDataL, $numRes);
	$information=~m/returned \d+ matches in (\d+) different texts/;
	$countTheFilesOrig = $1;
	# change this
	unless ($countTheFilesOrig == $countTheFiles) {
		$information .= ". The current solution set was found in $countTheFiles texts.";
	}
	$information .= $timeInfo;
	
	&printForms();
	print <<HTML;
	<BR><TABLE BORDER="0" CELLPADDING="3" WIDTH="100%">
	<TR>
		<TD HEIGHT="21" COLSPAN="4" BGCOLOR="#FF9999">
			<B>It was most frequently uttered by the following speakers 
			(only speakers with at least three occurrences are considered)</B>
		</TD>
	</TR>
	<TR>
		<TD BGCOLOR=\"#DDDDDD\"><B>&nbsp;Speaker</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Number of words</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Number of hits</B></TD>
		<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per<BR>million words</B></TD>
	</TR>
HTML
	
	$countMax=0;
	for ($i = 0; $i < $numOfSolutions; $i++) {
    	$numInstances=$resArray->[$i][0];
		next if ($numInstances < 3);
		$countMax++;
		$numOfWords=$resArray->[$i][1];
		$spid=$resArray->[$i][2];
		$theFrequency=$resArray->[$i][3];
		$text=$resArray->[$i][4];
		
		$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid = '$spid'";
		$queryLink =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
		
		$link = '<A HREF="/' . $bwCGIalias . '/speakerInfo_new.pl?text=' . $text . '&spid=' . $spid .'&urlTest=yes">' . $spid . '</A>';
		print "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$link</TD>";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($numOfWords) . "</TD>\n";
		$theNumber = &makeDecimals($numInstances);
		
		$history=$params{thMode};
		$oldHistory = $history;
		$history .= "##DS$spid#$text#$numInstances";
		setParam("thMode", "$history");		
		
		$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$queryLink&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
		setParam("thMode", "$oldHistory");	

		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" .  $theLink . "</TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theFrequency</TD></TR>\n";
		last if ($countMax == 20);
    }
    
	print <<HTML;
	<TR>
		<TD HEIGHT="21" COLSPAN="4" BGCOLOR="#FF9999">
			<B>Your query was least frequently uttered by the following speakers 
			(only speakers with at least one occurrence are considered)</B>
		</TD>
	</TR>
	<TR>
		<TD BGCOLOR="#DDDDDD"><B>&nbsp;Speaker</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Number of words</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Number of hits</B></TD>
		<TD ALIGN=center BGCOLOR="#DDDDDD"><B>Frequency per<BR>million words</B></TD>
	</TR>
HTML

	#minimum information
	$countMin=0;
	$numOfSolutions--;
	for ($i = $numOfSolutions; $i >= 0; $i--) {
    	$countMin++;
		$numInstances=$resArray->[$i][0];
		$numOfWords=$resArray->[$i][1];
		$spid=$resArray->[$i][2];
		$theFrequency=$resArray->[$i][3];
		$text= $resArray->[$i][4];
		$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid = '$spid'";
		$queryLink =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
		
		$link = '<A HREF="/' . $bwCGIalias . '/speakerInfo_new.pl?text = ' . $text . '&spid=' . $spid .'&urlTest=yes">' . $spid . '</A>';
		print "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$link</TD>";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($numOfWords) . "</TD>\n";
		$theNumber = &makeDecimals($numInstances);

		$history=$params{thMode};
		$oldHistory = $history;
		$history .= "##DS$spid#$text#$numInstances";
		setParam("thMode", "$history");	

		$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$queryLink&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
		setParam("thMode", "$oldHistory");	

		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" .  $theLink . "</TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theFrequency</TD></TR>\n";
		last if ($countMin == 20);
    	}
	
	print "</TABLE>\n";
	
	&printFooter();

} elsif ($params{type2} eq "INIT") {
	# user selected one category
	$sqlQuery = "SELECT DISTINCT fname FROM $params{dbname}";
	$sth= $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$countTheFiles = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	$information = "";
	$check = $params{thMode}=~m/\AM(\d+)#?/;
	$numRes = $1 if ($check);
	$information = &createTitle($params{thMode}, $theDataL, $numRes);

	$information=~m/returned \d+ matches in (\d+) different texts/;
	$countTheFilesOrig = $1;
	unless ($countTheFilesOrig == $countTheFiles) {
		$information .= ". The current solution set was found in $countTheFiles texts.";
	}
	$information .= $timeInfo;
	&printForms();
	print <<HTML;
	<TABLE BORDER="0" CELLPADDING="3" WIDTH="100%">
	<TR>
		<TD HEIGHT="21" COLSPAN="$colspan" BGCOLOR="#FF9999"><B>&nbsp;The following distribution was found:</B></TD>
	</TR>
	
HTML
	
	$countOptions=0;

	foreach $option (@categories) {
		
		$countOptions++;
		$option=~m/([a-zA-Z]+)(\d+)/;
		$cat=$1;
		$max=$2;
		$hitSpoken=$cat=~m/\A(age|sex|class|firstLanguage|education|dialect)\Z/;
		$max++ if (($cat eq "spowri") || ($cat eq "genre") || ($cat eq "alltim"));
		$header='';
		$printRows='';
		
		$header .= "<TR><TD COLSPAN=\"$colspan\" BGCOLOR=\"#FFCC99\">&nbsp;<BIG><B>$typeValues{$cat}:</B></BIG></TD></TR>\n";
		$header .= "<TR><TD VALIGN=top BGCOLOR=\"#DDDDDD\"><B>&nbsp;Category</B></TD>\n";
		$header .= "<TD VALIGN=top ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of words</B></TD>\n";
		$header .= "<TD VALIGN=top  ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of hits</B></TD>\n";
		if ($hitSpoken) {
			$header .= "<TD VALIGN=top WIDTH=\"18%\" ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Dispersion (over speakers)</B></TD>\n";
		} else {
			$header .= "<TD VALIGN=top WIDTH=\"18%\" ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Dispersion (over files)</B></TD>\n";
		}
		$header .= "<TD VALIGN=top  ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per <BR>million words</B></TD>\n";
		$header .= "<TD VALIGN=top  ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of hits <BR>(extrapolated)</B></TD>\n" if ($thinning < 1);
		$header .= "<TD VALIGN=top  ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per million <BR>words (extrapolated)</B></TD>\n" if ($thinning < 1);
		$header .= "</TR>";
		
		undef %freq_per_million;
		undef %resTot;
		undef %resCount;
		undef %resCountDiff;
		undef %resTotFname;
		
		loop: for ($j = 1; $j < $max; $j++) {
			
			if ($cat eq "derivedtexttype") {
				$k = $j;
				$k--;
				$string=$cat . "\=$k";
			} else {
				$string=$cat . "\=$j";
			}
			next loop if (!$catValues{$string});
			
			$theSillyStrings{$j}=$string;

			if (!$hitSpoken) {
				if ($categorySQL) {
					$sqlQuery = $categorySQL . " AND $string";
					# in case catRef and person elements are mixed
					$sqlQuery =~ s/SELECT sum\(speakerWords\) FROM ($bwMYSQLtable\.)?speakers WHERE/SELECT sum\(speakerWords\), count(distinct spid) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers WHERE fname = filename AND/;
					$sqlQuery =~s/SELECT sum\(numwords\)/SELECT sum\(numwords\), count\(distinct fname\)/;
				} else {
					$sqlQuery = "SELECT sum(numwords), count(distinct fname) FROM $bwMYSQLtable.headerInfo WHERE $string";
					
				}
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				
				@rowArray=$sth->fetchrow_array;
				next loop if (!$rowArray[0]);
				$resTot{$j}=$rowArray[0];
				$resTotFname{$j}=$rowArray[1];
				$resTot{$j}=0 if (!$resTot{$j});
				
				$sqlQuery = "SELECT count($bwMYSQLusertable.$params{dbname}.fname), count(distinct $bwMYSQLusertable.$params{dbname}.fname) FROM $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.fname=$bwMYSQLtable.headerInfo.fname and $bwMYSQLtable.headerInfo.$string";
				$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.fname=$bwMYSQLtable.headerInfo.fname and $bwMYSQLtable.headerInfo.$string order by $bwMYSQLusertable.$params{dbname}.beginPosition ASC";
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);

				@rowArray=$sth->fetchrow_array;
				$resCount{$j} = $rowArray[0];
				$resCountDiff{$j} = $rowArray[1];
				$resCountThin{$j} = int(($rowArray[0] / $thinning) + 0.5);
				$resCountLink{$j} = $queryLink;
			} else {
				if ($categorySQL) {
					$sqlQuery = $categorySQL . " AND $string";
					# in case catRef and person elements are mixed
					$sqlQuery =~ s/SELECT sum\(numwords\) FROM ($bwMYSQLtable\.)?headerInfo WHERE/SELECT sum\(speakerWords\), count(distinct spid) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers WHERE fname = filename AND/;
					$sqlQuery =~s/SELECT sum\(numwords\)/SELECT sum\(numwords\), count\(distinct fname\)/;
					$sqlQuery =~s/SELECT sum\(speakerWords\)/SELECT sum\(speakerWords\), count\(distinct spid\)/;
				} else {
					$sqlQuery = "SELECT sum(speakerWords), count(distinct spid) FROM $bwMYSQLtable.speakers WHERE $string";
				}
	
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				next loop if (!$rowArray[0]);
				$resTot{$j}=$rowArray[0];
				$resTotFname{$j}=$rowArray[1];
				
				$resTot{$j}=0 if (!$resTot{$j});
				
				$sqlQuery = "SELECT STRAIGHT_JOIN count($bwMYSQLusertable.$params{dbname}.fname), count(distinct $bwMYSQLusertable.$params{dbname}.spid) FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid and $bwMYSQLtable.speakers.$string";
				$queryLink = "SELECT STRAIGHT_JOIN $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid and $bwMYSQLtable.speakers.$string order by $bwMYSQLusertable.$params{dbname}.beginPosition ASC";
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				$resCount{$j} = $rowArray[0];
				$resCountDiff{$j} = $rowArray[1];
				$resCountThin{$j} = int(($rowArray[0] / $thinning) + 0.5);
				$resCountLink{$j} = $queryLink;
			}
			if ($resCount{$j}) {
				$freq_per_millionThin{$j}=int ((($resCount{$j} / ($resTot{$j} / 1000000)) * 100 / $thinning) + 0.5) / 100;
				$freq_per_million{$j}=int ((($resCount{$j} / ($resTot{$j} / 1000000)) * 100) + 0.5) / 100;
			} else {
				$resCount{$j}=0;
				$freq_per_million{$j}=0;
				$freq_per_millionThin{$j}=0;
			}
				
		}


		foreach $cat (sort {$freq_per_million{$b} <=> $freq_per_million{$a};} keys(%freq_per_million)) {
 			$printRows .= "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$catValues{$theSillyStrings{$cat}}</TD>";
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($resTot{$cat}) . "</TD>";
 			$theNumber = &makeDecimals($resCount{$cat});
 			$theNumberThin = &makeDecimals($resCountThin{$cat});
 			if ($theNumber) {
 				$resCountLink{$cat} =~ s/(\W)/sprintf("%%%x", ord($1))/eg;
 
 				$history=$params{thMode};
 				$oldHistory = $history;
 				$history .= "##DO$theSillyStrings{$cat}#$resCount{$cat}";
 				setParam("thMode", "$history");		
 				$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$resCountLink{$cat}&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
 				setParam("thMode", "$oldHistory");	
 			} else {
 				$theLink = "0";
 			}
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . $theLink . "</TD>";
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($resCountDiff{$cat}) . "/" . &makeDecimals($resTotFname{$cat}) . "</TD>\n";
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$freq_per_million{$cat}</TD>\n";
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theNumberThin</TD>\n" if ($thinning < 1);
 			$printRows .= "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$freq_per_millionThin{$cat}</TD>\n" if ($thinning < 1);
		}

		$totalWords=0;
		$totalHits=0;
		$totalFiles=0;
		$totalHitsThin=0;
		$totalFilesTot=0;
		for ($j = 1; $j < $max; $j++) {
			$totalWords += $resTot{$j};
			$totalHits += $resCount{$j};
			$totalFiles += $resCountDiff{$j};
			$totalFilesTot += $resTotFname{$j};
			$totalHitsThin += $resCountThin{$j};
		}
		if ($totalWords) {
			print $header . $printRows;
			$freq_per_million=int ((($totalHits / ($totalWords / 1000000)) * 100 / $thinning) + 0.5) / 100;
			$freq_per_millionBare=int ((($totalHits / ($totalWords / 1000000)) * 100) + 0.5) / 100;
			print "<TR><TD BGCOLOR=\"#DDDDDD\"><B>&nbsp;total</B></TD>";
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalWords) . "</B></TD>";
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalHits) . "</B></TD>";
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalFiles) . "/" .  &makeDecimals($totalFilesTot)  . "</B></TD>";
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$freq_per_millionBare</B></TD>" if ($thinning < 1);
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$totalHitsThin</B></TD>" if ($thinning < 1);
			print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$freq_per_million</B></TD>\n";
		}
	}
	print "</TR></TABLE>\n";


	&printFooter();
	exit(0);
} else {
	# user selected two categories for cross-tabulation
	$sqlQuery = "SELECT DISTINCT fname FROM $params{dbname}";
	$sth= $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$countTheFiles = $sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	
	# check consistency of data
	$params{type}=~m/([a-zA-Z]+)(\d+)/;
	$cat=$1;
	$max=$2;
	$hitSpoken=$cat=~m/\A(age|sex|class|firstLanguage|education)\Z/;
	$max++ if (($cat eq "spowri") || ($cat eq "genre") || ($cat eq "alltim"));	
	
	$params{type2}=~m/([a-zA-Z]+)(\d+)/;
	$cat2=$1;
	$max2=($2);
	$hitSpoken2=$cat2=~m/\A(age|sex|class|firstLanguage|education)\Z/;
	$max2++ if (($cat2 eq "spowri") || ($cat2 eq "genre") || ($cat2 eq "alltim"));
	

	$information="";

	$check = $params{thMode}=~m/\AM(\d+)#?/;
	$numRes = $1 if ($check);

	$information = &createTitle($params{thMode}, $theDataL, $numRes);
	$information=~m/returned \d+ matches in (\d+) different texts/;
	$countTheFilesOrig = $1;
	unless ($countTheFilesOrig == $countTheFiles) {
		$information .= ". The current solution set was found in $countTheFiles texts.";
	}
	$information .= $timeInfo;
	
	&printForms();
	print <<HTML;
	<TABLE BORDER="0" CELLPADDING="3" WIDTH="100%">
	<TR>
		<TD HEIGHT="21" COLSPAN="$colspan" BGCOLOR="#FF9999"><B>&nbsp;The following distribution was found:</B></TD>
	</TR>
	
HTML
	
	loop: for ($j = 1; $j < $max; $j++) {
		if ($cat eq "derivedtexttype") {
			$k = $j;
			$k--;
			$string=$cat . "\=$k";
		} else {
			$string=$cat . "\=$j";
		}
		next loop if (!$catValues{$string});

		next loop if (($hitSpoken2) && ($string=~m/\A(wri\S+|genre=(2(?![0-4])\d|[3-7]\d)|spowri=1|derivedtexttype=[0-5]|alltim=[0-2]|alltyp=[3-6])\Z/));
				
		$header="";
		$header .= "<TR><TD COLSPAN=$colspan BGCOLOR=\"#FFCC99\"><BIG><B>$typeValues{$cat2} \/ $typeValues{$cat}: $catValues{$string}</B></BIG></TD></TR>\n";
		$header .= "<TR><TD BGCOLOR=\"#DDDDDD\"><B>&nbsp;</B></TD>\n";
		$header .= "<TD VALIGN=TOP ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of words</B></TD>\n";
		$header .= "<TD VALIGN=TOP ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of hits</B></TD>\n";
		if (($hitSpoken) || ($hitSpoken2))  {
			$header .= "<TD VALIGN=top WIDTH=\"15%\" ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Dispersion (over speakers)</B></TD>\n";
		} else {
			$header .= "<TD VALIGN=top WIDTH=\"15%\" ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Dispersion (over files)</B></TD>\n";
		}
		$header .= "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per <BR>million words</B></TD>\n";
		$header .= "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>No. of hits <BR>(extrapolated)</B></TD>\n" if ($thinning < 1);
		$header .= "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>Frequency per million <BR>words (extrapolated)</B></TD>\n" if ($thinning < 1);
		$header .= "</TR>";

		print $header;
		undef %freq_per_million;
		undef %resTot;
		undef %resCount;
		undef %resCountDiff;
		undef %resTotFname;
		
		loop2: for ($k = 1; $k < $max2; $k++) {
			if ($cat2 eq "derivedtexttype") {
				$l = $j;
				$l--;
				$string2=$cat2 . "\=$l";
			} else {
				$string2=$cat2 . "\=$k";
			}

			$theSillyStrings{$k}=$string2;
			
			next loop2 if (!$catValues{$string2});
			if ((!$hitSpoken) && (!$hitSpoken2)) {
				if ($categorySQL) {
					$sqlQuery = $categorySQL . "AND $string AND $string2";
					$sqlQuery =~ s/SELECT sum\(speakerWords\) FROM ($bwMYSQLtable\.)?speakers WHERE/SELECT sum\(speakerWords\), count(distinct spid) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers WHERE fname = filename AND/;
					$sqlQuery =~s/SELECT sum\(numwords\)/SELECT sum\(numwords\), count\(distinct fname\)/;
				} else {
					$sqlQuery = "SELECT sum(numwords), count(distinct fname) FROM $bwMYSQLtable.headerInfo WHERE $string AND $string2";
				}
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				$resTot{$k}=$rowArray[0];
				$resTotFname{$k}=$rowArray[1];
				$resTot{$k}=0 if (!$resTot{$k});
				
				$sqlQuery = "SELECT count($bwMYSQLusertable.$params{dbname}.fname), count(distinct $bwMYSQLusertable.$params{dbname}.fname) FROM $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.fname=$bwMYSQLtable.headerInfo.fname and $bwMYSQLtable.headerInfo.$string and $bwMYSQLtable.headerInfo.$string2";
				$queryLink = "SELECT $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.fname=$bwMYSQLtable.headerInfo.fname and $bwMYSQLtable.headerInfo.$string and $bwMYSQLtable.headerInfo.$string2";
				
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				$resCount{$k}=$rowArray[0];
				$resCountDiff{$k} = $rowArray[1];
				$resCountThin{$k} = int(($rowArray[0] / $thinning) + 0.5);
				$resCountLink{$k} = $queryLink;

			} elsif (($hitSpoken) && ($hitSpoken2)) {
				if ($categorySQL) {
					$sqlQuery = $categorySQL . " AND $string AND $string2";
					# in case catRef and person elements are mixed
					$sqlQuery =~ s/SELECT sum\(numwords\) FROM ($bwMYSQLtable\.)?headerInfo WHERE/SELECT sum\(speakerWords\), count(distinct spid) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers WHERE fname = filename AND/;
					$sqlQuery =~s/SELECT sum\(numwords\)/SELECT sum\(numwords\), count\(distinct fname\)/;
				} else {
					$sqlQuery = "SELECT sum(speakerWords), count(distinct spid) FROM $bwMYSQLtable.speakers WHERE $string AND $string2";
				}
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				$resTot{$k}=$rowArray[0];
				$resTotFname{$k}=$rowArray[1];
				$resTot{$k}=0 if (!$resTot{$k});
				$sqlQuery = "SELECT STRAIGHT_JOIN count($bwMYSQLusertable.$params{dbname}.fname), count(distinct $bwMYSQLusertable.$params{dbname}.spid) FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid and $bwMYSQLtable.speakers.$string and $bwMYSQLtable.speakers.$string2";
				$queryLink = "SELECT STRAIGHT_JOIN $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '/$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname} WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid and $bwMYSQLtable.speakers.$string and $bwMYSQLtable.speakers.$string2";

				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
				$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
				@rowArray=$sth->fetchrow_array;
				$resCount{$k}=$rowArray[0];
				$resCountDiff{$k} = $rowArray[1];
				$resCountThin{$k} = int(($rowArray[0] / $thinning) + 0.5);
				$resCountLink{$k} = $queryLink;
			} elsif (($hitSpoken) ne ($hitSpoken2)) {
				if ($hitSpoken) {
					$firstString = $string;
					$secondString = $string2;
				} else {
					$firstString = $string2;
					$secondString = $string;
				}
				if ($categorySQL) {
					$sqlQuery = $categorySQL . "AND $bwMYSQLtable.speakers2.$firstString AND $bwMYSQLtable.headerInfo.$secondString";
					# in case catRef and person elements are mixed
					$sqlQuery =~ s/SELECT sum\(numwords\) FROM ($bwMYSQLtable\.)?headerInfo WHERE/SELECT sum\(speakerWords\) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers2 WHERE headerInfo.fname = speakers2.filename AND/;
					$sqlQuery =~ s/SELECT sum\(speakerWords\) FROM ($bwMYSQLtable\.)?speakers2 WHERE/SELECT sum\(speakerWords\) FROM $bwMYSQLtable.headerInfo, $bwMYSQLtable.speakers2 WHERE headerInfo.fname = speakers2.filename AND/;
				} else {
					$sqlQuery = "SELECT sum(speakerWords), count(distinct spid) FROM $bwMYSQLtable.speakers, $bwMYSQLtable.headerInfo WHERE speakers.$firstString AND speakers.filename = headerInfo.fname AND headerInfo.$secondString";
				}
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle->errstr);
				$sth->execute or bark($categorySQL . "7bCan't execute $sqlQuery: " . $sth->errstr);
				@rowArray=$sth->fetchrow_array;
				$resTot{$k}=$rowArray[0];
				$resTotFname{$k}=$rowArray[1];
				$resTot{$k}=0 if (!$resTot{$k});
				$sqlQuery = "SELECT STRAIGHT_JOIN count($bwMYSQLusertable.$params{dbname}.fname), count(distinct $bwMYSQLusertable.$params{dbname}.spid) FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid and $bwMYSQLtable.speakers.$firstString and $bwMYSQLtable.speakers.filename = $bwMYSQLtable.headerInfo.fname AND $bwMYSQLtable.headerInfo.$secondString";
				$queryLink = "SELECT STRAIGHT_JOIN $bwMYSQLusertable.$params{dbname}.beginPosition, $bwMYSQLusertable.$params{dbname}.endPosition INTO OUTFILE '$bwMySQLTempPath/$params{dbname}_new' FROM $bwMYSQLtable.speakers, $bwMYSQLusertable.$params{dbname}, $bwMYSQLtable.headerInfo WHERE $bwMYSQLusertable.$params{dbname}.spid=$bwMYSQLtable.speakers.spid AND $bwMYSQLtable.speakers.$firstString AND $bwMYSQLtable.speakers.filename = $bwMYSQLtable.headerInfo.fname AND $bwMYSQLtable.headerInfo.$secondString";
				$sth= $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle->errstr);
				$sth->execute or bark("8Can't execute $sqlQuery: " . $sth->errstr);
				@rowArray=$sth->fetchrow_array;
				$resCount{$k}=$rowArray[0];
				$resCountDiff{$k} = $rowArray[1];
				$resCountThin{$k} = int(($rowArray[0] / $thinning) + 0.5);
				$resCountLink{$k} = $queryLink;
			}

			if ($resCount{$k}) {
				$freq_per_millionThin{$k}=int ((($resCount{$k} / ($resTot{$k} / 1000000)) * 100 / $thinning) + 0.5) / 100;
				$freq_per_million{$k}=int ((($resCount{$k} / ($resTot{$k} / 1000000)) * 100) + 0.5) / 100;
			} else {
				$resCount{$k}=0;
				$freq_per_million{$k}=0;
				$freq_per_millionThin{$k}=0;
			}
			
		}

			
		
		$totalWords=0;
		$totalHits=0;
		$totalHitsThin=0;
		$totalFiles=0;
		$totalFilesTot=0;

		foreach $cat (sort {$freq_per_million{$b} <=> $freq_per_million{$a};} keys(%freq_per_million)) {
			print "<TR><TD BGCOLOR=\"#EEEEEE\">&nbsp;$catValues{$theSillyStrings{$cat}}</TD>\n";
			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($resTot{$cat}) . "</TD>\n";
			$theNumber = &makeDecimals($resCount{$cat});
			$theNumberThin = &makeDecimals($resCountThin{$cat});
			if ($theNumber) {
				$resCountLink{$cat} =~ s/(\W)/sprintf("%%%x", ord($1))/eg;

				$history=$params{thMode};
				$oldHistory = $history;
				$history .= "##DC$string#$theSillyStrings{$cat}#$resCount{$cat}";
				setParam("thMode", "$history");	

				$theLink = "<A HREF=\"/$bwCGIalias/main.pl?theData=$paramsEnc{theData}&chunk=1&inst=50&max=INIT&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&SQL=$resCountLink{$cat}&program=distribution&view=$view&thMode=$paramsEnc{thMode}&dbname=$paramsEnc{dbname}&theID=$paramsEnc{theID}&urlTest=yes\">$theNumber<\/A>";
				setParam("thMode", "$oldHistory");	
				
			} else {
				$theLink = "0";
			}
			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . $theLink . "</TD>\n";
 			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">" . &makeDecimals($resCountDiff{$cat}) . "/" . &makeDecimals($resTotFname{$cat}) . "</TD>\n";
			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$freq_per_million{$cat}</TD>\n";
			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$theNumberThin</TD>\n" if ($thinning < 1);
			print "<TD ALIGN=center BGCOLOR=\"#EEEEEE\">$freq_per_millionThin{$cat}</TD>\n" if ($thinning < 1);
			$totalWords += $resTot{$cat};
			$totalHits += $resCount{$cat};
			$totalHitsThin += $resCountThin{$cat};
			$totalFilesTot += $resTotFname{$cat};
			$totalFiles += $resCountDiff{$cat};
		}


		
		if ($totalWords) {
			$freq_per_million=int ((($totalHits / ($totalWords / 1000000)) * 100 / $thinning) + 0.5) / 100;
			$freq_per_millionBare=int ((($totalHits / ($totalWords / 1000000)) * 100) + 0.5) / 100;
		} else {
			$freq_per_million=0;
		}
		print "<TR><TD BGCOLOR=\"#DDDDDD\"><B>&nbsp;total</B></TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalWords) . "</B></TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalHits) . "</B></TD>\n";
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>" . &makeDecimals($totalFiles) . "/" .  &makeDecimals($totalFilesTot)  . "</B></TD>";
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$freq_per_millionBare</B></TD>" if ($thinning < 1);
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$totalHitsThin</B></TD>" if ($thinning < 1);
		print "<TD ALIGN=center BGCOLOR=\"#DDDDDD\"><B>$freq_per_million</B></TD>\n";
	}
	
	print "</TR></TABLE>\n";
	
	&printFooter();
	exit(0);

}
sub printForms {
	print <<END;
<P>
<FORM ACTION="/$bwCGIalias/show_distribution.pl" METHOD=GET>

<TABLE BORDER="0" WIDTH="100%">
	<TR>
		<TD HEIGHT="21" COLSPAN="3" BGCOLOR="#CCCCFF">
			<B>&nbsp;$information</B>
		</TD>
	</TR>
END
	unless ($thinning == 1) {
			$thinFactor=int (($thinning * 10000) + 0.5) / 10000;
			print <<END;
				<TR>
					<TD HEIGHT="21" COLSPAN="3" BGCOLOR="#EEEEEE">
						Your initial query result was thinned. Extrapolated word counts and the corresponding frequeny per million words figures 
						are given in columns 6 and 7 (thin-factor: $thinFactor). 
						The smaller the thin-factor, the less reliable these figures will be.
					</TD>
				</TR>
END
	}
	
	print <<END;
	<TR>
		<TD WIDTH="13%" BGCOLOR="#DDDDDD">
			 &nbsp;Categories:
		</TD>
		<TD WIDTH="39%" HEIGHT=40 BGCOLOR="#DDDDDD" VALIGN=MIDDLE ALIGN=RIGHT>

			<INPUT TYPE="hidden" NAME="qname" VALUE="$params{qname}">
			<INPUT TYPE="hidden" NAME="queryID" VALUE="$params{queryID}">
			<INPUT TYPE="hidden" NAME="theID" VALUE="$params{theID}">
			<INPUT TYPE="hidden" NAME="dbname" VALUE="$params{dbname}">
			<INPUT TYPE="hidden" NAME="thMode" VALUE="$params{thMode}">
			<INPUT TYPE="hidden" NAME="chunk" VALUE="$params{chunk}">
			<INPUT TYPE="hidden" NAME="inst" VALUE="$params{inst}">
			<INPUT TYPE="hidden" NAME="SQL" VALUE="$params{SQL}">
			<INPUT TYPE="hidden" NAME="view" VALUE="$params{view}">
			<INPUT TYPE="hidden" NAME="max" VALUE="$params{max}">
			
			<SELECT name=type>
END

if (($subcorpus eq "no_subcorpus") || ($subcorpus=~m/(spowri|allava|alltyp=\'(3|4|5|6)\'|alltim|wriaag|wriad|wriase|wriaty|wriaud|wridom|wrilev|wrimed|wripp|wrisam|wrista|writas|genre=\'(4(0|1|2|3|4|5|6)|3\d|2\d|1\d|\d\'))/) || (!$categorySQL) || (!$spowri) || ($spowri eq "written")   || ($categorySQL=~m/\(fname =/)) {
			print <<END;
				<OPTION VALUE=spowri2 $selected{spowri2}> Overall: Spoken or Written
				<OPTION VALUE=alltyp6 $selected{alltyp6}> Overall: Text type
				<OPTION VALUE=genre70 $selected{genre70}> Overall: Genre
				<OPTION VALUE=derivedtexttype9 $selected{derivedtexttype9}> Overall: Derived text type
				<OPTION VALUE=wridom10 $selected{wridom10}> Written: Text domain
				<OPTION VALUE=alltim3 $selected{alltim3}> Written: Publication date
				<OPTION VALUE=wrimed6 $selected{wrimed6}> Written: Medium of Text
				<OPTION VALUE=wrisam6 $selected{wrisam6}> Written: Text Sample
				<OPTION VALUE=wriaag7 $selected{wriaag7}> Written: Age of Author
				<OPTION VALUE=wriase4 $selected{wriase4}> Written: Sex of Author
				<OPTION VALUE=wriad6 $selected{wriad6}> Written: Domicile of Author
				<OPTION VALUE=wriaty4 $selected{wriaty4}> Written: Type of Author
				<OPTION VALUE=wriaud5 $selected{wriaud5}> Written: Age of Audience
				<OPTION VALUE=writas4 $selected{writas4}> Written: Target audience sex
				<OPTION VALUE=wrilev4 $selected{wrilev4}> Written: Perceived level of difficulty
END
	}
	if (($subcorpus eq "no_subcorpus") || ($subcorpus=~m/(spowri|allava|alltyp=\'(1|2)\'|scgdom|sdeage|sdecla|sdesex|spolog|sporeg|genre=\'([1-9]\'|1\d|2(0|1|2|3|4)))/) || (!$categorySQL) || (!$spowri) || ($spowri eq "spoken") || ($categorySQL=~m/\(fname =/)) {
		print <<END;

				<OPTION VALUE=spolog3 $selected{spolog3}> Spoken Texts: Type of Interaction
				<OPTION VALUE=sporeg4 $selected{sporeg4}> Spoken Texts: Region where spoken text was captured
				<OPTION VALUE=sdeage7 $selected{sdeage7}> Spoken demogr: Age of Resp.
				<OPTION VALUE=sdesex3 $selected{sdesex3}> Spoken demogr: Gender of Resp.
				<OPTION VALUE=sdecla5 $selected{sdecla5}> Spoken demogr: Social class of Resp.
				<OPTION VALUE=scgdom5 $selected{scgdom5}> Spoken context-governed: Domain
				<OPTION VALUE=age7 $selected{age7}> Speaker: Age
				<OPTION VALUE=sex3 $selected{sex3}> Speaker: Sex
				<OPTION VALUE=class5 $selected{class5}> Speaker: Social Class
				<OPTION VALUE=firstLanguage5 $selected{firstLanguage6}> Speaker: First Language
				<OPTION VALUE=education6 $selected{education6}> Speaker: Education
				<OPTION VALUE=dialect28 $selected{dialect28}> Speaker: Dialect/accent (an unreliable category!)
END
	}
	print <<END;
				<OPTION VALUE=FREQ $selected{FREQ}> File-frequency extremes
END

	$theData2=&encodeForm($params{theData});


				print "<OPTION VALUE=FREQS $selected{FREQS}> Speaker-frequency extremes" unless (($spowri eq "written") || ($subcorpus=~m/(allava|alltyp=\'(3|4|5|6)\'|alltim|wriaag|wriad|wriase|wriaty|wriaud|wridom|wrilev|wrimed|wripp|wrisam|wrista|writas)/));
	print <<END;
				<OPTION VALUE=INIT $selected{INIT}> General information
			</SELECT>&nbsp;
		</TD>
		<TD WIDTH="28%" BGCOLOR="#CCCCCC">
			&nbsp;<INPUT TYPE="SUBMIT" VALUE="Show distribution">
		</TD>
	</TR>
	<TR>
		<TD WIDTH="17%" BGCOLOR="#DDDDDD">
			 &nbsp;Categories<BR>&nbsp;(for crosstabs only):
		</TD>
		<TD WIDTH="31%" HEIGHT=40 BGCOLOR="#DDDDDD" VALIGN=MIDDLE ALIGN=RIGHT>
			<INPUT TYPE="hidden" NAME="theData" VALUE="$theData2">
			<SELECT name=type2>
END
	
	if (($subcorpus eq "no_subcorpus") || ($subcorpus=~m/(spowri|allava|alltyp=\'(3|4|5|6)\'|alltim|wriaag|wriad|wriase|wriaty|wriaud|wridom|wrilev|wrimed|wripp|wrisam|wrista|writas)/) || (!$categorySQL) || (!$spowri) || ($spowri eq "written")  || ($categorySQL=~m/\(fname =/)) {
			print <<END;
				<OPTION VALUE=spowri2 $selected2{spowri2}> Overall: Spoken or Written
				<OPTION VALUE=alltyp6 $selected2{alltyp6}> Overall: Text type
				<OPTION VALUE=genre70 $selected2{genre70}> Overall: Genre
				<OPTION VALUE=derivedtexttype9 $selected{derivedtexttype9}> Overall: Derived text type
				<OPTION VALUE=wridom10 $selected2{wridom10}> Written: Text domain
				<OPTION VALUE=alltim3 $selected2{alltim3}> Written: Publication date
				<OPTION VALUE=wrimed6 $selected2{wrimed6}> Written: Medium of Text
				<OPTION VALUE=wrisam6 $selected2{wrisam6}> Written: Text Sample
				<OPTION VALUE=wriaag7 $selected2{wriaag7}> Written: Age of Author
				<OPTION VALUE=wriase4 $selected2{wriase4}> Written: Sex of Author
				<OPTION VALUE=wriad6 $selected2{wriad6}> Written: Domicile of Author
				<OPTION VALUE=wriaty4 $selected2{wriaty4}> Written: Type of Author
				<OPTION VALUE=wriaud5 $selected2{wriaud5}> Written: Age of Audience
				<OPTION VALUE=writas4 $selected2{writas4}> Written: Target audience sex
				<OPTION VALUE=wrilev4 $selected2{wrilev4}> Written: Perceived level of difficulty
END
	}
	if (($subcorpus eq "no_subcorpus") || ($subcorpus=~m/(spowri|allava|alltyp=\'(1|2)\'|scgdom|sdeage|sdecla|sdesex|spolog|sporeg)/) || (!$categorySQL) || (!$spowri) || ($spowri eq "spoken") || ($categorySQL=~m/\(fname =/)) {
		print <<END;
				
				<OPTION VALUE=spolog3 $selected2{spolog3}> Spoken Texts: Type of Interaction
				<OPTION VALUE=sporeg4 $selected{sporeg4}> Spoken Texts: Region where spoken text was captured
				<OPTION VALUE=sdeage7 $selected2{sdeage7}> Spoken demogr: Age of Resp.
				<OPTION VALUE=sdesex3 $selected2{sdesex3}> Spoken demogr: Gender of Resp.
				<OPTION VALUE=sdecla5 $selected2{sdecla5}> Spoken demogr: Social class of Resp.
				<OPTION VALUE=scgdom5 $selected2{scgdom5}> Spoken context-governed: Domain
				<OPTION VALUE=age7 $selected2{age7}> Speaker: Age
				<OPTION VALUE=sex3 $selected2{sex3}> Speaker: Sex
				<OPTION VALUE=class5 $selected2{class5}> Speaker: Social Class
				<OPTION VALUE=firstLanguage5 $selected2{firstLanguage6}> Speaker: First Language
				<OPTION VALUE=education6 $selected2{education6}> Speaker: Education
				<OPTION VALUE=dialect28 $selected{dialect28}> Speaker: Dialect/accent (an unreliable category!)
END
	}
	$theURL = getURLparams();
	$optionSelector="";
	$thing = 'Location: /' . $bwCGIalias . '/BNCquery.pl?theQuery=search&urlTest=yes';
	$optionSelector .= "<OPTION VALUE=\"$thing\">New Query";
	$thing = 'Location:/' . $bwCGIalias . '/main.pl?' . $theURL . '&urlTest=yes';
	$optionSelector .= "<OPTION VALUE=\"$thing\">Back to Query Result";

	print <<END;
				<OPTION VALUE=INIT $selected2{INIT}> no crosstabs
			</SELECT>&nbsp;
			<INPUT TYPE="hidden" NAME="urlTest" VALUE="yes">
			
		</TD>
		</FORM>
		<FORM ACTION="/$bwCGIalias/dlogs2.pl" METHOD=GET>
		<TD BGCOLOR="#DDDDDD">
			&nbsp;<SELECT NAME="selected">
				$optionSelector
			</SELECT>
			<INPUT TYPE="submit" VALUE="Go">
		</TD>
	
		</FORM>
	</TR>
</TABLE>

END
}
