#!/usr/local/bin/perl

#NB: on Demon, needs to be #!/bin/perl
#NB: on Dolly, needs to be #!/usr/local/bin/perl

# please do a chmod 755 on me when you've uploaded

#what do we need then?
require 'D:\wwwroot\San Diego Museum of Art\www.sdmart.org\image\cogapp-cgi-lib.pl';

#Read in my arguments
&ReadParse(*theForm);


$sendMail		= $theForm{'sendMail'};
$highlightAtoZ	= $theForm{'highlightAtoZ'};
$highlightCatSubSection	= $theForm{'highlightCatSubSection'};
$pageTitle		= $theForm{'pageTitle'}; #set to default below after script has run.
$queryartist	= $theForm{'artist'};
$queryartists	= $theForm{'artists'};
$queryterm		= $theForm{'term'};
$queryterms		= $theForm{'terms'};
$querysubject	= $theForm{'subject'};
$querycatalogue	= $theForm{'catalogue'};
$querysubjects	= $theForm{'subjects'};
$querypainting	= $theForm{'painting'};
$queryblowup	= $theForm{'blowup'};
$querydetail	= $theForm{'detail'};
$queryglossary	= $theForm{'glossary'};
$queryhowbig	= $theForm{'howbig'};
$querywheremade	= $theForm{'wheremade'};
$queryalink		= $theForm{'alink'};
$queryelink		= $theForm{'elink'};
$thisaxis		= $theForm{'axis'};
$queryreturn	= $theForm{'return'};
$queryscript	= $theForm{'script'};
$wotmode		= $theForm{'mode'};
$swfDisplay		= $theForm{'swfDisplay'};

$querysearch	= $theForm{'search'};
$searchmode		= $theForm{'searchmode'};
$searchtype		= $theForm{'searchtype'};

$image			= $theForm{'Image'};
$collection		= $theForm{'Collection'};
$searchStr		= $theForm{'Search'};
$start			= $theForm{'Start'};
$end			= $theForm{'End'};
$searchMode		= $theForm{'SearchMode'};
$onlyOneMatch	= $theForm{'onlyOneMatch'};


# where do I look for things?
if ( "$ENV{'HTTP_HOST'}" =~ 'dolly' ) {

	# testing on Dolly
	
	$docs			= 'templates/';#'../docs/uk/';
	$dbs			= 'dbs/';#'../docs/uk/';
	if ( $wotmode eq 'test' ) {
		$cgipath		= 'image.pl';
	} else {
		$cgipath		= 'image.pl';
	}
	$imagePath		= 'images/';
} elsif ( "$ENV{'HTTP_HOST'}" =~ 'sdmart.org' ) {

	# probable final location on Demon (www.sdmart.org)
	
	if ( $wotmode eq 'test' ) {
		$docs			= 'D:\wwwroot\SanDiego Museum of Art\www.sdmart.org\image\templatesdev\\';
		$dbs			= 'D:\wwwroot\San Diego Museum of Art\www.sdmart.org\image\dbsdev\\';
		$cgipath		= 'http://cgi.www.sandiegomuseum.org/cgi-bin/www.sandiegomuseum.org/imagedev.pl';
	} else {
		$docs			= 'D:\wwwroot\San Diego Museum of Art\www.sdmart.org\image\templates\\';
		$dbs			= 'D:\wwwroot\San Diego Museum of Art\www.sdmart.org\image\dbs\\';
		$cgipath		= 'http://www.sdmart.org/image/image.pl';
	}
	$imagePath		= 'http://www.sdmart.org/image/images/';
} else {

	# initial public location at sdmart.com
	
	if ( $wotmode eq 'test' ) {
		$docs			= '../secure_html/templatesdev/';
		$dbs			= '../secure_html/dbsdev/';
		$cgipath		= 'image.pl';
	} else {
		$docs			= '../secure_html/templates/';
		$dbs			= '../secure_html/dbs/';
		$cgipath		= 'image.pl';
	}
	$imagePath		= 'http://www.sandiegomuseum.org/imageimages/';
}


$mapsPath		= $imagePath.'maps/';
$fullsizes		= $imagePath.'fullsize/';
$thumbs			= $imagePath.'thumbs/';
$navImages		= $imagePath.'nav/';
$thdetails		= $thumbs.'details/';
$fsdetails		= $fullsizes.'details/';
$movies			= $imagePath.'movies/';
$todaysSelections	= $dbs.'todaysSelections/';


#assign file names
$moviesdb		= $dbs.'movies.db';
$artistdb		= $dbs.'artist.db';
$encyclodb		= $dbs.'encyclo.db';
$subjectdb		= $dbs.'subject.db';
$scriptdb		= $dbs.'script.db';
$glossarydb		= $dbs.'glossary.db';
$worksdb		= $dbs.'works.db';
$imagesdb		= $dbs.'image.db';
$mapsdb			= $dbs.'maps.db';
$linksdb		= $dbs.'links.db';
$hotaxes		= $dbs.'hotaxes.db';
$coldaxes		= $dbs.'coldaxes.db';
$sectionsdb		= $dbs.'sections.db';
$cataloguedb	= $dbs.'catalogue.db';
$buttonsdb		= $dbs.'buttons.db';

$header			= $docs.'header.html';
$indexpicker	= $docs.'indexpicker.html';
$footer			= $docs.'footer.html';
$aIndexTemplate	= $docs.'aIndex.html';
$eIndexTemplate	= $docs.'eIndex.html';
$sIndexTemplate	= $docs.'sIndex.html';
$artistTemplate	= $docs.'artist.html';
$termTemplate	= $docs.'term.html';
$subjectTemplate= $docs.'subject.html';
$thumbTemplate	= $docs.'thumb.html';
$workTemplate	= $docs.'work.html';
$scriptTemplate	= $docs.'script.html';
$blowupTemplate	= $docs.'blowup.html';
$fsPicTemplate	= $docs.'fspic.html';
$buPicTemplate	= $docs.'bupic.html';
$detPicTemplate	= $docs.'detpic.html';
$probTemplate	= $docs.'problem.html';
$glossTemplate	= $docs.'glossary.html';
$howbigTemplate	= $docs.'howbig.html';
$wheremadeTemplate	= $docs.'wheremade.html';
$catTemplate	= $docs.'catalogueList.html';
$searchresult	= $docs.'searchresult.html';
$searchChoice	= $docs.'searchChoice.html';
$detailTemplate	= $docs.'detail.html';
$labelTemplate	= $docs.'label.html';
$prevTemplate	= $docs.'prev.html';
$nextTemplate	= $docs.'next.html';
$featureTemplate= $docs.'feature.html';
$swfPlacerTemplate	= $docs.'swfPlacer.html';
$swfMovieTemplate	= $docs.'swfMovie.html';
$todaysSelectionTemplateFile	= $docs.'todaysSelection.html';


# things to go into row 4 of the header
$row4picker		= $docs.'row4picker.html';
$row4cat		= $docs.'row4cat.html';
$row4search		= $docs.'row4search.html';
$row4artist		= $docs.'row4artist.html';
$row4work		= $docs.'row4work.html';
$row4term		= $docs.'row4term.html';
$row4subject	= $docs.'row4subject.html';  # some html tags
$ss				= '<STRONG>';
$se				= '</STRONG>';
$p				= '<P>';
$fs				= '<FONT FACE="Ariel,Helvetica,GillSans,Gill">';
$fs				= '<FONT size=3 FACE="Arial,Helvetica,sans-serif" color="#000066">';
$fs2			= '<FONT size=2 FACE="Arial,Helvetica,sans-serif" color="#000066">';
$fe				= '</FONT>';

# some globals
$newAxis		= time();
$protectedAxes	= 2; # AllMuseums and AllArtists
$keepAxes		= 60*60*24; # 24 hours
#this is the standin image name for pictures not to show on the web
$defaultImage	= "NotForWeb.gif";

$contentType	= "Content-type: text/html\n\n";
$contentType	= "Content-type: text/plain\n\n";
$htmlReturn		= &GenericProblem( $query );
$DisplayAtATime	= 20;


%gBtnArray		= ( '','' );
%gBtnArrayAltTags		= ( '','' );
$noofbtns		= &ButtonsArray();

@sectionPicker	= ( 'artist', 'subject', 'catalogue', 'term', 'search' );
@azPicker		= split( '', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' );
@catalogueSubSectionPicker		= ( 'american', 'european', 'farEastern', 'modern', 'southAsian', 'printsAndDrawings' );
%catalogueSubSectionGivesImageNames	= (	'AMERICAN ART','american', 'EUROPEAN ART','european', 'FAR EASTERN ART','farEastern', 'MODERN ART','modern', 'SOUTH ASIAN ART','southAsian', 'PRINTS & DRAWINGS','printsAndDrawings' );

$htmextn		= '.htm';
$htmlextn		= '.html';
$oCurly			= '{';
$cCurly			= '}';

# debug stuff
$DEBUG			= 'variables';
$DEBUG			= 'false';

#this is the scale image used in 'How big is it?'
$manpix = "scale.gif";

#dimensions (pixels & cms of the man in the howbigisit popup)
$manwidthpix	= 184;
$manheightpix	= 291;
$manheightin	= 72;
$manheightcm	= 200;
$popupborder	= 45;

#############################


#are we doing a GET )if not what are we doing?)
if ($ENV{'REQUEST_METHOD'} eq "POST" || $ENV{'REQUEST_METHOD'} eq "GET") {

	if ( $DEBUG eq 'variables' ) {
		print &GenericProblem( "{Request method=$ENV{'REQUEST_METHOD'}}<BR>{noofbtns=$noofbtns}<BR>{axis=$thisaxis}<BR>{newAxis=$newAxis}<BR>{search=$searchStr}<BR>{image=$image}<BR>{collection=$collection}<BR>{start=$start}<BR>{SearchMode=$searchMode}<BR>{end=$end}<BR>Date: ".&Date() );
		exit;
	}
	
	if ( $queryartists ne '' ) {
		
		# artist index request
		$htmlReturn = &GetIndex( $artistdb, $queryartists, $thisaxis, $newAxis, $start, $end );
	
	} elsif ( $queryterms ne '' ) {
		
		# terms index request
		$htmlReturn = &GetIndex( $encyclodb, $queryterms, $thisaxis, $newAxis, $start, $end );
	
	} elsif ( $querysubjects ne '' ) {
		
		# subject index request
		$htmlReturn = &GetIndex( $subjectdb, $querysubjects, $thisaxis, $newAxis, $start, $end );
	
	} elsif ( $queryartist ne '' ) {
		
		# artist request
		$htmlReturn = &GetArtist( $queryartist, $thisaxis, $newAxis, $start, $end, $highlightAtoZ );
	
	} elsif ( $queryterm ne '' ) {
		
		# encyclopedia request
		$htmlReturn = &GetTerm( $queryterm, $thisaxis, $newAxis, $start, $end, $highlightAtoZ );
	
	} elsif ( $querysubject ne '' ) {
		
		# subject request
		$htmlReturn = &GetSubject( $querysubject, $thisaxis, $newAxis, $start, $end, $highlightAtoZ );
	
	} elsif ( $querypainting ne '' ) {

		# its an image		
		$htmlReturn = &GetWork( $querypainting, $fsPicTemplate, $workTemplate, $thisaxis, $newAxis );
	
	} elsif ( $queryscript ne '' ) {

		# its an image		
		$htmlReturn = &GetScript( $queryscript, $thisaxis, $newAxis );
	
	} elsif ( $queryblowup ne '' ) {

		# its an image		
		$htmlReturn = &GetWork( $queryblowup, $buPicTemplate, $blowupTemplate, $thisaxis, $newAxis );
	
	} elsif ( $querydetail ne '' ) {

		# its an image		
		$htmlReturn = &GetDetail( $querydetail, $detPicTemplate, $buPicTemplate );
	
	} elsif ( $queryglossary ne '' ) {

		# its a glossary popup		
		$htmlReturn = &GetGlossary( $queryglossary, $thisaxis );
	
	} elsif ( $queryhowbig ne '' ) {

		# its a how big is it popup		
		$htmlReturn = &GetHowBigIsIt( $queryhowbig, $thisaxis );
	
	} elsif ( $querywheremade ne '' ) {

		# its a how big is it popup		
		$htmlReturn = &GetWhereIsItMade( $querywheremade, $thisaxis );
	
	} elsif ( $querycatalogue ne '' ) {

		# its a catalogue		
		$htmlReturn = &GetCatalogue( $querycatalogue, $thisaxis, $newAxis, $start, $end, $highlightCatSubSection );
	
	} elsif ( $queryalink ne '' ) {

		# its a link		
		$htmlReturn = &GetArtist( $queryalink, "Artists" ); # force the axis to be 'Artists'
		$htmlReturn = &GetTerm( $queryalink, "Terms" ) if ($htmlReturn eq ''); # force the axis to be 'Terms'
	
	} elsif ( $queryelink ne '' ) {

		# its an encyclopedia		
		$htmlReturn = &GetTerm( $queryelink, "Terms" ); # force the axis to be 'Terms'
	
	} elsif ( $querysearch ne '' ) {

		$htmlReturn = &SendSearchResults( $querysearch, $searchmode, $searchtype, $thisaxis, $newAxis, $start, $end );
	
	} elsif ( $queryreturn ne '' ) {

		$htmlReturn = &ReturnFile( $queryreturn, $thisaxis );
	
	} elsif ( $collection ne '' ) {

		# $htmlReturn = &GenericProblem( "requesting collection:<BR>{request method=$ENV{'REQUEST_METHOD'}}<BR>{query=$query}<BR>{axis=$thisaxis}<BR>{newAxis=$newAxis}<BR>{search=$searchStr}<BR>{image=$image}<BR>{collection=$collection}<BR>{start=$start}<BR>{end=$end}<BR>Date: ".&Date() );
		# its an image		
		$htmlReturn = &RequestCollection( $collection, $axis );
	
	} elsif ( $swfDisplay ne '' ) {

		$htmlReturn = &SwfDisplay( $swfDisplay );
	
	} elsif ( $sendMail ne '' ) {

		$htmlReturn = &SendMail( $sendMail );

	} else {
		#default - added 1/8/00 bhr
		$htmlReturn = &ReturnFile( 'index', $thisaxis );

	}


	local( $sendURLToAFriend ) = &SendURLToAFriend();
	$htmlReturn =~ s/sendURLToAFriend/testing: $sendURLToAFriend/g;

	$htmlReturn =~ s/cgipath/$cgipath/g;
	$htmlReturn =~ s/navImages/$navImages/g;
	$htmlReturn =~ s/mode/$wotmode/g;
	
	$pageTitle	= 'IMAGE On The Web' if ( $pageTitle eq '' );
	$pageTitle	= "SDMA: $pageTitle";
	$htmlReturn =~ s/pageTitle/$pageTitle/g;
	
	
	# return a message
	print &Charsubs( $htmlReturn );
}

exit;


######################### Subroutines listed alphabetically #################################

#UNDER DEVELOPMENT FOR NEXT ROUND - USES NEW FOOTER.HTML
#the hot link to put at the bottom of each page
sub SendURLToAFriend {
	local( $url ) = &GetThisURL();
	local( $sendURLToAFriend ) = "<A HREF=\"cgipath?mode=mode&sendMail=$url\">Click here to send this URL to a friend<\/A>";
	return $sendURLToAFriend;
}
sub SendMail {
	local( $url ) = @_;
	$url =~ s/ZZFS/\./g;
	$url =~ s/ZZQM/\?/g;
	$url =~ s/ZZFM/\&/g;
	$url =~ s/ZZEQ/\=/g;
	local( $template ) = &ReadTemplate( $probTemplate );
	
	local( $temp ) = &ReadTemplate( $header, "", ""  );
	$temp = &DoButtons( '', $temp, @sectionPicker );
	$template =~ s/header/$temp/;
	$temp = &ReadTemplate( $footer, "", ""  );
	$template =~ s/footer/$temp/;
	
	$template =~ s/problem/url=$url/;
	return &PrintHeader() . $template;
	
}
sub GetThisURL {
	local( $url ) = "$cgipath?mode=mode";
	$url .= "&highlightAtoZ=$highlightAtoZ" if ( $highlightAtoZ ne '' );
	$url .= "&highlightCatSubSection=$highlightCatSubSection" if ( $highlightCatSubSection ne '' );
	$url .= "&pageTitle=$pageTitle" if ( $pageTitle ne '' );
	$url .= "&artist=$queryartist" if ( $queryartist ne '' );
	$url .= "&artists=$queryartists" if ( $queryartists ne '' );
	$url .= "&term=$queryterm" if ( $queryterm ne '' );
	$url .= "&terms=$queryterms" if ( $queryterms ne '' );
	$url .= "&subject=$querysubject" if ( $querysubject ne '' );
	$url .= "&subjects=$querysubjects" if ( $querysubjects ne '' );
	$url .= "&catalogue=$querycatalogue" if ( $querycatalogue ne '' );
	$url .= "&catalogue=$querycatalogue" if ( $querycatalogue ne '' );
	$url .= "&painting=$querypainting" if ( $querypainting ne '' );
	$url .= "&blowup=$queryblowup" if ( $queryblowup ne '' );
	$url .= "&detail=$querydetail" if ( $querydetail ne '' );
	$url .= "&glossary=$queryglossary" if ( $queryglossary ne '' );
	$url .= "&howbig=$queryhowbig" if ( $queryhowbig ne '' );
	$url .= "&wheremade=$querywheremade" if ( $querywheremade ne '' );
	$url .= "&alink=$queryalink" if ( $queryalink ne '' );
	$url .= "&elink=$queryelink" if ( $queryelink ne '' );
	$url .= "&axis=$thisaxis" if ( $thisaxis ne '' );
	$url .= "&return=$queryreturn" if ( $queryreturn ne '' );
	$url .= "&script=$queryscript" if ( $queryscript ne '' );
	$url .= "&mode=$wotmode" if ( $wotmode ne '' );
	$url .= "&swfDisplay=$swfDisplay" if ( $swfDisplay ne '' );
	$url .= "&search=$querysearch" if ( $querysearch ne '' );
	$url .= "&searchmode=$searchmode" if ( $searchmode ne '' );
	$url .= "&searchtype=$searchtype" if ( $searchtype ne '' );
	$url .= "&Image=$image" if ( $image ne '' );
	$url .= "&Collection=$collection" if ( $collection ne '' );
	$url .= "&Search=$searchStr" if ( $searchStr ne '' );
	$url .= "&Start=$start" if ( $start ne '' );
	$url .= "&End=$end" if ( $end ne '' );
	$url .= "&SearchMode=$searchMode" if ( $searchMode ne '' );
	$url .= "&onlyOneMatch=$onlyOneMatch" if ( $onlyOneMatch ne '' );
	$url =~ s/\./ZZFS/g;
	$url =~ s/\?/ZZQM/g;
	$url =~ s/\&/ZZFM/g;
	$url =~ s/\=/ZZEQ/g;
	$url =~ s/ /+/g;
	
	return $url;
}
#END OF UNDER DEVELOPMENT


sub ButtonsArray {
	local( $temp ) = &ReadTemplate( $buttonsdb );
	local( @btns ) = split( "\n", $temp );
	local( $c ) = '';
	foreach $btn (@btns ) {
		local( @atm ) = split( "\t", $btn );
		$gBtnArray{$atm[0]} = $atm[1];
		$gBtnArrayAltTags{$atm[0]} = $atm[2];
		$c++; 
	}
	return $c;
}


# Do some substitutions in case we missed any
sub Charsubs {
	local( $t ) = @_;
	$t =~ s//-/g;
	$t =~ s//-/g;
	$t =~ s//&eacute;/g;
	$t =~ s//&Eacute;/g;
	$t =~ s//&aacute;/g;
	$t =~ s//&Aacute;/g;
	$t =~ s//&egrave;/g;
	$t =~ s//&Egrave;/g;
	$t =~ s//&agrave;/g;
	$t =~ s//&Agrave;/g;
	$t =~ s//'/g;
	$t =~ s//'/g;
	$t =~ s//&pound;;/g;
	$t =~ s//&uml;/g;
	$t =~ s//&Uml;/g;
	$t =~ s//&ccedil;/g;
	$t =~ s//.../g;
	$t =~ s//&oacute;/g;
	return $t;
}

# take out the 'funny' chars for search purposes
sub CharSubsNormalize {
	local( $t ) = @_;
	$t =~ s//e/g;
	$t =~ s//E/g;
	$t =~ s//a/g;
	$t =~ s//A/g;
	$t =~ s//e/g;
	$t =~ s//E/g;
	$t =~ s//a/g;
	$t =~ s//A/g;
	$t =~ s//u/g;
	$t =~ s//U/g;
	$t =~ s//c/g;
	$t =~ s//o/g;	
	$t =~ s/&eacute;/e/g;
	$t =~ s/&Eacute;/E/g;
	$t =~ s/&aacute;/a/g;
	$t =~ s/&Aacute;/A/g;
	$t =~ s/&egrave;/e/g;
	$t =~ s/&Egrave;/E/g;
	$t =~ s/&agrave;/a/g;
	$t =~ s/&Agrave;/A/g;
	$t =~ s/&uml;/u/g;
	$t =~ s/&Uml;/U/g;
	$t =~ s/&ccedil;/c/g;
	$t =~ s/&oacute;/o/g;
	return $t;
}


# CheckAxis
# Checks for a standard axis first then for a dynamic axis
sub CheckAxis {
	local( $id, $wotaxis ) = @_;
	local( $thisAxis ) = '';
	local( $axis ) = '';
	
	if ( $wotaxis ne '' ) {
		$thisAxis = &TranslateCode( $wotaxis, $coldaxes, 0, 0 );
		if ( $thisAxis eq '' ) {
			# return "$wotaxis in $id";
			$axis = &TranslateCode( $wotaxis, $hotaxes, 0, 0 );
			
		}
	}
	# check if there's more than one in the list
	local( @noof ) = split( ',', $axis );
	if ( $#noof > 0 ) {
		return $thisAxis;
	} else {
		return '';
	}
}


# CullAxes
# To handle the axes we have a file that axes are written to when a selection or search is made
# An axis consists of a label (the time in seconds plus a character) then a comma separated list of ids.
# There are several protected axes that have names not numbers (AllArtists, AllMuseums). The axis label
# is used to purge the axis file by deleting old axes. Axes last 24 hours.
sub CullAxes {
	# open the db and read it all in
	open( AXESREF, $hotaxes );
	local( $t ) = '';
	local( @temp) = '';
	while(<AXESREF>){
		$t .= $_ . '';
	}
	close(AXESREF);
	chop( $t );
	# make an array
	@t = split( '', $t );
	$tot = $#t;
	open( AXESREF, ">$hotaxes" );
	for (0 .. $tot) {
		@temp = split( "\t", $t[$_] );
		#chop( $temp[0] );
		if ( $temp[0] > (time() - $keepAxes) ) {
			printf AXESREF "$t[$_]";
		}
	}
	close( AXESREF );
}


# return a date - empty will give today's date
sub Date {
	local( $when, $long ) = @_;
	$when = time() if ( $when eq '' );
	local($sc, $mn, $hr, $dy, $mo, $yr, $wd, $yd, $is) = gmtime( $when );
	local( @days)  = ('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');
	local( @months ) = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec',);
	$yr += 1900;
	$mo++;
	if ( $long eq 'long' ){
		return "$dy-$months[$mo-1]-$yr";
	} else {
		return "$dy-$months[$mo-1]-$yr";
	}
}


sub DisplayDate {
	local( $start, $end, $when ) = @_;
	local( $today ) = time();
	if ( $when ne '' ) {
		if ( $start < $today ) {
			return 'started ' . &Date( $start, 'long' );
		} else {
			return 'starts ' . &Date( $start, 'long' );
		}
	} elsif ( $start eq '' || $start < $today ) {
		$start = "now until ";
	} elsif ( $start >= $today ) {
		$start = "starts " . &Date( $start, 'long' ) . " until ";
	}
	return $start . &Date( $end, 'long' );
}


sub DoButtons {
	local( $here, $body, @row ) = @_;
	local( $t ) = '';
	foreach $i ( @row ) {
		local( $in ) = "$i".'in';
		local( $out ) = "$i".'out';
		local( $hereOut ) = "$i".'here';
		local( $alt ) = "$i".'AltTag';
		local( $intag ) = "$in";
		local( $outtag ) = "$out";
		local( $altTag ) = "$alt";
		if ( $here eq $i ) {
			#the highlighted button shouldn't be changed by mouse over
			$body =~ s/$intag/$gBtnArray{$hereOut}/g;
			$body =~ s/$outtag/$gBtnArray{$hereOut}/g;
		} else {
			$body =~ s/$intag/$gBtnArray{$in}/g;
			$body =~ s/$outtag/$gBtnArray{$out}/g;
		}
		$body =~ s/$altTag/$gBtnArrayAltTags{$in}/g;
	}
	return $body;
}


# Filter out any non alpha numeric chars
sub FilterAll {
	local( $t ) = @_;
	$t =~ y/ a-zA-Z//cd;
	return $t;
}


# Filter out any non alpha numeric chars except some punctuation
sub Filter {
	local( $t ) = @_;
	#$t =~ y/ 0-9a-zA-Z.,;:()@!?'""~-$%\///cd;
	return $t;
}


# Generic function to return something
sub GenericProblem {
	local( $err )		= @_;

	local( $template ) = &ReadTemplate( $probTemplate );
	
	local( $temp ) = &ReadTemplate( $header, "", ""  );
	$temp = &DoButtons( '', $temp, @sectionPicker );
	$template =~ s/header/$temp/;
	$temp = &ReadTemplate( $footer, "", ""  );
	$template =~ s/footer/$temp/;
	
	local( $ret ) = "$ss$fs". "Oops! That link is not yet implemented!<BR> ($err)$se$fe";
	$template =~ s/problem/$ret/;
	return &PrintHeader() . $template;
}


sub GetArtist {
	local( $query, $axis, $newaxis, $s, $e, $highlightAtoZ ) = @_;	
	# match the artist id
	local( $art ) = &GetOneEntry( $query, $artistdb );
	local( $head ) = '';	
	return '' if ( $art eq '' );	
	local( @oneartist ) = split( "\t", $art );	
	local( $code, $indexchar, $sortName, $attrib, $attribUp, $surname, $name, $dates, $sound, $text ) = @oneartist;
	local( $body ) = &ReadTemplate( $artistTemplate, "", ""  );
	local( $foot ) = &ReadTemplate( $footer, "", ""  );
	local( $prev ) = &ReadTemplate( $prevTemplate, "", "" );
	local( $next ) = &ReadTemplate( $nextTemplate, "", "" );
	$body = &PutInHeaderAndRow4( $body, $query, 'Artist Index', 'artist', 'Artists', $highlightAtoZ, $row4artist );
	# substitute some details into the templates
	$body =~ s/footer/$foot/;
	$body =~ s/name/$attrib/;
	$body =~ s/dates/$dates/;
	$text =~ s//<P>/g;
	$text = &ZParseLinks( $text );	
	$body =~ s/text/$text/;
	# go find some picture links
	local( $links ) = &GetList( "$code\t", $linksdb );
	local( @piclinks ) = split( "\n", $links );
	local( $thumb ) = &ReadTemplate( $thumbTemplate, "", ""  );
	local( $axes ) = "";
	local( $c ) = 0;
	# for all the picture links
	for ($[ .. $#piclinks) {
		local( @onework ) = &WorkDetails( $piclinks[$_] );		
		local( @oneimag ) = &ImageDetails( $onework[0] );
		#remember - a work will not appear in the imagedb if it is not to be shown on the web
		#in this case substitute the default image
		local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
		$body =~ s/debug/$oneimag[0],$oneimag[1],$oneimag[2],$oneimag[3],$oneimag[4],$oneimag[5],$oneimag[6]/;
		# substitute the template into the first holder in the html
		$body =~ s/pic/$thumb/;
		$body =~ s/thtitle/$onework[2]/g;
		$body =~ s/altTag/$imageAltTag/g;
		$body =~ s/date/$onework[3]/;
		$body =~ s/name/$onework[5]/;
		local( $th ) = "$thumbs$imageFileName";
		$body =~ s/imag/$th/;
		local( $width ) = &GetPhraseWidth( $oneimag[4] );
		$body =~ s/w/$width/;
		local( $height ) = &GetPhraseHeight( $oneimag[3] );
		$body =~ s/h/$height/;
		$body =~ s/actn/$cgipath?mode=mode&painting=$onework[0]insertAxis/;
		$axes .= "$oneimag[0]," if ($oneimag[0] ne '');
		$c++;
	}	
	# loop up to 10 to empty any remaining tags
	 $body =~ s/pic//g;	 
	# process the navigation
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&artist=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$prev =~ s/hot/$temp/;
		$body =~ s/prev/$prev/;
		$temp = "$cgipath?mode=mode&artist=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$next =~ s/hot/$temp/;
		$body =~ s/next/$next/;
	} else {
		
		$body =~ s/prev//;
		$body =~ s/next//;
	}		
	chop( $axes );
	if ( $c > 1 ) {
		# store the axis
		$body =~ s/insertAxis/&axis=$newaxis/g;
		$error = &WriteFile( "$newaxis\t$axes", "\n", $hotaxes );
	} else {
		$body =~ s/insertAxis//g;
	}
	$pageTitle = $attrib;
	return &PrintHeader() . $body;
}


sub GetCatalogue {
	local( $query, $axis, $newaxis, $s, $e, $highlightCatSubSection ) = @_;
	local( $axes ) = '';
	local( $c ) = 0;
	# match the artist id
	local( $term ) = &GetOneEntry( $query, $cataloguedb );
	local( @oneterm ) = split( "\t", $term );
	local( $code, $indexchar, $sortName, $upTitle, $subTitle, $sound, $text ) = @oneterm;
	# read in the templates
	local( $head ) = &ReadTemplate( $header, $upTitle, ""  );
	$head = &DoButtons( 'catalogue', $head, @sectionPicker );
	local( $row4 ) = &ReadTemplate( $row4cat, "", ""  );
	#makes sub-articles stay highlighted
	$highlightCatSubSection = &GetCatSubSectionName( $upTitle ) if ( $highlightCatSubSection eq '' );
	$row4 = &DoButtons( $highlightCatSubSection, $row4, @catalogueSubSectionPicker );
	local( $body ) = &ReadTemplate( $catTemplate, "", ""  );
	local( $foot ) = &ReadTemplate( $footer, "", ""  );
	# substitute some details into the templates
	$head =~ s/row4/$row4/;
	$body =~ s/header/$head/;
	$body =~ s/footer/$foot/;
	$body =~ s/name/$upTitle/;
	$text =~ s//<P>/g;
	$text = &ZParseLinks( $text );
	$body =~ s/text/$text/;
	# go find some picture links
	local( $links ) = &GetList( "$code\t", $linksdb );
	local( @piclinks ) = split( "\n", $links );
	local( $thumb ) = &ReadTemplate( $thumbTemplate, "", ""  );
	# for all the picture links
	for ($[ .. $#piclinks) {
		local( @onework ) = &WorkDetails( $piclinks[$_] );
		local( @oneimag ) = &ImageDetails( $onework[0] );
		#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
		local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
		# substitute the template into the first holder in the html
		$body =~ s/pic/$thumb/;
		$body =~ s/thtitle/$onework[2]/g;
		$body =~ s/altTag/$imageAltTag/g;
		$body =~ s/date/$onework[3]/;
		$body =~ s/name/$onework[5]/;
		#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
		local( $th ) = "$thumbs$imageFileName";
		$body =~ s/imag/$th/;
		local( $width ) = &GetPhraseWidth( $oneimag[4] );
		$body =~ s/w/$width/;
		local( $height ) = &GetPhraseHeight( $oneimag[3] );
		$body =~ s/h/$height/;
		#actn line apparently lost sometime 19/7 - 31/7; restored 1/8/00 bhr
		$body =~ s/actn/$cgipath?mode=mode&painting=$onework[0]insertAxis/;
		# generate some axes
		$axes .= "$onework[0]," if ($onework[0] ne '');
		$c++;
	}
	# loop up to 10 to empty any remaining tags
	 $body =~ s/pic//g;
	# process the navigation
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&subject=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$prev =~ s/hot/$temp/;
		$body =~ s/prev/$prev/;
		$temp = "$cgipath?mode=mode&subject=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$next =~ s/hot/$temp/;
		$body =~ s/next/$next/;
	} else {
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	chop( $axes );
	if ( $c > 1 ) {
		$body =~ s/insertAxis/&axis=$newaxis/g;
		# store the axis
		$error = &WriteFile( "$newaxis\t$axes", "\n", $hotaxes );
		# &CullAxes();
	} else {
		$body =~ s/insertAxis//g;
	}
	$upTitle = &GetCatSubSectionTitleName( $highlightCatSubSection ) if ( $upTitle eq '' );
	$pageTitle = $upTitle;
	return &PrintHeader() . $body;
}


sub GetCatSubSectionName{
	local( $sectionName ) = @_;
	local( $imageName ) = $catalogueSubSectionGivesImageNames{ $sectionName };
	return $imageName;
}

sub GetCatSubSectionTitleName{
	local( $imageName ) = @_;
	local( %catalogueSubSectionGivesSectionNames ) = reverse %catalogueSubSectionGivesImageNames;
	local( $sectionName ) = $catalogueSubSectionGivesSectionNames{ $imageName };
	return $sectionName;
}


sub GetDailyChoice {
	local( $indexType, $indexDB, $body ) = @_;
	local( @todaysSelectionDetails ) = &GetDailyChoiceInfo( $indexType, $indexDB );
	local( $todaysSelectionTemplate ) = &ReadTemplate( $todaysSelectionTemplateFile, "", ""  );
	$body =~ s/todaysSelection/$todaysSelectionTemplate/;
	$body =~ s/todaysTitle/$todaysSelectionDetails[8]/;
	local( $attrib ) = $todaysSelectionDetails[2] ;
	local( $pictureTitle ) = $todaysSelectionDetails[3] ;
	local( $thumbName ) =  $todaysSelectionDetails[4] ;
	local( $thumbWidth ) = $todaysSelectionDetails[5] ;
	local( $thumbHeight ) =  $todaysSelectionDetails[6] ;
	local( $hotlink ) =  $todaysSelectionDetails[7] ;
	local( $altTag ) =  $todaysSelectionDetails[9] ;
	$body =~ s/attrib/$attrib/;
	$body =~ s/pictureTitle/$pictureTitle/;
	$body =~ s/thumbName/$thumbName/;
	$body =~ s/thumbWidth/$thumbWidth/;
	$body =~ s/thumbHeight/$thumbHeight/;
	$body =~ s/hotlink/$hotlink/;
	$body =~ s/altTag/$altTag/;
	return $body;
}

#if file already exists with todays random selection then return that
#if no file exists then make a random selection and store it in a file
sub GetDailyChoiceInfo {
	local( $indexType, $indexDB ) = @_;
	local( $todaysDate ) = &Date();
	local( $fileName ) = $todaysSelections . $indexType . ".txt";
	local( $noOfPossibles ) = '';
	local( $randomChoiceNumber, $initialRandomTime, $nonZeroRandom ) = '';
	local( @randomChoice ) = '';
	#get the first line of the stored info then close so can be opened again fresh.
	open( RANDOMSTORE, $fileName );
	local( $firstline ) = <RANDOMSTORE>;
	close(RANDOMSTORE);
	#if this is today's choice then use it otherwise choose for today
	if ( $firstline =~/date=$todaysDate/ ){
		#get todays info and return it
		#[0]date [1]code, [2]name, [3]title, [4]pic, [5]width, [6]height, [7]hotlink, [8]todaysTitle, [9]NoteOfRandomNumber/noOfPossibles
		open( RANDOMSTORE, $fileName );
		local( @choice ) = <RANDOMSTORE>; 
		close(RANDOMSTORE);
		return @choice;
	} else {
		#need to replace info with todays Selection info
		#find out how many possible choices there are
		local( $pictureTitle, $thumbName, $thumbWidth, $thumbHeight, $alreadyTried, $altTag) = '';
		#need to keep doing this until find a picture to use NB. some encyclo.db entries for eg. don't have associated pictures
		open( DATASTORE, $indexDB );
			while( <DATASTORE> ){
				$noOfPossibles++;
			}
		close(DATASTORE);
		while( $thumbName eq '' ) {		
			#make a random selection
			($randomChoiceNumber, $initialRandomTime, $nonZeroRandom) = &GetRandomNumber( $noOfPossibles ); 
			$alreadyTried .= "$randomChoiceNumber,";
			#get the info of that selection
			local( $randomChoiceInfo ) = '';
			local( $counter ) ='';
			open( DATASTORE, $indexDB );
				while( <DATASTORE> ){
					$counter++;		#ie. first line of database usually [0] to [x-1] is taken as [1] to [x] instead
					if ( $counter eq $randomChoiceNumber ){
						$randomChoiceInfo = $_;
						close(DATASTORE);
					}
				}
			close(DATASTORE);
			chop( $randomChoiceInfo ); #get rid of newline;
			local( @randomChoiceInfo ) = split( "\t", $randomChoiceInfo );
			$randomChoice[0] = "date=$todaysDate"; #irrelevant but keeps everything the same
			if ( $indexType eq "artist" ) {
				local( $code, $indexchar, $sortName, $attrib, $attribUp, $surname, $name, $dates, $sound, $text ) = @randomChoiceInfo;
				$randomChoice[1] = $code;
				$randomChoice[2] = $attrib;
				$randomChoice[7] = "$cgipath?mode=mode&artist=$code&axis=Artists";
				$randomChoice[8] = "Today's selected artist is:";
			} elsif ( $indexType eq "subject" ) {
				local( $code, $indexchar, $sortName, $upTitle, $subTitle, $displaytitle, $text ) = @randomChoiceInfo;
				$randomChoice[1] = $code;
				$randomChoice[2] = $displaytitle;
				$randomChoice[7] = "$cgipath?mode=mode&subject=$code&axis=Subjects";
				$randomChoice[8] = "Today's selected subject is:";
			} elsif ( $indexType eq "term" ) {	#ie. encyclopedia
				local( $code, $indexchar, $sortName, $upTitle, $subTitle, $attribution, $text ) = @randomChoiceInfo;
				$randomChoice[1] = $code;
				$randomChoice[2] = $upTitle;
				$randomChoice[7] = "$cgipath?mode=mode&term=$code&axis=Terms";
				$randomChoice[8] = "Today's selected term is:";
			} else {
				# assume it is for the first page index.html, show a painting.
				local( $code, $accession, $title, $datettext, $sortdate, $name, $wheremade, $period, $construction, $dimensions, $donorcredit, $department, $maps, $imageid, $height, $width ) = @randomChoiceInfo;
				$randomChoice[1] = $code;
				$randomChoice[2] = $name;
				$randomChoice[7] = "$cgipath?mode=mode&painting=$code";
				$randomChoice[8] = "Today's wonderful thing is:";
				#short cut for the picture link 'cos we have all the info already, just need to check if it is copyright or not
				local( @oneimag ) = &ImageDetails( $code );
				#NB. a work may not appear in the imagedb if it is not to be shown on the web, in this case substitute the default image
				#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
				local( $imageFileName, $imageAltTag, $usingDefault ) = &GetImageOrDefaultInfo( $oneimag[2], $title );
				if ( $usingDefault eq "false" ) {
					$pictureTitle = $title;
					$altTag = $imageAltTag;
					$thumbName = "$thumbs$imageFileName";
					$thumbWidth = &GetPhraseWidth( $oneimag[4] );
					$thumbHeight = &GetPhraseHeight( $oneimag[3] );
				}
			}		
			# go find some picture links except for the above 'painting' already done
			if (indexType ne "painting" ) {
				local( $links ) = &GetList( "$randomChoice[1]\t", $linksdb );
				$debugKeepLinks = $links;
				local( @piclinks ) = split( "\n", $links );
				# check all the picture links until the first useful one
				for ($[ .. $#piclinks) {
					if ( $thumbName eq '' ) {
						local( @onework ) = &WorkDetails( $piclinks[$_] );
						local( @oneimag ) = &ImageDetails( $onework[0] );
						#NB. a work may not appear in the imagedb if it is not to be shown on the web, in this case substitute the default image
						#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
						local( $imageFileName, $imageAltTag, $usingDefault ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
						if ( $usingDefault eq "false" ) {
							$pictureTitle = $onework[2];
							$altTag = $imageAltTag;
							$thumbName = "$thumbs$imageFileName";
							$thumbWidth = &GetPhraseWidth( $oneimag[4] );
							$thumbHeight = &GetPhraseHeight( $oneimag[3] );
						}
					}
				}
			}
		}
		$randomChoice[3] = $pictureTitle;
		$randomChoice[4] = $thumbName;
		$randomChoice[5] = $thumbWidth;
		$randomChoice[6] = $thumbHeight;
		$randomChoice[9] = $altTag;
		$randomChoice[10] = "DEBUG INFO: alreadyTried= $alreadyTried  $randomChoiceNumber / $noOfPossibles , initialRandomTime= $initialRandomTime, nonZeroRandom= $nonZeroRandom";
		$randomChoice[11] = $debugKeepLinks;
		#now store the choice (NB. > = overwrite / >> = append)
		open( RANDOMSTORE, ">$fileName" );
			print RANDOMSTORE "$randomChoice[0]\n$randomChoice[1]\n$randomChoice[2]\n$randomChoice[3]\n$randomChoice[4]\n$randomChoice[5]\n$randomChoice[6]\n$randomChoice[7]\n$randomChoice[8]\n$randomChoice[9]\n$randomChoice[10]\n$randomChoice[11]";
		close(RANDOMSTORE);
		return @randomChoice;
	}
}	


sub GetDetail {
	local( $query, $workTemplate, $pictemplate ) = @_;
	local( $head )  = &GetHeader( '', $query, $row4work, '' );	
	local( $body )	= &ReadTemplate( $workTemplate, "", ""  );
	local( $foot )	= &ReadTemplate( $footer, "", ""  );
	local( $fs ) 	= &ReadTemplate( $pictemplate, "", ""  );
	# substitute some details into the templates
	$body =~ s/pic/$fs/;
	$body =~ s/header/$head/;
	$body =~ s/footer/$foot/;
	$body =~ s/prev//;
	$body =~ s/next//;
	@oneimag = &ImageDetails( $query );
	$body =~ s/imag/$fsdetails$query/;
	local( $width ) = &GetPhraseWidth( $oneimag[4] );
	$body =~ s/w/$width/;
	local( $height ) = &GetPhraseHeight( $oneimag[3] );
	$body =~ s/h/$height/;
	$body =~ s/worktitleAlt/blowup detail/;
	return &PrintHeader() . $body;
}


sub GetGlossary {
	local( $query, $axis ) = @_;
	local( $temp ) = &GetOneEntry( $query, $glossarydb );
	local( @glossary ) = split( "\t", $temp );
	
	local( $template ) = &ReadTemplate( $glossTemplate, $glossary[1], ""  );
	$glossary[4] = &ZParseLinks( $glossary[4], 'blank' );
	
	$template =~ s/glossary/$glossary[4]/;
	$template =~ s//<P>/g;
	return &PrintHeader() . $template;

}


sub GetHeader {
	local( $themeid, $title, $row4, $section ) = @_;
	# read in the files we need
	local( $head ) = &ReadTemplate( $header, '', ''  );
	
	$head = &DoButtons( $section, $head, @sectionPicker );
	
	local( $row4 ) = &ReadTemplate( $row4, '', ''  );
	$head =~ s/row4/$row4/;

	return $head;
}


sub GetHowBigIsIt {
	local( $query, $axis ) = @_;
	local( $temp ) = &GetOneEntry( $query, $worksdb );
	local( @onework ) = split( "\t", $temp );
	local( $template ) = &ReadTemplate( $howbigTemplate, $onework[3], ""  );
	local( $imagename, $imageh, $imagew ) = &GetNameAndDimsHowBig( $query );
	$template =~ s/imagename/$imagename/;
	$template =~ s/manpix/$manpix/;
	$template =~ s/manwidthpix/$manwidthpix/;
	$template =~ s/manheightpix/$manheightpix/;
	$template =~ s/imageh/$imageh/;
	$template =~ s/imagew/$imagew/;
	$template =~ s/debug//;
	$template =~ s//<P>/g;
	return &PrintHeader() . $template;
}


sub GetIndex {
	local( $db, $query, $axis, $newaxis, $s, $e ) = @_;
	local( %wot ) = '';
	if ( $db eq $artistdb ) {
		%wot = ( 'label','Artist Index', 'template',$aIndexTemplate, 'link','artist', 'coldaxis','Artists', 'nom','6', 'id','0', 'row4',$row4picker, '','', '','', '','' );
	} elsif ( $db eq $encyclodb ) {
		%wot = ( 'label','Encyclopedia', 'template',$eIndexTemplate, 'link','term', 'coldaxis','Terms', 'nom','3', 'id','0', 'row4',$row4picker, '','', '','', '','' );
	} elsif ( $db eq $subjectdb ) {
		%wot = ( 'label','Subject Index', 'template',$sIndexTemplate, 'link','subject', 'coldaxis','Subjects', 'nom','3', 'id','0', 'row4',$row4picker, '','', '','', '','' );
	} else {
		%wot = ( 'label','Artist Index', 'template',$aIndexTemplate, 'link','artist', 'coldaxis','Artists', 'nom','6', 'id','0', '','', '','', '','', '','' );
	}
	# match the string <tab>indexchar<tab>
	local( $list ) = &GetList( "\t$query\t", $db );
	# put the return list into an array
	local( @indexes ) = split( "\n", $list );
	# initialise some variables
	local( $axes ) = '';
	local( $c ) = 0;
	# do a sort
	#local( @indexes ) = sort IndexSort @unsortindex;
	# construct the index list
	foreach $index (@indexes) {
		local( @oneindex ) = split( "\t", $index );
		# make sure we match in the 3rd field
		$allindex .= "<LI><A HREF=\"$cgipath?mode=mode&$wot{'link'}=$oneindex[$wot{'id'}]&axis=$wot{'coldaxis'}&highlightAtoZ=$query\">$oneindex[$wot{'nom'}]</A>\n";

		# need to build axis list and store it here
		$axes .= "$oneindex[$wot{'id'}]," if ($oneindex[$wot{'id'}] ne '');
		$c++;
	}	
	# read in thie templates
	local( $head ) = &ReadTemplate( $header, $wot{'label'}, "",  );
	$head = &DoButtons( $wot{'link'}, $head, @sectionPicker );
	local( $pick ) = &ReadTemplate( $wot{'row4'}, $wot{'label'}, ""  );
	$pick =~ s/link/$wot{'link'}s/g;
	$pick =~ s/axis/$wot{'coldaxis'}/g;
	$pick = &DoButtons( $query, $pick, @azPicker );
	local( $body ) = &ReadTemplate( $wot{'template'}, "", ""  );
	local( $foot ) = &ReadTemplate( $footer, "", ""  );
	$body =~ s/listing/$allindex/;
	$body =~ s/header/$head/;
	$body =~ s/row4/$pick/;
	$body =~ s/footer/$foot/;
	$body =~ s/matches/$wot{'label'}: $query/;
	# put in the random daily choice
	$body = &GetDailyChoice( $wot{'link'}, $db, $body );
	# process the navigation
	if ( $axis ne '' ) {
		#$temp = "$cgipath?mode=mode&topic=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		#$body =~ s/prev/$temp/;
		#$temp = "$cgipath?mode=mode&topic=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		#$body =~ s/next/$temp/;
	} else {
		
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	chop( $axes );
	if ( $c > 1 ) {
		# store the axis
		$error = &WriteFile( "$newaxis\t$axes", "\n", $hotaxes );
		# &CullAxes();
	}
	$pageTitle = $wot{'label'};
	return &PrintHeader() . $body;
}


sub GetImageOrDefaultInfo {
	local( $imageFileName, $imageAltTag ) = @_;
	if ( $imageFileName eq '' ) {
		$imageFileName = $defaultImage;
		$imageAltTag = "This image cannot be displayed for copyright reasons";
		$usingDefault = "true";
	} else {
		$imageFileName = "$imageFileName.jpg";
		$usingDefault = "false";
	}
	return ($imageFileName, $imageAltTag, $usingDefault);
}


# Given a code and a db find all matches, anywhere
sub GetList {
	local( $pat, $fname ) = @_;
	local( $t ) = "";
	open( ENTRYREF, $fname );
	while( <ENTRYREF> ){
		if ( /$pat/ ){
			$t .= "$_";
		}
	}
	close(ENTRYREF);
	return $t;
}


#passes back the width/height phrases & the numbers too, (for urls)
sub GetMovieDims {
	local( $movieName ) = @_;
	local( $dims ) = &GetOneEntry( $movieName, $moviesdb );	
	local( @dims ) = split( "\t", $dims );
	local( $w ) = $dims[1];
	local( $h ) = $dims[2];
	local( $width ) = "WIDTH=\"$w\"" if ( $w ne '' );
	local( $height ) = "HEIGHT=\"$h\"" if ( $h ne '' );
	return $width, $height, $w, $h;
}


sub GetMoviePlacerText {
	local( $movieName ) = @_;
	local( $dims ) = &GetOneEntry( $movieName, $moviesdb );	
	local( @dims ) = split( "\t", $dims );
	local( $placerText ) = $dims[3];
	return $placerText;
}


#local( $code, $accession, $title, $datettext, $sortdate, $name, $wheremade, $period, $construction, $dimensions, $donorcredit, $department, $maps, $imageid, $height, $width ) = @onework;
sub GetNameAndDimsWhereMade {
	local( $query ) = @_;
	local( $tempwork ) = &GetOneEntry( $query, $worksdb );
	local( @onework ) = split( "\t", $tempwork );
	
	local( $wheremade ) = $onework[6];
	local( $mapname1, $mapname2 ) = split( ",", $onework[12] );
	$mapname1 =~ s/_//g;
	$mapname2 =~ s/_//g;
	$mapname1 =~ s/\///g;
	$mapname2 =~ s/\///g;
	local( @map1 ) = &MapDetails( $mapname1 );
	local( @map2 ) = &MapDetails( $mapname2 );
	local( @NameAndDims ) = ("$mapsPath$mapname1.jpg","$map1[3]","$map1[4]","$mapsPath$mapname2.jpg","$map2[3]","$map2[4]");
	return @NameAndDims;
}

sub GetNameAndDimsHowBig {
	local( $query ) = @_;
	local( $cdid, $AccNum, $AccID, $jpthH, $jpthW, $fsH, $fsW, $MagH, $MagW ) = &ImageDetails( $query );
	local( $work ) = &GetOneEntry( $query, $worksdb );
	local( @onework ) = split( "\t", $work );
	local( $MetH ) = $onework[14];
	local( $MetW ) = $onework[15];
	local( @NameAndDims ) = '';
	local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $AccID, $onework[2] );
	$NameAndDims[0] = "$fullsizes$imageFileName";
	#scale the object's height with the man in cm
	$NameAndDims[1] = int(($MetH * $manheightpix)/$manheightcm);
	#then work out the relevant width - not from metricW cm as this is not same ratio as fsh/w or inches - but from fsh/w
	#however use MetW/MetH as a last resort if there is not imagedb entry.
	if ( $fsH eq '' ) {
		$NameAndDims[2] = int(($NameAndDims[1] * $MetW)/$MetH);
	} else {
		$NameAndDims[2] = int(($NameAndDims[1] * $fsW)/$fsH);
	}
	return @NameAndDims;
}


# Given a URL and a search for a matching id at the beginning of the line
sub GetOneEntry {
	local( $pat, $fname ) = @_;
	local( $t ) = '';
	open( ENTRYREF, $fname );
	$pat .= "\t";
	while( <ENTRYREF> ){
		if ( /^$pat/ ){
			$t = "$_";
			close(ENTRYREF);
			return $t;
		}
	}
	close(ENTRYREF);
	return $t;
}


#returns the dimension phrases - used to prevent width=0 errors
sub GetPhraseWidth {
	local( $width ) = @_;
	if ( $width eq '' ){
		return '';
	} else {
		return "WIDTH=\"" . $width . "\"";
	}
}	
sub GetPhraseHeight {
	local( $height ) = @_;
	if ( $height eq '' ){
		return '';
	} else {
		return "HEIGHT=\"" . $height . "\"";
	}
}	


sub GetRandomNumber {
#return 92; #for debugging purposes
	local( $maximum ) = @_;   #1-x	see GetDailyChoiceInfo function, first line in db is called [1] not [0]
	local( $random ) = int( time() );
	local( $initialRandomTime) = $random;
	$random =~ s/0//g; #remove the zeros in the number,
	local( $nonZeroRandom) = $random;
	local( $reverseRandom ) = '';
	while ( $random > $maximum ) {
		$reverseRandom = reverse( $random );
		chop( $reverseRandom );
		$random = int( reverse( $reverseRandom ) );
	}
	#if maximum is <9 it is possible that the one digit number produced by above will be bigger than maximum, 
	#therefore it will then be reduced to 0 in the last iteration of the while loop
	#if this happens resort to ordinary random
	if ( $random eq 0) {
		$random = int( rand( $maximum ) ) + 1; #NB. +1 because rand gives 0-(max-1)
		$nonZeroRandom = "Resorted to ordinary random (as maximum < 9, ie. $maximum, and result was bigger then maximum)";
	}
	return ($random, $initialRandomTime, $nonZeroRandom);
}


sub GetScript {
	local( $query, $axis, $newaxis ) = @_;
	local( $head )  = &GetHeader( '', $query, $row4work, '' );	
	local( $body )	= &ReadTemplate( $scriptTemplate, "", ""  );
	local( $detl )  = &ReadTemplate( $detailTemplate, "", "" );
	local( $labl )  = &ReadTemplate( $labelTemplate, "", "" );
	local( $flsh )  = &ReadTemplate( $swfPlacerTemplate, "", "" );
	local( $text )	= &ScriptDetails( $query );
	$body =~ s/header/$head/;
	$body =~ s/footer/$foot/;
	$text = &ZParseLinks( $text );
	# lines start with A-Z, <, square or curly bracket
	local( @fText ) = split( "", $text );
	local( @oneimag, $html, @temp ) = '';
	# '' signifies the cut between 2 columns ie. caption/image OR image/caption
	foreach $line ( @fText ) {
		local( @cells ) = split( "", $line );
		local( @wotcell ) = '';
		$wotcell[0] = $wotcell[1] = '';
		local( $c ) = 0;
		for (1 .. 2) {
			# maximum of two lines
			if ( $cells[$c] =~ '.jpg' ) {
				# its an image
				@insert = split( "", $cells[$c] );
				# '' signifies the cut between caption and image name
				@oneimag = &ImageDetails( $insert[1] );
				$wotcell[$c] = $detl;
				$wotcell[$c] =~ s/filename/$thdetails$insert[1]/;
				#This prevents 'width=0' which causes images not to show with some browsers
				local( $width ) = &GetPhraseWidth( $oneimag[4] );
				$wotcell[$c] =~ s/w/$width/;
				local( $height ) = &GetPhraseHeight( $oneimag[3] );
				$wotcell[$c] =~ s/h/$height/;
				$wotcell[$c] =~ s/label/$insert[0]/;
				local( $passOnTitle ) = $pageTitle;
				$passOnTitle =~ s/ /+/g;
				$wotcell[$c] =~ s/actn/$cgipath?mode=mode&detail=$insert[1]&pageTitle=$passOnTitle/;
			} elsif ( $cells[$c] =~ '.swf' ) {
				@insert = split( "", $cells[$c] );
				#put in a placer to open a new window for the flash movie
				$wotcell[$c] = $flsh;
				local( $placerFilename ) = $movies . $insert[1];
				$placerFilename =~ s/.swf/_placer.jpg/;
				$wotcell[$c] =~ s/placerFilename/$placerFilename/g;
				$wotcell[$c] =~ s/placerW/WIDTH="117"/g;
				$wotcell[$c] =~ s/placerH/HEIGHT="108"/g;
				local( $placerText ) = &GetMoviePlacerText( $insert[1] );
				$wotcell[$c] =~ s/placerText/$placerText/g;
				#$wotcell[$c] =~ s/filename/$movies$insert[1]/g;
				local( $passOnTitle ) = $pageTitle;
				$passOnTitle =~ s/ /+/g;
				$wotcell[$c] =~ s/actn/$cgipath?mode=mode&swfDisplay=$insert[1]&pageTitle=$passOnTitle/;
				#local( $width, $height, $w, $h ) = &GetMovieDims( $insert[1] );
				#pass on the numbers to the url
				#$wotcell[$c] =~ s/w/$w/g;
				#$wotcell[$c] =~ s/h/$h/g;
				#and put in the width=whatever phrases
				#$wotcell[$c] =~ s/wid/$width/g;
				#$wotcell[$c] =~ s/hei/$height/g;
				#$wotcell[$c] =~ s/windowTitle/Feature+Movie/g;
			} else {
				# its a paragraph of text
				$wotcell[$c] = $labl;
				$wotcell[$c] =~ s/text/$cells[$c]/;
			}
			$c++;
		}
		if ( $cells[1] ne '' ) {
			$wotcell[0] =~ s/n/1/;
			$wotcell[1] =~ s/n/1/;
		} else {
			$wotcell[0] =~ s/n/2/;
			$wotcell[1] = '';
		}
		$html .= "<TR>$wotcell[0]\n$wotcell[1]</TR>\n";
	}
	$body =~ s/prev//;
	$body =~ s/next//;
	$body =~ s/text/$html/;
	#$pageTitle is set by URL line from hot link on prev. page ie. set in &GetWork
	return &PrintHeader() . $body;
}


sub GetSubject {
	local( $query, $axis, $newaxis, $s, $e, $highlightAtoZ ) = @_;
	# match the artist id
	local( $term ) = &GetOneEntry( $query, $subjectdb );
	local( @oneterm ) = split( "\t", $term );
	local( $head ) = '';
	local( $code, $indexchar, $sortName, $upTitle, $subTitle, $displaytitle, $text ) = @oneterm;
	local( $body ) = &ReadTemplate( $subjectTemplate, "", ""  );
	local( $foot ) = &ReadTemplate( $footer, "", ""  );
	local( $prev ) = &ReadTemplate( $prevTemplate, "", "" );
	local( $next ) = &ReadTemplate( $nextTemplate, "", "" );
	$body = &PutInHeaderAndRow4( $body, $query, 'Subject Index', 'subject', 'Subjects', $highlightAtoZ, $row4term );
	# substitute some details into the templates
	$body =~ s/footer/$foot/;
	$body =~ s/name/$displaytitle/;
	$body =~ s/dates/$subTitle/;
	$text =~ s//<P>/g;
	$text = &ZParseLinks( $text );
	$body =~ s/text/$text/;
	$body =~ s/row4//; # blank for now
	# go find some picture links
	local( $links ) = &GetList( "$code\t", $linksdb );
	local( @piclinks ) = split( "\n", $links );
	local( $thumb ) = &ReadTemplate( $thumbTemplate, "", ""  );
	local( $axes ) = "";
	local( $c ) = 0;
	# for all the picture links
	for ($[ .. $#piclinks) {
		local( @onework ) = &WorkDetails( $piclinks[$_] );
		local( @oneimag ) = &ImageDetails( $onework[0] );
		#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
		local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
		# substitute the template into the first holder in the html
		$body =~ s/pic/$thumb/;
		$body =~ s/thtitle/$onework[2]/g;
		$body =~ s/altTag/$imageAltTag/g;
		$body =~ s/date/$onework[3]/;
		$body =~ s/name/$onework[5]/;
		local( $th ) = "$thumbs$imageFileName";
		$body =~ s/imag/$th/;
		local( $width ) = &GetPhraseWidth( $oneimag[4] );
		$body =~ s/w/$width/;
		local( $height ) = &GetPhraseHeight( $oneimag[3] );
		$body =~ s/h/$height/;
		$body =~ s/actn/$cgipath?mode=mode&painting=$onework[0]insertAxis/;
		$axes .= "$oneimag[0]," if ($oneimag[0] ne '');
		$c++;
	}
	# loop up to 10 to empty any remaining tags
	 $body =~ s/pic//g;
	# process the navigation
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&subject=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$prev =~ s/hot/$temp/;
		$body =~ s/prev/$prev/;
		$temp = "$cgipath?mode=mode&subject=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$next =~ s/hot/$temp/;
		$body =~ s/next/$next/;
	} else {
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	chop( $axes );
	if ( $c > 1 ) {
		$body =~ s/insertAxis/&axis=$newaxis/g;
		# store the axis
		$error = &WriteFile( "$newaxis\t$axes", "\n", $hotaxes );
		# &CullAxes();
	} else {
		$body =~ s/insertAxis//g;
	}
	$pageTitle = $displaytitle;
	return &PrintHeader() . $body;
}


sub GetTerm {
	local( $query, $axis, $newaxis, $s, $e, $highlightAtoZ ) = @_;
	# match the artist id
	local( $term ) = &GetOneEntry( $query, $encyclodb );
	local( @oneterm ) = split( "\t", $term );
	local( $head ) = '';
	local( $code, $indexchar, $sortName, $upTitle, $subTitle, $attribution, $text ) = @oneterm;
	local( $body ) = &ReadTemplate( $termTemplate, "", ""  );
	local( $foot ) = &ReadTemplate( $footer, "", ""  );
	local( $prev ) = &ReadTemplate( $prevTemplate, "", "" );
	local( $next ) = &ReadTemplate( $nextTemplate, "", "" );
	$body = &PutInHeaderAndRow4( $body, $query, 'Encyclopedia', 'term', 'Terms', $highlightAtoZ, $row4term );
	# substitute some details into the templates
	$body =~ s/footer/$foot/;
	$body =~ s/name/$upTitle/;
	$body =~ s/dates/$subTitle/;
	$text =~ s//<P>/g;
	$text = &ZParseLinks( $text );
	$body =~ s/text/$text/;
	# go find some picture links
	local( $links ) = &GetList( "$code\t", $linksdb );
	local( @piclinks ) = split( "\n", $links );
	local( $thumb ) = &ReadTemplate( $thumbTemplate, "", ""  );
	local( $axes ) = "";
	local( $c ) = 0;
	# for all the picture links
	for ($[ .. $#piclinks) {
		local( @onework ) = &WorkDetails( $piclinks[$_] );
		local( @oneimag ) = &ImageDetails( $onework[0] );
		#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
		local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
		$body =~ s/debug/$oneimag[0],$oneimag[1],$oneimag[2],$oneimag[3],$oneimag[4],$oneimag[5],$oneimag[6]/;
		# substitute the template into the first holder in the html
		$body =~ s/pic/$thumb/;
		$body =~ s/thtitle/$onework[2]/g;
		$body =~ s/altTag/$imageAltTag/g;
		$body =~ s/date/$onework[3]/;
		$body =~ s/name/$onework[5]/;
		#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
		local( $th ) = "$thumbs$imageFileName";
		$body =~ s/imag/$th/;
		local( $width ) = &GetPhraseWidth( $oneimag[4] );
		$body =~ s/w/$width/;
		local( $height ) = &GetPhraseHeight( $oneimag[3] );
		$body =~ s/h/$height/;
		$body =~ s/actn/$cgipath?mode=mode&painting=$onework[0]insertAxis/;
		$axes .= "$oneimag[0]," if ($oneimag[0] ne '');
		$c++;
	}
	# loop up to 10 to empty any remaining tags
	 $body =~ s/pic//g;
	# process the navigation
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&term=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$prev =~ s/hot/$temp/;
		$body =~ s/prev/$prev/;
		$temp = "$cgipath?mode=mode&term=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$next =~ s/hot/$temp/;
		$body =~ s/next/$next/;
	} else {
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	chop( $axes );
	if ( $c > 1 ) {
		$body =~ s/insertAxis/&axis=$newaxis/g;
		# store the axis
		$error = &WriteFile( "$newaxis\t$axes", "\n", $hotaxes );
		# &CullAxes();
	} else {
		$body =~ s/insertAxis//g;
	}
	$pageTitle = $upTitle;
	return &PrintHeader() . $body;
}


sub GetWhereIsItMade {
	local( $query, $axis ) = @_;
	local( $temp ) = &GetOneEntry( $query, $worksdb );
	local( @onework ) = split( "\t", $temp );
	local( $template ) = &ReadTemplate( $wheremadeTemplate, $onework[3], ""  );
	local( $map1, $map1h, $map1w, $map2, $map2h, $map2w ) = &GetNameAndDimsWhereMade( $query );	
	$template =~ s/map1/$map1/g;
	$template =~ s/map1w/$map1w/g;
	$template =~ s/map1h/$map1h/g;
	$template =~ s/map2/$map2/g;
	$template =~ s/map2w/$map2w/g;
	$template =~ s/map2h/$map2h/g;
	$template =~ s//<P>/g;
	return &PrintHeader() . $template;
}


sub GetWork {
	local( $query, $pictemplate, $workTemplate, $axis, $newaxis ) = @_;	
	# match the artist id
	local( $work ) = &GetOneEntry( $query, $worksdb );
	local( @onework ) = split( "\t", $work );
	local( $code, $accession, $title, $datettext, $sortdate, $name, $wheremade, $period, $construction, $dimensions, $donorcredit, $department, $maps, $imageid, $height, $width ) = @onework;
	local( $head ) = '';
	# read in the templates
	if ( $onlyOneMatch ) {
		$head = &GetHeader( '', $query, '', '' );		
	} else {
		$head = &GetHeader( '', $query, $row4work, '' );	
	}
	local( $body )	= &ReadTemplate( $workTemplate, "", ""  );
	local( $foot )	= &ReadTemplate( $footer, "", ""  );
	local( $fs ) 	= &ReadTemplate( $pictemplate, "", ""  );
	local( $prev )  = &ReadTemplate( $prevTemplate, "", "" );
	local( $next )  = &ReadTemplate( $nextTemplate, "", "" );
	local( $feat )  = &ReadTemplate( $featureTemplate, "", "" );
	# substitute some details into the templates
	$body =~ s/pic/$fs/;
	$body =~ s/header/$head/;
	$body =~ s/footer/$foot/;
	#$body =~ s/row4//; # blank out for the moment
	local( $datettextANDwheremade ) = '';
	if ( $datettext ne '' && $wheremade ne '' ) {
		$datettextANDwheremade = "$datettext, $wheremade"
	} else {
		$datettextANDwheremade = "$datettext$wheremade"
	}
	$body =~ s/accession/$accession/;
	$body =~ s/datettextANDwheremade/$datettextANDwheremade/;
	$body =~ s/sortdate/$sortdate/;
	$body =~ s/name/$name/;
	$body =~ s/period/$period/;
	$body =~ s/construction/$construction/;
	$body =~ s/dimensions/$dimensions/;
	$body =~ s/donorcredit/$donorcredit/;
	$body =~ s/department/$department/;
	#the command to make a how big popup of the right size
	local( $imagename, $imageh, $imagew ) = &GetNameAndDimsHowBig( $code );
	local( $wid ) = int( $imagew + $manwidthpix + $popupborder );
	local( $hei ) = '';
	
	if ($imageh > $manheightpix) {
		$hei = $imageh + $popupborder;
	} else {
		$hei = $manheightpix + $popupborder;
	}
	$body =~ s/howbigisit/<A HREF="javascript:onClick=howbig($code,$wid,$hei)">How big is it?<\/A>/;
	#the command to make a map popup of the right size
	local( $map1, $map1h, $map1w, $map2, $map2h, $map2w ) = &GetNameAndDimsWhereMade( $code );	
	local( $hei ) = int( $map1h + $map2h + $popupborder );
	if ($map1w > $map2w) {
		$wid = $map1w + $popupborder;
	} else {
		$wid = $map2w + $popupborder;
	}
	$body =~ s/wheremade/<A HREF="javascript:onClick=wheremade($code,$wid,$hei)">Where was it made?<\/A>/;
	local( @oneimag ) = &ImageDetails( $onework[0] );
	#put in the title of the work in the list of info
	$body =~ s/worktitle/$onework[2]/g;
	#if there is no imagedb entry for this work or oneimag[2] is empty then use the default.
	local( $imageFileName, $imageAltTag ) = &GetImageOrDefaultInfo( $oneimag[2], $onework[2] );
	$body =~ s/worktitleAlt/$imageAltTag/g;
	local( $fs ) = "$fullsizes$imageFileName";
	$body =~ s/imag/$fs/;
	if ( $query eq $querypainting ) {
		# if its a painting shrink it and make it hot
		#if picture not allowed on web set dimensions of picture to default values and don't make it hot
		if ($oneimag[2] eq '') {
			$oneimag[5] = 340;
			$oneimag[6] = 400;
			$body =~ s/actn//;
		} else {
			$oneimag[5] = int($oneimag[5] / 2);
			$oneimag[6] = int($oneimag[6] / 2);
			$body =~ s/actn/<A HREF=\"$cgipath?mode=mode&blowup=$onework[0]\">/;
		}
	}
	local( $thisWidth ) = &GetPhraseWidth( $oneimag[6] );
	$body =~ s/w/$thisWidth/;
	local( $thisHeight ) = &GetPhraseHeight( $oneimag[5] );
	$body =~ s/h/$thisHeight/;
	# finally get the script
	local( $script ) = &GetOneEntry( $code, $linksdb );
	local( @script ) = split( "\t", $script );
	local( $text ) = &ScriptDetails( $script[1] );
	if ( $text ne '' ) {
		local( $passOnTitle ) = $title;
		$passOnTitle =~ s/ /+/g;
		$feat =~ s/hot/$cgipath?mode=mode&script=$script[1]&pageTitle=$passOnTitle/;
		$body =~ s/feature/$feat/;
	} else {
		$body =~ s/feature//;
	}
	# get the links to other sections
	local( $links ) = &GetList( "\t$code\t", $linksdb );
	local( @links ) = split( "\n", $links );
	local( $linklist ) = '';
	foreach $link (@links) {
		local ( @onelink ) = split( "\t", $link );
		local ( @linkdetails ) = &LinkDetails( $onelink[3] );
		local ( $linkname ) = &LinkName( $onelink[0], $dbs.$linkdetails[2] );
		$linklist .= "<LI><A HREF=\"$cgipath?mode=mode&$linkdetails[3]=$onelink[0]&axis=$linkdetails[4]\">$linkname</A>";
	}
	$body =~ s/links/$linklist/;
	# process the navigation
	if ( $axis ne '' && $query eq $querypainting ) {
		$temp = "$cgipath?mode=mode&painting=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$prev =~ s/hot/$temp/;
		$body =~ s/prev/$prev/;
		$temp = "$cgipath?mode=mode&painting=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$next =~ s/hot/$temp/;
		$body =~ s/next/$next/;
	} else {
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	$pageTitle = $title;
	return &PrintHeader() . $body;
}


sub GoAlongAxis {
	local( $go, $direction, $wotaxis ) = @_;
	if ( $wotaxis ne '' ) {
		$thisAxis = &TranslateCode( $wotaxis, $coldaxes, 1, 1 );
		if ( $thisAxis eq '' ) { # check the dynamic axes
			$thisAxis = &TranslateCode( $wotaxis, $hotaxes, 1, 1 );
		}
		($go = &OnAxis( $go, $thisAxis, $direction )) if ( $thisAxis ne '' );
	}
	return $go;
}


# take a URL and a strapline and make into a href anchor
sub HotRef {
	local( $id, $title, $type, $axisID, $onlyOneMatch ) = @_;
	return "$title" if ( $id eq '' );
	$axisID = "&axis=$axisID" if ( $axisID ne '' );
	$type = "$cgipath?mode=mode&$type=" if ( $type ne '' );
	$id = "$type$id" if ( $id ne '' );
	return "<A HREF=$id$axisID$onlyOneMatch>$title</A>";
}


#local( $cdid, $AccNum, $AccID, $jpthH, $jpthW, $fsH, $fsW, $MagH, $MagW ) = &ImageDetails( $query );
sub ImageDetails {
 	local( $imag ) = @_;
	local( $imag ) = &GetOneEntry( $imag, $imagesdb );
	@imag = split( "\t", $imag );
	return @imag;
}	


# sort routine for the topic lists
sub IndexSort {
	local( @f1 ) = split ( /\t/, $a );
	local( @f2 ) = split ( /\t/ , $b );
	$f1[2] <=> $f2[2];
}


sub LinkDetails {
	local( $link ) = @_;
	local( $details ) = &GetOneEntry( $link, $sectionsdb );
	local( @details ) = split( "\t", $details );
	
	return ( $details[0], $details[1], $details[2], $details[3], $details[4] );
}

sub LinkName {
	local( $id, $db ) = @_;
	local( $temp ) = &GetOneEntry( $id, $db );
	local( @details ) = split( "\t", $temp );
	
	if ( $db =~ 'artist' ) {
		return ( $details[6] );
	} else {
		return ( $details[3] );
	}
}


sub MapDetails {
 	local( $map ) = @_;
	local( $map ) = &GetOneEntry( $map, $mapsdb );
	@map = split( "\t", $map );
	return @map;
}	


# Given a pattern search for it in the title field
# store an axis and id in a file for retrieval later
sub MatchEntries {
	local( $unpat, $fnames, $mode, $type, $axisID, $template, $start, $end, $hot ) = @_;
	local( $c, $field ) = 0;
	local( $oneOnly ) = '';
	local( $ret ) = "";
	local( $top ) = "";
	local( $axes ) = '';
	$unpat = &CharSubsNormalize( $unpat ); #ie. takes out 'funny' chars just in case they are typed in by search user
	@pat = split( ' ', $unpat );
	if ( $start == 0 || $start eq '' ) {
		$start = $c;
		$end = $start + ($DisplayAtATime - 1);
	}
	#check each database in the list of dbs
	@fnames = split( ',', $fnames );
	foreach $fname ( @fnames ) {
		# open the db
		$hot = 'artist' if ( $fname eq $artistdb );
		$hot = 'subject' if ( $fname eq $subjectdb );
		$hot = 'painting' if ( $fname eq $scriptdb );
		$hot = 'term' if ( $fname eq $encyclodb );
		# print &GenericProblem( "{hot=$hot}<BR>{fname=$fname}<BR>{axis=$thisaxis}<BR>{newAxis=$newAxis}<BR>{search=$searchStr}<BR>{image=$image}<BR>{collection=$collection}<BR>{start=$start}<BR>{SearchMode=$searchMode}<BR>{end=$end}<BR>Date: ".&Date() );

		open( FILEREF, $fname ) ;
		while( <FILEREF> ){
			local( $currentDBLine ) = &CharSubsNormalize( $_ ); #ie. takes out 'funny' chars which won't be typed in by search user
			local( $gotIt ) = 0;
			if ( $mode eq 'whole' ) {
				$gotIt++ if ( $currentDBLine =~ /\b$pat[0]\b/i )
			} elsif ( $mode eq 'start' ) {
				$gotIt++ if ( $currentDBLine =~ /\b$pat[0]/i )
			} else {
				$gotIt++ if ( $currentDBLine =~ /$pat[0]/i )
			}
			if ( $gotIt ) {
				# matched the first word somewhere, match any others in the appropriate fields
				$found = 1;
				local( @entryForMoreChecking ) = split( "\t", $currentDBLine );
				local( @entry ) = split( "\t", $_ );
				
				if ( $fname eq $scriptdb ) {
					# just look in field 6 (title)
					foreach $elem ( @pat ) {
						if ( ($entryForMoreChecking[1] !~ /$elem/i) && ($entryForMoreChecking[2] !~ /$elem/i) ) {
							$found = 0; # ie. if there's more than one word to search MUST match any others in this entry
						}
					}
					$field = 1;
				} else {
					# just look in field 2 and 3 (title and text)
					foreach $elem ( @pat ) {
						if ( ($entryForMoreChecking[4] !~ /$elem/i) && ($entryForMoreChecking[5] !~ /$elem/i) ) {
							$found = 0; # ie. if there's more than one word to search MUST match any others in this entry
						}
					}
					$field = 2;
				}			

				if ( $found == 1 ) {
					# we still have a match
					local( $link ) = ''; local( @link ) = '';
				
					if ( ($c >= $start) && ($c <= $end) ) {
						$link = &MatchOneEntry( $entry[0], $linksdb );
						@link = split( "\t", $link );
						# [4] is the exhibit id, [6] is the title
						$lastLink0 =  $link[0];
						$lastEntryf = $entry[$field];
						$lasthot = $hot;
						$lastaxisid = $axisID;
						$ret .=  &HotRef( $link[0], $entry[$field], $hot, $axisID, '' ) . '<BR>';
					}
					
					# save these ##############
					$c++;
					$oneOnly = $_; #save it
					$axes .= "$link[0]," if ($link[0] ne '');
					# # # # # # # #
				}
			}
		}
		close(FILEREF);
	}
	$start++;
	$end++;
	$end = $c if ( $end > $c );
	if ( $c == 1 ) {
		$template =~ s/found/Found $c match for \"$unpat\"/g;
		$ret =  &HotRef( $lastLink0, $lastEntryf, $lasthot, $lastaxisid, '&onlyOneMatch=true' ) . '<BR>';
	} else {	
		$template =~ s/found/Found $c matches for \"$unpat\" - displaying $start to $end/g;	
	}
	$template =~ s/list/$ret/;
	$start--;
	$end--;
	# is there a next?
	if ( $c > $end + 1) {
		local( $news ) = $start + $DisplayAtATime;
		local( $newe ) = $end + $DisplayAtATime;
		$newe = $c if ( $newe > $c );
		local( $next ) = "<A HREF=\"$cgipath?mode=mode&search=$unpat&searchtype=$type&start=$news&end=$newe\">Next &gt;&gt;&gt;</A>";
		$template =~ s/nextsearch/\| $next/g;
	} else {
		$template =~ s/nextsearch//g;
	}
	# is there a prev?
	if ( $start > 0 ) {
		local( $news ) = $start - $DisplayAtATime;
		local( $newe ) = $news + $DisplayAtATime - 1;
		local( $prev ) = "<A HREF=\"$cgipath?mode=mode&search=$unpat&searchtype=$type&start=$news&end=$newe\">&lt;&lt;&lt; Prev</A>";
		$template =~ s/prevsearch/$prev/g;
	} else {
		$template =~ s/prevsearch//g;
	}

	chop( $axes );
	if ( $c > 1 ) {
		# store the axis
		$error = &WriteFile( "$axisID\t$axes", "\n", $hotaxes );
		&CullAxes();
		return $template;
	} elsif ( $c == 1 ) {
		return $template;
	} else {
		return '';
	}
}


# Given a code and a db find anywhere
sub MatchOneEntry {
	local( $pat, $fname ) = @_;
	local( $t ) = "";
	open( ENTRYREF, $fname );
	while( <ENTRYREF> ){
		if ( /$pat/ ){
			$t = "$_";
			close(ENTRYREF);
			return $t;
		}
	}
	close(ENTRYREF);
	return $t;
}


sub NewHotRef {
	local( $id, $title, $type, $axisID ) = @_;
	return "$title" if ( $id eq '' );
	$axisID = "&axis=$axisID" if ( $axisID ne '' );
	$type = "$cgipath?mode=mode&$type=" if ( $type ne '' );
	$id = "$type$id" if ( $id ne '' );
	return "$id$axisID";
}


sub OnAxis {
	local( $current, $oneAxis, $offset ) = @_;

	@oneAxis = split( ',', $oneAxis );
	local( $where ) = '';
	for ($[ .. $#oneAxis) {
		$where = $_;
		last if ( $oneAxis[$_] eq $current );
	}
	return $current if ( $where eq '' );
	
	if (( $where == $[ ) && ( $offset == -1 )) {
		#matched first and want to go previous - so loop to end
		return $oneAxis[$#oneAxis];
	} elsif (( $where == $#oneAxis ) && ( $offset == 1 )) {
		#matched last and want to go next - so loop to start
		return $oneAxis[$[];
	} else {
		return $oneAxis[$where + $offset];
	}
}


# Returns the magic line which tells WWW that we're an HTML document
sub PrintHeader {
	return $contentType;
}


#adds in a-z pickers	
#called from GetArtist etc
#uses $highlightAtoZ to remember which letter of A-Z pickers needs to be highlighted &
#$row4 to also put in other buttons such as next and prev
sub PutInHeaderAndRow4 {
	local( $body, $query, $label, $link, $coldAxis, $highlightAtoZ, $row4 ) = @_;

	local( $head ) = &ReadTemplate( $header, $label, "",  );
	$head = &DoButtons( $link, $head, @sectionPicker );
	
	local( $pick ) = &ReadTemplate( $row4picker, $label, ""  );
	local( $pluralLink ) = $link . "s";
	$pick =~ s/link/$pluralLink/g;
	$pick =~ s/axis/$coldAxis/g;
	$pick = &DoButtons( $highlightAtoZ, $pick, @azPicker );

	if ( $onlyOneMatch ) {
		$pick = $pick
	} else {
		local( $row4Extra ) = &ReadTemplate( $row4, '', ''  );
		$pick = $pick . $row4Extra;
	}

	# substitute some details into the templates
	$body =~ s/header/$head/;
	$body =~ s/row4/$pick/;
	
	return $body;
}


# Read in a template file
sub ReadTemplate {
	local( $fName, $title, $meta ) = @_;
	open( TEMPREF, $fName );
	local( $t ) = '';
	while(<TEMPREF>){
		$t .= $_;
	}
	close(TEMPREF);
	# get rid of any html tags
	$title =~ s/<[a-zA-Z]*>|<\/[a-zA-Z]*>//g;
	$t =~ s/title/$title/ig;
	$t =~ s/meta/$meta/i;
	return $t;
}


sub ReturnFile {
	local( $query, $axis ) = @_;
	local( $body ) = &ReadTemplate( $docs . $query . $htmlextn, $query, ""  );
	local( $head ) = '';	
	if ( $query eq 'catalogue' ) {
		$head = &GetHeader( '', $query, $row4cat, 'catalogue' );
		$head = &DoButtons( 'catalogue', $head, @sectionPicker );
		#Puts in images for sub-articles
		$head = &DoButtons( '', $head, @catalogueSubSectionPicker );
	} elsif ( $query eq 'search' ) {
		$head = &GetHeader( '', $query, $row4search, 'search' );	
		local( $searchChoice ) = &ReadTemplate( $searchChoice, '', ""  );
		$body =~ s/search/$searchChoice/;
	} else {	
		$head = &GetHeader( '', $query,'' ,'' );	
	}	
	# put in the random daily choice if nec. ie. used with index.html
	$body = &GetDailyChoice( "painting", $worksdb, $body ) if ( $query eq "index" );	
	$body =~ s/header/$head/;
	local( $temp ) =  &ReadTemplate( $footer, "", ""  );	
	$body =~ s/footer/$temp/;	
	$body =~ s/gImageRoot/$imagePath/g;
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&return=" . &GoAlongAxis( $query, -1, $axis ) . "&axis=$axis";
		$body =~ s/prev/$temp/;
		$temp = "$cgipath?mode=mode&return=" . &GoAlongAxis( $query, 1, $axis ) . "&axis=$axis";
		$body =~ s/next/$temp/;
	} else {		
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	$pageTitle = $query;
	return &PrintHeader() . $body;
}


sub ScriptDetails {
 	local( $script ) = @_;
	local( $script ) = &GetOneEntry( $script, $scriptdb );
	local( @script ) = split( "\t", $script );
	return $script[2];
}	


sub SendSearchResults {
	local( $search, $mode, $type, $axis, $newaxis, $start, $end ) = @_;
	local( $body ) = &ReadTemplate( $searchresult );
	local( $btn )  = &ReadTemplate( $searchbtn );
	local( $head ) = &GetHeader( '', "Search >> $search", '', 'search' );	
	$body =~ s/header/$head/;	
	$pageTitle = 'Search Results';
	if ( $axis ne '' ) {
		$temp = "$cgipath?mode=mode&return=" . &GoAlongAxis( 'search', -1, $axis ) . "&axis=$axis";
		$body =~ s/prev/$temp/;
		$temp = "$cgipath?mode=mode&return=" . &GoAlongAxis( 'search', 1, $axis ) . "&axis=$axis";
		$body =~ s/next/$temp/;
	} else {
		
		$body =~ s/prev//;
		$body =~ s/next//;
	}
	local( $temp ) =  &ReadTemplate( $footer, "", ""  );	
	$body =~ s/footer/$temp/;
	
	local( $searchChoice ) = &ReadTemplate( $searchChoice, '', ""  );
	$body =~ s/search/$searchChoice/;
	$body =~ s/gImageRoot/$imagePath/g;
	if ( $search ne '' ) {
		#matchentries is now called with a list of databases (sep. by ' ')
		local( $db ) = $artistdb if ( $type eq 'arti' );
		local( $db ) = $subjectdb if ( $type eq 'subj' );
		local( $db ) = $scriptdb if ( $type eq 'script' );
		local( $db ) = $encyclodb if ( $type eq 'encyclo' );
		local( $db ) = $artistdb . ',' . $subjectdb . ',' . $scriptdb . ',' . $encyclodb if ( $type eq 'every' );
		local( $hot ) = 'artist' if ( $type eq 'arti' );
		local( $hot ) = 'subject' if ( $type eq 'subj' );
		local( $hot ) = 'painting' if ( $type eq 'script' );
		local( $hot ) = 'term' if ( $type eq 'encyclo' );
		local( $axisOrNot ) = '';
		#don't use an axis if search results is a combination of paintings/terms/subjects etc as axis can't cope.
		if ( $type ne 'every' ) {
			$axisOrNot = $newAxis;
		}
		$match = &MatchEntries( $search, $db, $mode, $type, $axisOrNot, $body, $start, $end, $hot );
		if ( $match ne '' ) {
			# the match is a list of entries (contains a blockquote) so return the list as is
			return &PrintHeader() . $match;
		} else {
			# nada
			local( $ret ) = "Couldn\'t find any matches for \"$search\"";
			$body =~ s/found/$ret/;
			$body =~ s/list/$sform/;
			$body =~ s/prevsearch//;
			$body =~ s/nextsearch//;
			return &PrintHeader() . $body;
		}
	} else {
		# no search string
		local( $ret ) = "Nothing to search for!";
		$body =~ s/found/$ret/;
		$body =~ s/list/$sform/;
		$body =~ s/nextsearch//g;
		$body =~ s/prevsearch//g;
		return &PrintHeader() . $body;
	}
}


sub SplitRef {
	local( $term ) = @_;	
	local( @term ) = split( '=', $term );	
	return @term;
}


# Work out a standard axis for a given id 
sub StandardAxis {
	local( $id ) = @_;
	local( %mainAxes ) = ('A','AllArtists','M','AllMuseums','E','AllExhibByName');
	return $mainAxes{chop( $id )};
}


sub SwfDisplay {
	local( $imagesrc ) = @_;
	local( $head )  = &GetHeader( '', $query, '', '' );	
	local( $body )	= &ReadTemplate( $swfMovieTemplate, "", ""  );
	local( $foot )	= &ReadTemplate( $footer, "", ""  );
	# substitute some details into the templates
	$body =~ s/header/$head/;
	$body =~ s/footer/$foot/;
	local( $width, $height, $w, $h ) = &GetMovieDims( $imagesrc );
	$body =~ s/filename/$movies$imagesrc/g;
	$body =~ s/w/$width/g;
	$body =~ s/h/$height/g;
	return &PrintHeader() . $body;
}


sub TitleIt {
	local( $t ) = @_;
	return "<P><STRONG>$t</STRONG>";
}


# Translate the string to a code stored in the codes file, returns the $arg element of the matched line
sub TranslateCode {
	local( $code, $wotfile, $arg, $chop ) = @_;
	
	# open the db
	open( CODEREF, $wotfile );

	$found = '';
	$code .= "\t";

	while(<CODEREF>){
		if ( /^$code/ ){
			@t = split( "\t", $_ );
			$found = $t[$arg];
			last;
		}
	}
	close(CODEREF);
	chop( $found ) if ( $chop );
	return $found;
}


sub UnWebify {
	local( $data ) = @_;
	$data =~ tr/+/ /;
	$data =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
	return $data;
}


# Write out the data (appends to filename in the current directory)
sub WriteFile {
	local( $data, $sep, $filename ) = @_;
	
	unless ( $r = open( WRITEREF, ">>$filename" ) ) {
		return "Couldn't write to $filename";
	}
	$data = &WriteFilter( $data );
	printf WRITEREF $data . $sep;
	close( WRITEREF );
	return "$r";
}


sub WriteFilter {
	local( $data ) = @_;
	$data =~ s/(\r\n?|\n)//g;
	return $data;
}


#local( $code, $accession, $title, $datettext, $sortdate, $name, $wheremade, $period, $construction, $dimensions, $donorcredit, $department, $maps, $imageid, $height, $width ) = @onework;
sub WorkDetails {
 	local( $link ) = @_;
	local( @link ) = split( "\t", $link );
	local( $link ) = &GetOneEntry( $link[1], $worksdb );
	@link = split( "\t", $link );	
	return @link;
}	


# ZParseLinks
sub ZParseLinks {
	local( $text, $blank ) = @_;	
	# do the italics
	$text =~ s//\<I\>/g;
	$text =~ s//\<\/I\>/g;
	# split the refs
	local( @snippets ) = split( $cCurly, $text );
	local( $mode ) = '';
	if ( $wotmode eq 'test' ) { # a frig
		$mode = 'mode=test';
	} else {
		$mode = 'mode=';
	}
	# parse out the jumps - have to split it up first so that the grep works correctly
	# otherwise the grep pattern matches from the start of the first hotlink to the end 
	# of the last one
	for (0 .. $#snippets) {
		if ( $blank eq '' ) {
			$snippets[$_] =~ s/{j([0-9]*)\|(.*)$/<A HREF="$cgipath?$mode&alink=$1">$2<\/A>/g;
			$snippets[$_] =~ s/{g([0-9]*)\|(.*)$/<A HREF="javascript:onClick=glossary($1)">$2<\/A>/g;
			
		} else {
			$snippets[$_] =~ s/{[jg]([0-9]*)\|(.*)$/$2/g;
		}
	}	
	$text = join( '', @snippets );	
	return $text;
}

