#!/usr/bin/perl

##########################################################
# Show.pl						 #
# By Mike Shor					 	 #
# Displays working papers in database			 #
# Created 27 July 2004					 #
# Updates:						 #
#					 		 #
#					 		 #
# usage: show.pl?name1=value1&name2=value2&... 		 #
#	where name1,name2,... are field names 		 #
#	name of "search" looks in all fields 		 #
#	a !value means "does not contain" 		 #
#					 		 #
##########################################################


##########################################################
# Requires and constants	                         #
##########################################################

# HTTP header
print "Content-type: text/html\n\n";

# place current directory into perl path
# so that paths are read correctly for requires
 
BEGIN{($curdir=$0)=~s![\\/][^\\/]+$!!;unshift @INC,$curdir;}

require Config;
require Routines;

my $file_name     	= $Config::data_file;
my $HTML_template 	= $Config::results_template;
my $HTML_full_template  = $Config::results_full_template;
my $joinsep       	= $Config::record_separator;
my $ID_field	  	= $Config::auto_id_field_name;

##########################################################
# Process data from web submission             	         #
##########################################################


$qs=$ENV{'QUERY_STRING'};



##########################################################
# Format record separator             	         	 #
##########################################################

my $splitsep = $joinsep;
my $splitsep = "\\".$joinsep if ($joinsep eq '|'or  $joinsep eq ',' or  $joinsep eq '.');


##########################################################
# Read Database			             	         #
##########################################################

my @data = &Routines::read_file($file_name);
chomp $data[0];

# define fields from first line
my @fields= split($splitsep, shift @data);

# check for total number of records
$base_length = @data;
&Routines::error("Database $file_name does not contain any fields") if !@fields;
&Routines::error("Database $file_name does not contain any records") if $base_length<1;





##########################################################
# Search			             	         #
##########################################################

	@conditions=split(/&/,$qs);
	my $counter=0;
	foreach (@conditions){
		($name, $value) = split(/=/, $_);
		if (valid($value)) {
			if($name eq 'full'){
				@data = search($value, $ID_field);
				&display_full;
			}
			if($name eq 'sortBy'){
				$byWhat=$value;
			}
		        elsif($name eq 'search'){@data = search($value);}
			elsif($_=~/([^=<>!]+)!=([^=<>!]+)/){@data = search($value, $1, "!=");}
			elsif($_=~/([^=<>!]+)=([^=<>!]+)/){@data = search($value, $1);}
			$counter++;
		}
	}
	@sorted_recs = sort mySort @data;
	@data = @sorted_recs;
	&display_part;

##########################################################
# Format results		             	         #
##########################################################


sub display_part {

	# Read in HTML template
	(my $head, my $tmp, my $foot) = &Routines::get_html($HTML_template);

	my $result;
	foreach(@data){
		chomp;
		@line = split($splitsep, $_);
		$counter=0; %INSERT=();
		foreach(@fields){$INSERT{$_} = $line[$counter++];}
		$result.=get_record($tmp)
	}

	%INSERT=();
	$INSERT{'#_matches'} = @data;
	$INSERT{'#_total'}   = $base_length;
	$result = "No records found that match your criteria." unless @data;
	print get_record($head), $result, get_record($foot);
	undef $result; undef $head; undef $foot;
	exit;
}


##########################################################
# Format results for a full record             	         #
##########################################################

sub display_full{

	# Read in HTML template
	(my $head, my $tmp, my $foot) = &Routines::get_html($HTML_full_template);
	my $result;
	@line = split($splitsep, $data[0]);
	$counter=0; %INSERT=();
	foreach(@fields){$INSERT{$_} = $line[$counter++];}
	$result.=get_record($tmp);
	$result = "No records found that match your criteria." unless @data;
	print get_record($head), $result, get_record($foot);
	exit;
}


##########################################################
#   Sort by field			 		 #
##########################################################


sub mySort{
   	my @sort_a = split($splitsep,$a);
   	my @sort_b = split($splitsep,$b);

	return 0 unless ($byWhat);
	$byWhat=~s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C",hex($1))/eg;  	
	my $counter=0;
	my $position=-1;
	foreach(@fields){$position=$counter if $_ eq $byWhat; $counter++;}
	return 0 unless ($position>-1);
	$compare = ( lc $sort_b[$position] <=> lc $sort_a[$position] );
        if ( $compare == 0 ) {	
		$compare = ( lc $sort_a[$position] cmp lc $sort_b[$position] );
	}
	return ($compare);
}


##########################################################
#   Seach Subroutine			 		 #
##########################################################

sub search{
	my $word=shift;
	my $field=shift;
	my $action=shift;

        # dewebify by replacing + with space and removing uuencode
        $word=~ tr/+/ /;
        $word=~ s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C",hex($1))/eg;
     
	my %match;
	if($action eq '!='){for(0..@data-1){$match{$_} = 1;}}
	$word =~s/ +/ /g;
	my @new_data=();



	if($field){
		$field=~s/%([\dA-Fa-f][\dA-Fa-f])/pack ("C",hex($1))/eg;  	
	} else {
		$field = 'search';
	}
    my @testfields = split('\.',$field);
    foreach $field (@testfields) {
		my $a=0;
		my $position=-1;
		foreach(@fields){$position=$a if $_ eq $field; $a++;}

	my @keys= split(" ", $word);
	foreach $key (@keys){
		$a=0;
		foreach $record (@data){
			@line = split($splitsep, $record);
			if($field && $position>-1){
				if($action eq '!='){
					$match{$a} = 0 if $line[$position]=~m/\Q$key/i;
				} else {
					$match{$a} = 1 if $line[$position]=~m/\Q$key/i;
				}
			} else {
				foreach(@line) {
					if ($_=~m/\Q$key/i){$match{$a} = 1; last;}
				}
			}
			$a++;
		}
	}
    }
	$a=0; my $b=0;
	foreach(@data){
		$new_data[$b++] = $_ if $match{$a};
		$a++;
	}
	return @new_data;
}



sub get_record{
	my $text = $_[0];
	$text =~ s{<<(.*?)\|(.*?)\|(.*?)>>}{ exists($INSERT{$2}) and valid($INSERT{$2}) ? $1 . $INSERT{$2} . $3 : ""}gsex;
	return $text;
}


sub valid {
	if ((length @_[0]) ==0) {return 0;}
	return 1;
}

