#!/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;

use Time::HiRes qw (time);
use Getopt::Long qw(:config no_bundling no_ignore_case);

$startTime = time;

#set these items to suit your system
$username = $ENV{'REMOTE_USER'};

# browser-check?
$jScript=1;

# 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);
$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);
$frequencyHandle = DBI->connect("DBI:mysql:$bwMYSQLfrequency:$bwMYSQLhost:$bwMysqlPort", "$bwMysqlUser", "$bwMysqlPwd") or bark("Can't connect to mysql on $bwMYSQLhost at port: $bwMysqlPort <BR>" . $frequencyHandle::errstr);


$|=1;

	
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");
}

#setParam("theData", &decURL($params{theData}));

$variable=$params{kind};


$sqlQuery = "SELECT * FROM mysqlLog where feature = '$variable'";
$sth = $bncHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $bncHandle::errstr);
$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
$rows = $sth->rows;

# check for maximum number of concurrent collocations
if ($rows >= $bwConcurrentProcesses) {

	# check whether there are dead entries in mysqlLog
	$countDead = 0;
	$ps = qx{ps -aux};
	
	$sqlQuery = "SELECT processID FROM mysqlLog where feature = '$variable'";
	$sth = $bncHandle->prepare($sqlQuery) or barkFull("Can't prepare $sqlQuery: " . $bncHandle::errstr);
	$sth->execute or bark("Can't execute $sqlQuery: " . $sth::errstr);
	$rows = $sth->rows;
	for ($i = 0; $i < $rows; $i++) {
		@rowArray=$sth->fetchrow_array;
		$processID = $rowArray[0];
		$check=$ps=~m/[a-zA-Z]\s+${processID}\s/;
		unless ($check) {
			$sqlQuery = "DELETE FROM mysqlLog where processID = $processID";
			$bncHandle->do($sqlQuery) or barkFull("Can't delete: $sqlQuery: " . $bncHandle::errstr);
			$countDead++;
		}
	}
	# none of the pids are dead - display warning
	if (!$countDead) {
		&printHeader("Too many processes...");
		
		print <<END;
		<BODY BGCOLOR="#FFFFFF">
			<TABLE BORDER="0" CELLPADDING=3 CELLSPACING=2 WIDTH="100%">
				<TR>
					<TD HEIGHT="30" BGCOLOR="#FF3333">
						<BIG><BIG><B>Too many processes...</B></BIG></BIG>
					</TD>
				</TR>
				<TR>
					<TD HEIGHT="50" VALIGN="MIDDLE">
						There are already $bwConcurrentProcesses $variable databases being compiled. Please use the "back"-button
						of your browser and try again in a few moments.
					</TD>
				</TR>
			</TABLE>
			<HR>$bwCopyright
	
		</BODY>
		</HTML>		
	
END
		exit(0);
	}

} 


# check whether db is cached
$sqlQuery = "SELECT query, subcorpus FROM savedQueries WHERE theID = '$params{theID}'";
$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;
$SQquery=$rowArray[0];
$SQsubcorpus=$rowArray[1];
$SQqueryQuote = $bncHandle->quote($SQquery);
$SQsubcorpusQuote = $bncHandle->quote($SQsubcorpus);
$thModeQuote = $bncHandle->quote($params{thMode});
$SQsubcorpusQuote  = '\'\'' unless ($SQsubcorpus);

unless ($SQsubcorpus eq "###") {
	
	if ($variable eq "collocation") {
		$sortOrColl = " and includeLemma = '$params{includeLemma}' and totrange = $params{totrange} and sentBound = '$params{sentBound}'";
	} else {
		$sortOrColl = "";
	}
	
	$sqlQuery = "SELECT db_name FROM tableLog WHERE query = $SQqueryQuote and theRestrictions = $SQsubcorpusQuote and thMode = $thModeQuote and db_type = '$variable' $sortOrColl limit 1";
	$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;
	$dbname=$rowArray[0];
	if ($dbname) {
		$theTime = int(time);
		$sqlQuery = "UPDATE tableLog set crTime = $theTime where db_name='$dbname'";
		$bncHandle->do($sqlQuery) or bark("Can't insert $sqlQuery: " . $bncHandle::errstr);
		setParam("dbname", "$dbname");
	}

}



unless ($dbname) {
	# make sure users can't create enormous temp-tables
	$usernameQuote = $bncHandle->quote($username);
	
	$sqlQuery = "select collocationMax, sortMax from userLimits where user = $usernameQuote";
	$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;
	$collocMax=$rowArray[0];
	$sortMax=$rowArray[1];
	
	$collocMax = $bwDefaultCollocation if (!$collocMax);
	$sortMax = $bwDefaultSort if (!$sortMax);
	
	$error = 0;
	$error = 1 if (($params{numOfSolutions} > $collocMax) && ($variable eq "collocation"));
	$error = 1 if (($params{numOfSolutions} > $sortMax) && ($variable eq "sort"));
	if ($error) {
		if ($variable eq "collocation") {
			$displayMax = $collocMax;
		} elsif ($variable eq "sort") {
			$displayMax = $sortMax;
		}
		$displayMax = &makeDecimals($displayMax);
		
		$displayActual = &makeDecimals($params{numOfSolutions});
		
		&printHeader("Disk space alert");
		print <<END;
		<P>
		<TABLE BORDER="0" CELLPADDING="3" CELLSPACING="3" WIDTH="100%" BGCOLOR="#FFFFFF">
			<TR>
				<TD WIDTH="100%" HEIGHT="19" BGCOLOR="#CCCCFF"><FONT SIZE="4"><B>Disk Space Alert</B></FONT></TD>
			</TR>
			<TR>
				<TD WIDTH="100%" BGCOLOR="#DDDDDD"><B>The action you have requested would use up too much disk-space!</B></TD>
			</TR>
			<TR>
				<TD WIDTH="100%" BGCOLOR="#DDDDDD">
				
				You were trying to work with $displayActual hits but your limit is currently set to a maximum of $displayMax instances.<BR><BR>
				
				You can perform the desired action on a random subset of your data: In the query result display,
				select the option "Thin..." and then enter a number up to the maximum of $displayMax. Alternatively, if you really need access to the full set of data, 
				please contact your system administrator who will be able to increase the limit for you.</TD>
			</TR>
		</TABLE>
		<HR>$bwCopyright
	
		</BODY>
		</HTML>		
END
		exit(0);
	}

}


$subcorpus = &subcorpusCheck($params{thMode});
@subcorpParts = split (/ \& /, $subcorpus);
$subcorpus=join(' & ', sort { lc($a) cmp lc($b) } @subcorpParts);

if (($params{fListCache}) && ($variable eq "collocation")) {
	# update timestamp in cache
	$theTime = int(time);
	$sqlQuery = "UPDATE frequencyLists set time_of_creation=$theTime where subcorpus='$subcorpus'";
	$bncHandle->do($sqlQuery) or bark("Can't $sqlQuery: " . $bncHandle::errstr);

}


if ((($subcorpus) && (!$params{fListCache}) && ($variable eq "collocation")) || ($params{basis}) || (!$dbname)) {	
	
	
	&printHeader("Storing $variable data...");
	
	print <<END;
	<BODY BGCOLOR="#FFFFFF">
		<TABLE BORDER="0" CELLPADDING=3 CELLSPACING=2 WIDTH="100%">
			<TR>
				<TD HEIGHT="30" BGCOLOR="#CCCCFF">
					<BIG><BIG><B>Storing $variable data...</B></BIG></BIG>
				</TD>
			</TR>
			<TR>
				<TD BGCOLOR="#FFFFFF" HEIGHT="30">
END


	if ($jScript) {
		print "After the calculation has finished, you will automatically be taken to the ";
		print "result page. (If not, enable JavaScript in your browser) </TD></TR>";
	}

}

## create frequency lists unless already cached (or user has selected a pre-compiled list)


if (($subcorpus) && (!$params{fListCache}) && ($variable eq "collocation") && (!$params{basis})) {
	
	$time = int(time);
	$tempname = $username . "_" . $time;

	&compileFlist($subcorpus, $tempname, $username);

	&deleteCachedFreqlists($bwMaxFreqlistMySQL);
		
	setParam("fListCache", "$tempname");	
	
}

unless ($dbname) {
	# connect to CQP
	CQPconnect();
	
	$CQP->exec("set Context 0");			# set context & display options for kwic lines
	$CQP->exec("show -cpos");
	
	
	$startTime = int(time);
	$processID = $$;
	$theID = "${startTime}_${username}";
	$sqlQuery = "INSERT INTO mysqlLog (
		db_name, 
		feature,
		crTime,
		processID
		) VALUES (
		'$theID',
		'$variable',
		$startTime,
		$processID
		)";
	$bncHandle->do($sqlQuery) or bark("Can't insert $sqlQuery: " . $bncHandle::errstr);
	
	
	$dbTime=int(time);
	if ($variable eq "collocation") {
		$dbname="${dbTime}_${username}_col";
	} elsif ($variable eq "sort") {
		$dbname="${dbTime}_${username}_adj";
	}
	setParam("dbname", "$dbname");

	
	$decOld="0";
	$oneOld="0";
	
	$sqlQuery = "DROP TABLE IF EXISTS $dbname";
	$userHandle->do($sqlQuery);
	
	if ($variable eq "collocation") {
				
		$lemmaAdd = "";
		$lemmaAdd = "lemma char(60)," if ($params{includeLemma} eq "yes");

		$sqlQuery = "CREATE TABLE $params{dbname} (
			refnum MEDIUMINT UNSIGNED NOT NULL,
			item char(40) NOT NULL,
			$lemmaAdd
			dist SMALLINT NOT NULL,
			fname char(3),
			tag char(7) NOT NULL,
			beginPosition int,
			endPosition int
		) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE latin1_general_ci";
	} elsif ($variable eq "sort") {
		$sqlQuery = "CREATE TABLE $dbname (
			before5 char(80) NOT NULL,
			before4 char(80) NOT NULL,
			before3 char(80) NOT NULL,
			before2 char(80) NOT NULL,
			before1 char(80) NOT NULL,
			after1 char(80) NOT NULL,
			after2 char(80) NOT NULL,
			after3 char(80) NOT NULL,
			after4 char(80) NOT NULL,
			after5 char(80) NOT NULL,
			tagbefore5 char(7) NOT NULL,
			tagbefore4 char(7) NOT NULL,
			tagbefore3 char(7) NOT NULL,
			tagbefore2 char(7) NOT NULL,
			tagbefore1 char(7) NOT NULL,
			tagafter1 char(7) NOT NULL,
			tagafter2 char(7) NOT NULL,
			tagafter3 char(7) NOT NULL,
			tagafter4 char(7) NOT NULL,
			tagafter5 char(7) NOT NULL,
			node char(120) NOT NULL,
			tagnode char(70) NOT NULL,
			fname char(3),
			beginPosition int,
			endPosition int,
			refnum MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
			key(refnum)
			) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE latin1_general_ci";
	}
	
	$userHandle->do($sqlQuery) or bark("Can't bloody create table $sqlQuery: " . $userHandle::errstr);
	
	# delete old temporary tables
	&deleteCachedMySQLTables($bwMaxMySQLSize);
	
	# open saved solution set
	$qName = $params{qname};
	
	$CQP->exec("set DataDirectory '/$bwTempPath/'");
	$CQP->exec("$bwCorpus");
	
	($theNum) = $CQP->exec("size $qName");
	
	print "<TR><TD>Extracting context data... <BR></TD></TR>";
	warn "beginning data export ".time;
	
	
	# Change this to include lemma information by default! 
	# remove $params{includeLemma} in previous page???
	# uses more space, of course...
	# maybe leave in option?
	# discuss with SE
	# SH 29.4.2006
	if ($variable eq "collocation") {
	
		# set $parms{sortpos} to avoid error when inserting into tableLog;
		setParam("sortpos", "0");

	    my $window = $params{totrange};
	    my $include_lemma = ($params{includeLemma} eq "yes") ? 1 : 0;
	    
	    $temp = new CWB::TempFile "/$bwTempPath/";
	    $temp->finish;
	    $tempname = $temp->name;
	    $tempname=~m/\/([^\/]+)\Z/;
	    $mysqlTempname = $1;
	    
	    my $awk = new CWB::TempFile "/$bwTempPath/";
	    $awk->write('BEGIN{ OFS = FS = "\t" }', "\n");
	    my $tabulate_cmd = "tabulate $qName ";
	    
	    if ($params{sentBound}) {
		if ($include_lemma) {
		    $tabulate_cmd .= join(", ", "match", "matchend", "match text_id", "match s_n", 
					  (map {"match[$_] word, match[$_] pos, match[$_] s_n, match[$_] lemma"} -$window .. -1),
					  (map {"matchend[$_] word, matchend[$_] pos, matchend[$_] s_n, matchend[$_] lemma"} 1 .. $window));
		}
		else{
		    $tabulate_cmd .= join(", ", "match", "matchend", "match text_id", "match s_n", 
					  (map {"match[$_] word, match[$_] pos, match[$_] s_n"} -$window .. -1),
					  (map {"matchend[$_] word, matchend[$_] pos, matchend[$_] s_n"} 1 .. $window));
		}
		my $match = '$1';		# gawk fields
		my $matchend = '$2';
		my $text_id = '$3';
		my $s_n = '$4';
		my %word = ();		# can be used as $word{-3}, $word{1}, ...
		my %lemma = ();
		my %pos = ();
		my %s_n = ();
		foreach my $i (-$window .. -1, 1 .. $window) {
		    my $delta = (($i < 0) ? $window + $i : $window + $i - 1); # (NB there's no data in the tabulate output for $i == 0)
		    my $offset = 5 + $delta * (($include_lemma) ? 4 : 3);	# pre-calculate offset of information items in tabulate output
		    $word{$i} = '$'.$offset;
		    $pos{$i} = '$'.($offset+1);
		    $s_n{$i} = '$'.($offset+2);
		    $lemma{$i} = '$'.($offset+3)
			if $include_lemma;
		}
		foreach my $i (-$window .. -1, 1 .. $window) {
		    if ($include_lemma) {
			$awk->write("$s_n{$i} == $s_n { print NR-1, $word{$i}, $lemma{$i}, $i, $text_id, $pos{$i}, $match, $matchend }\n");
		    }
		    else {
			$awk->write("$s_n{$i} == $s_n { print NR-1, $word{$i}, $i, $text_id, $pos{$i}, $match, $matchend }\n");
		    }
		}
	    } else {
		if ($include_lemma) {
		    $tabulate_cmd .= join(", ", "match", "matchend", "match text_id",  
					  (map {"match[$_] word, match[$_] pos, match[$_] lemma"} -$window .. -1),
					  (map {"matchend[$_] word, matchend[$_] pos, matchend[$_] lemma"} 1 .. $window));
		}
		else {
		    $tabulate_cmd .= join(", ", "match", "matchend", "match text_id",  
					  (map {"match[$_] word, match[$_] pos"} -$window .. -1),
					  (map {"matchend[$_] word, matchend[$_] pos"} 1 .. $window));
		}
		my $match = '$1';		# gawk fields
		my $matchend = '$2';
		my $text_id = '$3';
		my %word = ();		# can be used as $word{-3}, $word{1}, ...
		my %lemma = ();
		my %pos = ();
		foreach my $i (-$window .. -1, 1 .. $window) {
		    my $delta = (($i < 0) ? $window + $i : $window + $i - 1); # (NB there's no data in the tabulate output for $i == 0)
		    my $offset = 4 + $delta * (($include_lemma) ? 3 : 2);	# pre-calculate offset of information items in tabulate output
		    $word{$i} = '$'.$offset;
		    $pos{$i} = '$'.($offset+1);
		    $lemma{$i} = '$'.($offset+2)
			if $include_lemma;
		}
		foreach my $i (-$window .. -1, 1 .. $window) {
		    if ($include_lemma) {
			$awk->write("{ print NR-1, $word{$i}, $lemma{$i}, $i, $text_id, $pos{$i}, $match, $matchend }\n");
		    }
		    else {
			$awk->write("{ print NR-1, $word{$i}, $i, $text_id, $pos{$i}, $match, $matchend }\n");
		    }
		}
	    }

	    $awk->finish;
	    my $awk_prog = $awk->name;
	    
	    ## Use this code for testing and debugging purposes:
	    #warn "TABULATE CMD:\n", "$tabulate_cmd\n\n";
	    #warn "AWK SCRIPT:\n", `cat $awk_prog`, "\n";

	    $CQP->exec("$tabulate_cmd > \"| awk -f '$awk_prog' > $tempname\"");
	    $awk->close;
	    
	    warn "beginning load infile ".time;
	    
	} elsif ($variable eq "sort") {
	
	
		# set collocation-specific variables to "" to avoid errors when inserting into tableLog;
		setParam("totrange", "0");
		setParam("sentBound", "0");

		my $offset = $params{sortpos};
		my $word_lemma = "word"; # change this to sort based on lemmas
		
		$temp = new CWB::TempFile "/$bwTempPath/";
		$temp->finish;
		$tempname = $temp->name;
		$tempname=~m/\/([^\/]+)\Z/;
		$mysqlTempname = $1;
	
		my $tabulate_cmd = "tabulate $qName "
		    . "match[-5] $word_lemma, match[-4] $word_lemma, match[-3] $word_lemma, match[-2] $word_lemma, match[-1] $word_lemma, "
		    . "matchend[1] $word_lemma, matchend[2] $word_lemma, matchend[3] $word_lemma, matchend[4] $word_lemma, matchend[5] $word_lemma, "
		    . "match[-5] pos, match[-4] pos, match[-3] pos, match[-2] pos, match[-1] pos, "
		    . "matchend[1] pos, matchend[2] pos, matchend[3] pos, matchend[4] pos, matchend[5] pos, "
		    . "match .. matchend $word_lemma, match .. matchend pos, "
		    . "match text_id, match, matchend";
		$CQP->exec("$tabulate_cmd > '$tempname'");
	
	}
		
	print "<TR><TD>Importing tokens into database... <BR></TD></TR>";
	
	$sqlQuery = "Alter table $dbname disable keys";
	$userHandle->do($sqlQuery);
	$sqlQuery = "LOAD DATA INFILE '/$bwMySQLTempPath/$mysqlTempname' into table $dbname FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY ''";
	$userHandle->do($sqlQuery);

	$sqlQuery = "Alter table $dbname enable keys";
	$userHandle->do($sqlQuery);
	
	print "100% done!!</TABLE>\n" unless ($jScript);
	

	
	$temp->close;
	
	$sqlQuery = "DELETE FROM mysqlLog where db_name='$theID'";
	$bncHandle->do($sqlQuery) or bark("Can't $sqlQuery: " . $bncHandle::errstr);

# 	$sqlQuery = "SELECT count(*) FROM $dbname";
# 	$sth = $userHandle->prepare($sqlQuery) or bark("Can't prepare $sqlQuery: " . $userHandle::errstr);
# 	$sth->execute or bark("Can't execute $sqlQuery: ". $sth::errstr);
# 	@rowArray=$sth->fetchrow_array;
# 	$numRows=$rowArray[0];

	$numRows = &getTableSize($dbname);
	
	$theTime=int(time);
		
	$sqlQuery = "INSERT INTO tableLog (
			db_name, 
			crTime, 
			thMode,
			query,
			theRestrictions, 
			db_type,
			numRows,
			includeLemma,
			totrange,
			sentBound,
			sortpos
		) VALUES (
			'$dbname', 
			$theTime,
			$thModeQuote,
			$SQqueryQuote,
			$SQsubcorpusQuote,
			'$variable',
			$numRows,
			'$params{includeLemma}',
			$params{totrange},
			'$params{sentBound}',
			0
		)";
	$bncHandle->do($sqlQuery) or bark("Can't insert $sqlQuery: " . $bncHandle::errstr);

	$endTime = time;
	$timeTaken = int((($endTime - $startTime) * 1000) + 0.5)/ 1000;
	setParam("timeTaken","$timeTaken");
		
} else {
	setParam("timeTaken","cache");
	&printHeader("Storing $variable data...");

	print <<END;
	<BODY BGCOLOR="#FFFFFF">		
END
	#print "</TABLE>\n" if (($subcorpus) && (!$params{fListCache}) && ($variable eq "collocation"));
}

# check how to change this!

if ($variable eq "collocation") {
	if ($jScript) {
		$indexBut = '/' . $bwCGIalias . '/show_collocation.pl?qname=' . $paramsEnc{qname} . '&queryID=' . $paramsEnc{queryID} . '&dbname=' . $paramsEnc{dbname} . '&numOfSolutions=' . $paramsEnc{numOfSolutions} . '&timeTaken=' . $paramsEnc{timeTaken} . '&delRare=' . $paramsEnc{delRare} . '&begin=0&theData=' . $paramsEnc{theData} . '&minus=' . (0 - $params{totrange}) . '&plus=' . $params{totrange} . '&word=&statType=' . $paramsEnc{statType} . '&basis=' . $paramsEnc{basis} . '&excludePun=' . $paramsEnc{excludePun} . '&down=0&totrange=' . $params{totrange} . '&totfreq=5&thinning=' . $paramsEnc{thinning} . '&coll=0&thMode=' . $paramsEnc{thMode} . '&includeLemma=' . $params{includeLemma} . '&inst=' . $paramsEnc{inst} . '&sentBound=' . $paramsEnc{sentBound} . '&theID=' . $paramsEnc{theID} . '&fListCache=' . $paramsEnc{fListCache} . '&first=yes&urlTest=yes';


		print <<END;
		
		<SCRIPT><!--
		location.replace("$indexBut");
		//--></SCRIPT>
	
END
	} 
	
	print '<BR><A HREF="/' . $bwCGIalias . '/show_collocation.pl?qname=' . $paramsEnc{qname} . '&dbname=' . $paramsEnc{dbname} . '&queryID=' . $paramsEnc{queryID} . '&numOfSolutions=' . $paramsEnc{numOfSolutions} . '&timeTaken=' . $paramsEnc{timeTaken} . '&delRare=' . $paramsEnc{delRare} . '&begin=0&theData=' . $paramsEnc{theData} . '&minus=' . (0 - $params{totrange}) . '&plus=' . $params{totrange} . '&word=&statType=' . $paramsEnc{statType} . '&basis=' . $paramsEnc{basis} . '&excludePun=' . $paramsEnc{excludePun} . '&down=0&totrange=' . $params{totrange} . '&totfreq=5&thinning=' . $paramsEnc{thinning} . '&coll=0&thMode=' . $paramsEnc{thMode} . '&inst=' . $paramsEnc{inst} . '&sentBound=' . $paramsEnc{sentBound} . '&theID=' . $paramsEnc{theID} . '&fListCache=' . $paramsEnc{fListCache} . '&first=yes&urlTest=yes"> [Show collocations] </A>';

} elsif ($variable eq "sort") {
	if ($params{sorttype} eq "direct") {
	
		if ($params{ot} eq "tagafter1") {
			$reverseOrderType = "after1";
		} else {
			$reverseOrderType = "before1";
		}
		
		$SQL = "SELECT beginPosition, endPosition, $ot INTO OUTFILE '/$bwMySQLTempPath/${dbname}_new' FROM $dbname ORDER BY $params{ot}, $reverseOrderType";
		
		setParam("SQL", "$SQL");
		
		if ($jScript) {
			$ButBefore = '/' . $bwCGIalias . '/sort_freqList.pl?XYZ2';
			$theURL = getURLparams();
			$link = "$theURL&program=sort&dbname=$dbname&chunk=1&view=kwic&changeSort=yes&changePosition=yes&urlTest=yes";
			$ButBefore =~ s/XYZ2/$link/o;	
			print <<END;
			
			<SCRIPT><!--
			location.replace("$ButBefore");
			//--></SCRIPT>
		
END
		} 
		
	} else {
		if ($jScript) {
			$ButBefore = '/' . $bwCGIalias . '/main.pl?XYZ2';
			$link = "program=sort&theData=$paramsEnc{theData}&dbname=$dbname&chunk=1&inst=$paramsEnc{inst}&max=$paramsEnc{max}&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&ot=$paramsEnc{ot}&letter=&tag=&view=kwic&thMode=$paramsEnc{thMode}&sortpos=$paramsEnc{sortpos}&changeSort=yes&changePosition=yes&theID=$paramsEnc{theID}&timeTaken=$paramsEnc{timeTaken}&urlTest=yes";
			$ButBefore =~ s/XYZ2/$link/o;	
			print <<END;
			
			<SCRIPT><!--
			location.replace("$ButBefore");
			//--></SCRIPT>
		
END
		} else {
			print '<BR><A HREF="/' . $bwCGIalias . '/main.pl?program=sort&theData=$paramsEnc{theData}&dbname=$dbname&chunk=1&inst=$paramsEnc{inst}&max=$paramsEnc{max}&queryID=$paramsEnc{queryID}&qname=$paramsEnc{qname}&ot=$paramsEnc{ot}&letter=&tag=&view=kwic&thMode=$paramsEnc{thMode}&sortpos=$paramsEnc{sortpos}&changeSort=yes&changePosition=yes&theID=$paramsEnc{theID}&timeTaken=$paramsEnc{timeTaken}&urlTest=yes">Show results</A>';
		}
	}

}
&CQPdisconnect();
exit (0);

