#!/usr/bin/perl
###############################################################################

local $SIG{__DIE__}  = sub { my $msg = shift; print "<H2>ERROR: $msg</H2>\n"; };
#local $SIG{__WARN__} = sub { my $msg = shift; print "<H2>WARNING: $msg</H2>\n"; };

#require "/home/httpd/cgi-bin/renice.pl";
require "/var/www/www.letterville.com/htdocs/cgi/cgi-lib.pl";
require "/var/www/www.letterville.com/htdocs/cgi/dbutil.cgi";
require "/var/www/www.letterville.com/htdocs/cgi/utils.cgi";
require "/var/www/www.letterville.com/htdocs/cgi/lists.cgi";

require "/var/www/www.letterville.com/htdocs/cgi/counter.cgi";
($countAll, $countUniq, $exclAll, $exclUniq) = Count();

@Countries	= LoadFile( 'data/countries.cgi' );		# List of Countries and their Abbreviations
foreach( @Countries )
{
	my( $code, $label ) = split( ':', $_, 2 );
	$Countries{$code} = $label;						# Build a mapping hash from code to label
}

@Cats	= LoadFile( 'data/cats.cgi' );				# List of Categories and their codes
foreach( @Cats )
{
	my( $code, $name ) = split( ':', $_, 2 );
	$Cats{$code} = $name;							# Build a mapping hash from code to name
}

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

my $PageSize = 15;
my $location = 'Location';
my $cats = 'Cats';
$ext = ".sup";

$Title = 'Letterhead Suppliers Around the World';

$ImgBack = "images/logos/head2.gif";

my $Ad = <<EOF;
<P>&nbsp;
<BR>
<A HREF="http://www.letterhead.com/signgold.html"><IMG
	SRC="images/logos/signgoldt.jpg" ALT="SignGold - 27.9KB jpg" WIDTH=468 HEIGHT=87 BORDER=0></A>
<P>&nbsp;
<BR>
EOF
$Ad = "";	# Remove SignGold for now.

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

$query	= $ENV{QUERY_STRING};	# All after the query character - '?'
$this	= $ENV{SCRIPT_NAME};	# Includes path from $droot with leading slash
$www	= $ENV{REMOTE_ADDR};

&ReadParse();	# Get form data into %in hash

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

#$focus = qq( OnLoad="document.Search[1].focus()");

$db = MyOpenDb( $suppliers );
$total = $db->{totrec};			# Use this before $Title in <H1> tag below

print <<EOF;
Content-type: text/html

<HTML>
<HEAD><TITLE>$Title</TITLE></HEAD>
<BODY BACKGROUND="$ImgBack" BGCOLOR="#FFFFFF" $focus>
EOF

$loc = MyOpenDb( $location );
unless( $loc )
{
	print "<H1>Couldn't open Location list</H1>\n";
}

$cat = MyOpenDb( $cats );
unless( $cat )
{
	print "<H1>Couldn't open Categories list</H1>\n";
}

GetInd( 'ID' );	# Main mapping hash as %map

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

if( $in{Shop} )		# Specific shop was selected from the list
{
	DisplayShop();

	print <<EOF;
<HR>
<A HREF="javascript:history.go(-1)" OnMouseOver="window.status='Back to Previous Page'"><FONT FACE=Arial><B>Back to the Previous Page</B></FONT></A>
</CENTER>
EOF
}
else
{
	print <<EOF;
<CENTER>
<TABLE WIDTH=500 CELLPADDING=0 CELLSPACING=4><TR VALIGN=bottom>

<TD><IMG ALIGN=left SRC="images/logos/supply2.gif"
	ALT="Sign Up Supplier" WIDTH=300 HEIGHT=141></TD>

<TD><FONT SIZE=-1>
	Please <B>Select/Type Any/All</B> of the following <B>Criteria</B>
	and select "<B>Search Now...</B>" button.
</TD></TR></TABLE>

<TABLE BORDER=0>
<FORM METHOD=get ACTION="$this" NAME=Search>

<TR><TD><B>Category</B>:</TD><TD COLSPAN=2><SELECT NAME=Cat OnChange="Search.submit()">
EOF
	for( $cat->GoTop(); $cat->ValidPos; $cat->Next() )
	{
		my %Rec = $cat->GetFieldsHash( 'Code', 'Name', 'Parent' );	# Select clause
		$Rec{Name} = "- " . $Rec{Name} if int(unpack("H2",$Rec{Parent})) > 0;
		$Rec{Code} = unpack( "H2", $Rec{Code} );
		my $selected = " SELECTED" if( $in{Cat} && $Rec{Code} eq $in{Cat} );
		print "<OPTION VALUE=$Rec{Code}$selected>$Rec{Name}\n";
	}

	print "	</SELECT></TD></TR>\n";

	if( $in{Country} )
	{
		# Find the full name of the Country

		my $countryName = $in{Country};	# Default to the country code

		for( $loc->GoTop(); $loc->ValidPos; $loc->Next() )
		{
			my %Rec = $loc->GetFieldsHash( 'Type', 'ID', 'Label' );	# Select clause

			if( $Rec{Type} eq 'ALL' &&
				$Rec{ID} eq $in{Country} )	# Where clause
			{
				$countryName = $Rec{Label};
				last;
			}
		}


		print <<EOF;
<INPUT TYPE=hidden NAME=Country VALUE="$in{Country}">
<TR><TD><B>Country:</B></TD>
	<TD><TABLE BORDER=2 CELLSPACING=0 CELLPADDING=0 WIDTH=97% BGCOLOR=#eeeeee><TR>
			<TD>&nbsp;<BIG>$countryName</BIG></TD>
		</TR></TABLE></TD>
	<TD><A HREF="$ENV{SCRIPT_NAME}"><B>Restart Searching - Clear</B></A></TD>
</TR>
EOF
		if( $in{Country} eq 'USA' )
		{
			BuildLocation( 'USA' );
		}
		elsif( $in{Country} eq 'CAN' )
		{
			BuildLocation( 'CAN' );
		}
		elsif( $in{Country} eq 'AUS' )
		{
			BuildLocation( 'AUS' );
		}
		else
		{
			print <<EOF;
<TR><TD><B>Region</B>:</TD><TD><INPUT NAME=State VALUE="$in{State}" SIZE=25></TD>
	<TD><FONT SIZE=-2>Can be Partial or Full Region name</FONT></TD></TR>
EOF
		}
		print <<EOF;
<TR><TD><B>City</B>:</TD><TD><INPUT NAME=City VALUE="$in{City}" SIZE=25></TD>
	<TD><FONT SIZE=-2>Can be Partial or Full City name</FONT></TD></TR>
EOF
	}
	else
	{
		BuildLocation( 'ALL' );
	}

	if( !exists $in{Date} || $in{Date} )	# Default to showing them, Date=0 will turn them off
	{
		$joinedEntries = <<EOF;
	<TD>
		<B>Joined</B>:
	</TD>
	<TD>
		after <INPUT NAME=After VALUE="$in{After}" SIZE=6 MAXLENGTH=8>
		before <INPUT NAME=Before VALUE="$in{Before}" SIZE=6 MAXLENGTH=8>
		<FONT SIZE=-2>YYMMDD</FONT>
EOF
	}
	else
	{
		$joinedEntries = "<TD COLSPAN=2>";
	}


	print <<EOF;

<TR>
	<TD><B>Name</B>:</TD>
	<TD><INPUT NAME=Find VALUE="$in{Find}" SIZE=25>
		<FONT SIZE=-2>Matches Supplier Name, Contact Name, Email (type at least 2 chars)</FONT>
	</TD>
</TR>
<TR>
	$joinedEntries
		&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <INPUT TYPE=submit VALUE="Search Now...">
	</TD>
</TR>

</FORM>
</TABLE>
</CENTER>

<HR>
EOF

	DisplayTable( BuildList() );
}

$loc->Close();
$cat->Close();

DisplayFooter();

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

sub BuildLocation
{
	my $type = shift;
	my $name = ($type eq 'ALL') ? 'Country' : 'State';

	for( $loc->GoTop(); $loc->ValidPos; $loc->Next() )
	{
		my %Rec = $loc->GetFieldsHash( 'Type', 'ID', 'Label' );	# Select clause

		if( $Rec{Type} eq $type )	# Where clause
		{
			if( $Rec{ID} eq '_' )	# Label for the list (first entry for Type)
			{
				print "<TR><TD><B>$Rec{Label}</B>:</TD><TD><SELECT NAME=$name OnChange=\"Search.submit()\">\n";
			}
			else
			{
				my $selected = " SELECTED" if( $in{$name} && $Rec{ID} eq $in{$name} );
				print "<OPTION VALUE=$Rec{ID}$selected>$Rec{Label}\n";
			}
		}
	}
	print "</SELECT></TD></TR>\n";
}

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

sub DisplayFooter
{
	print <<EOF;
<HR>
<CENTER>
<H4>[
	<A HREF="../">Main Page</A> |
	<A HREF="signups.cgi">New Supplier Registration</A> |
	<A HREF="../ubb">Bulletin Board</A> |
	<A HREF="events">Events</A> |
	<A HREF="basics/ads.html">Advertising</A>
]</H4>
$Ad
<HR>
<FONT SIZE=2>
	Copyright&nbsp;&copy;&nbsp;1997 Letterville.com The Letterhead Webiste</p>
		<p>&nbsp;CGI&nbsp;and&nbsp;Database&nbsp;Programming&nbsp;in&nbsp;Perl5
	by&nbsp;Piotr Pytlik;	Copyright&nbsp;&copy;&nbsp;1997,&nbsp;Double P&nbsp;Software
</FONT><BR>
<FONT SIZE=-2>
	
</FONT>

</CENTER>
</BODY>
</HTML>
EOF
}

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

sub BuildList
{
	GetInd( 'Country' );
	my @list;
	if( $in{Country} )	# Start with the list of matches for Country
	{
		@list = @{$Indexes{Country}{$in{Country}}};
	}
	else				# If no country selected then start with ALL entries
	{
		for( keys %{$Indexes{Country}} )
		{
			#@list = ListOr( \@list, \@{$Indexes{Country}{$_}} );
		}
	}

	if( $in{Cat} && $in{Cat} ne "00" )	# But if Searching, narrow it down based on matching names
	{
		my @listCat = ();
		GetInd( 'Cat' );

		foreach $key ( keys %{$Indexes{Cat}} )
		{
			if( $key =~ /$in{Cat}/i )					# Case insensitive pattern search
			{
				@listCat = ListOr( \@listCat, \@{$Indexes{Cat}{$key}} );
			}
		}
		@list = @list > 0 ? ListAnd( \@list, \@listCat ) : @listCat;
	}

	if( $in{State} )	# But if Searching, narrow it down based on matching names
	{
		my @listState = ();
		GetInd( 'State' );

		foreach $key ( keys %{$Indexes{State}} )
		{
			if( $key =~ /$in{State}/i )					# Case insensitive pattern search
			{
				@listState = ListOr( \@listState, \@{$Indexes{State}{$key}} );
			}
		}
		@list = @list > 0 ? ListAnd( \@list, \@listState ) : @listState;
	}

	if( $in{City} )		# Allow to type a query string to match the city
	{
		my @listCity = ();
		GetInd( 'City' );
		foreach $key ( sort keys %{$Indexes{City}} )
		{
			if( $key =~ /$in{City}/i )					# Case insensitive pattern search
			{
				@listCity = ListOr( \@listCity, \@{$Indexes{City}{$key}} );
			}
		}
		@list = @list > 0 ? ListAnd( \@list, \@listCity ) : @listCity;
	}

	if( $in{Find} )		# But if Searching, narrow it down based on matching names
	{
		my @listFound = ();
		foreach $index ( qw( Name FName LName Email ) )	# Search those fields
		{
			GetInd( $index );
			foreach $key ( sort keys %{$Indexes{$index}} )
			{
				foreach $word ( split( ' ', $in{Find} ) )	# Search for each word provided separately
				{
					if( $key =~ /$word/i )					# Case insensitive pattern search
					{
						@listFound = ListOr( \@listFound, \@{$Indexes{$index}{$key}} );
					}
				}
			}
		}
		@list = @list > 0 ? ListAnd( \@list, \@listFound ) : @listFound;
	}

	if( $in{After} || $in{Before} )	# If requested a limit on date range then narrow the list even further
	{
		my @listDate = ();
		GetInd( 'Joined' );

		$in{After}  += 19000000 if $in{After}  && $in{After}  < 1000000;	# Dates in database use full year as 1997
		$in{Before} += 19000000 if $in{Before} && $in{Before} < 1000000;	# And then month and day as two-digit each

		for( keys %{$Indexes{Joined}} )
		{
			next if( $in{After}  && int($_) < int($in{After}) );	# If requested After but date is before then skip
			next if( $in{Before} && int($_) > int($in{Before}) );	# If requested Before but date is after then skip

			@listDate = ListOr( \@listDate, \@{$Indexes{Joined}{$_}} );
		}
		@list = @list > 0 ? ListAnd( \@list, \@listDate ) : @listDate;
	}

	return @list;
}

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

sub DisplayTable
{
	my @list = @_;		# Passes the list of Shop IDs to display

	return unless $db;

	print "<CENTER>\n";

	# Now process some page handling, multiple pages can be navigated to with this technique.

	my $Total = @list;
	my $Pages = int( ($Total + $PageSize - 1) / $PageSize );
	my $Page = $in{Page} || 1;
	$query =~ s/&Page=(\d*|all)//;	# Remove the old page parameter from query so it can be re-added below safely.

	my $from = ($in{Page} - 1) * $PageSize + 1;
	$from = 1 if $from < 1;

	my $to = $from + $PageSize - 1;
	$to = $Total if $to > $Total;

	my $nav;
	if( $Page > 1 )
	{
		$nav .= qq(<A HREF="$this?$query"><B>|< First Page</B></A> | );
		my $prev = $Page - 1;
		$nav .= qq(<A HREF="$this?$query&Page=$prev"><B><< Previous Page</B></A>);
	}
	$nav .= " [Page $Page of $Pages] " if( $Pages > 1 );
	if( $Page < $Pages )
	{
		$nav .= ' | ' if $nav;
		my $next = $Page + 1;
		$nav .= qq(<A HREF="$this?$query&Page=$next"><B>Next Page >></B></A> | );
		$nav .= qq(<A HREF="$this?$query&Page=$Pages"><B>Last Page >|</B></A>);
	}

	$nav .= qq( | <A HREF="$this?$query&Page=all"><B>All Pages</B></A>) if( $Pages > 1 );

	if( $in{Page} =~ /^all$/i )		# Selecting All pages overrides all calculations.
	{
		$nav = "";
		$from = 1;
		$to = $Total;
	}

	if( $Total > 0 )
	{
		print <<EOF;
<FONT SIZE=+1>Found a total of <BIG><B>$Total</B></BIG> matching entries
	<FONT SIZE=-1 FACE=Arial>(<B>$Pages</B> page[s] - <B>$PageSize</B> entries each)</FONT><BR>
	$nav
	<P>
</FONT>
EOF
	}

	my $nr = 0;
	foreach $shop ( @list )		# And now display all matching entries within this page's range.
	{
		next if( ++$nr < $from );
		last if( $nr > $to );

		print <<EOF if( $nr == $from );	# The table header is displayed only once and only if there were entries
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1>
<TR BGCOLOR=#bbbbbb>
	<TH>#</TH>
	<TH>Shop Name</TH>
	<TH>www</TH>
	<TH COLSPAN=2>Contact Name</TH>
	<TH>Phone</TH>
	<TH COLSPAN=2>City / Country</TH>
</TR>
EOF

		$db->GoTo( $map{$shop} );
		my %Rec = $db->GetFieldsHash( qw( URL Company FName LName Phone City Country) );
		my $url = $Rec{'URL'} ? 'web' : '&nbsp;';
		my $shopname = $Rec{Company} || "[$Rec{FName} $Rec{LName}]";

		print <<EOF;
<TR><TH BGCOLOR=#bbbbbb>$nr</TH>
	<TD BGCOLOR=#aabbff><A HREF="$this?Shop=$shop"><B>$shopname</B></A></TD>
	<TD BGCOLOR=#aaffff ALIGN=center><B>$url</B></TD>
	<TD BGCOLOR=#aaffaa><B>$Rec{'FName'}</B></TD>
	<TD BGCOLOR=#aaffaa><B>$Rec{'LName'}</B></TD>
	<TD BGCOLOR=#ffeeaa><B><CODE>$Rec{'Phone'}</CODE></B></TD>
	<TD BGCOLOR=#ffbbaa><B>$Rec{'City'}</B></TD>
	<TD BGCOLOR=#ffbbaa><B>$Rec{'Country'}</B></TD>
</TR>
EOF
	}

	print "</TABLE>\n" if $nr;
	if( $nav )
	{
		print "<HR><H3>$nav</H3>\n";
	}

	print "</CENTER>\n";

	$db->Close();
}

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

sub DisplayShop
{
	unless( exists $map{$in{Shop}} )
	{
		print <<EOF;
<CENTER>
<H1>Sorry, there is no Supplier with ID = $in{Shop}!</H1>
<H2>Please Try Again</H2>
EOF
		return;
	}

	return unless $db;

	$db->GoTo( $map{$in{Shop}} );
	my %Rec = $db->GetFieldsHash();

	my $update = qq(<A HREF="edit.cgi?$in{Shop}">PLEASE UPDATE IT</A>);
	my $email = $Rec{'Email'};
	if( $email && $email ne 'NONE' )
	{
		if( $email =~ s/^!\s*(.*)/$1/ )
		{
			$email = "<A HREF=\"mailto:$1\">$1</A> <BLINK>THIS EMAIL BOUNCED</BLINK> $update";
		}
		else
		{
			$email = "<A HREF=\"mailto:$email\">$email</A>";
		}
	}
	else
	{
		$email = "<BLINK>EMAIL IS MISSING</BLINK> $update";
	}

	my $url = $Rec{'URL'};
	if( $url )
	{
		$url =~ s|^http://||;								# Prevent duplicate http:// prefix on old entries.
		$url = "<A HREF=\"http://$url\"><B>$url</B></A>";
	}

	$Rec{Info} =~ s/\n/<BR>/g;

	my $shopname = $Rec{'Company'} || "[$Rec{FName} $Rec{LName}]";

	print <<EOF;
<CENTER>
<FONT SIZE=+1 FACE=Arial>$Title</FONT>
<TABLE BORDER=2 CELLPADDING=4><TR><TD BGCOLOR=#e2e2ff>
	 <H1><FONT FACE=Arial>$shopname
</TD></TR></TABLE>

<TABLE BORDER=0 WIDTH=80% CELLSPACING=0>
<TR><TH ALIGN=right><B>Contact:</TH>
	<TD><H2>$Rec{'FName'} $Rec{'LName'}</TD>
</TR>
<TR><TH ALIGN=right><B>Email:</TH>
	<TD><H3>$email</TD>
</TR>
EOF
	print <<EOF if $url;
<TR><TH ALIGN=right><B>Web Page:</TH>
	<TD><H3>$url</TD>
</TR>
EOF
	print <<EOF if $Rec{'Phone'};
<TR><TH ALIGN=right><B>Phone:</TH>
	<TD><H3>$Rec{'Phone'}</TD>
</TR>
EOF
	print <<EOF if $Rec{'TollFree'};
<TR><TH ALIGN=right><B>Toll Free Phone:</TH>
	<TD><H3>$Rec{'TollFree'}</TD>
</TR>
EOF
	print <<EOF if $Rec{'Fax'};
<TR><TH ALIGN=right><B>Fax:</TH>
	<TD>$Rec{'Fax'}</TD>
</TR>
EOF
	print <<EOF;
<TR><TD>&nbsp;</TD></TR>

<TR><TH ALIGN=right><B>Address:</TH>
	<TD>$Rec{'Address'}</TD>
</TR>
<TR><TH ALIGN=right><B>City, State, ZIP:</TH>
	<TD>$Rec{'City'},
		$Rec{'State'},
		$Rec{'Zip'}</TD>
</TR>
<TR><TH ALIGN=right><B>Country:</TH>
	<TD><H3>$Countries{$Rec{'Country'}}</TD>
</TR>

<TR><TD>&nbsp;</TD></TR>
EOF

	my $cats;
	my $countcats = 0;
	if( length( $Rec{'Cats'} ) )
	{
		foreach( split( '', $Rec{'Cats'} ) )		# Stored as string of single characters
		{
			$_ = unpack( "H2", $_ );
			next if $_ eq '00';
			$cats .= "$Cats{$_}<BR>\n";
			$countcats += 1;
		}
	}
	if( $countcats > 1 )
	{
		print <<EOF
	<TR><TD COLSPAN=2 ALIGN=center>
		<B>Categories selected for this business:</B><BR>
		$cats
EOF
	}
	elsif( $countcats == 1 )
	{
		print "<TR><TD ALIGN=right><B>Business Category:</B></TD><TD><FONT SIZE=+2 FACE=Arial><B>$cats";
	}
	print "</TD></TR>\n<TR><TD>&nbsp;</TD></TR>\n";

	if( length( $Rec{'Info'} ) > 0 )
	{
		$_ = $Rec{'Info'};
		s#((http|mailto|ftp|news):[^\s\<]+)#<A HREF="$1"><B>$1</B></A>#;
		print <<EOF;

<TR VALIGN=top><TH COLSPAN=2 ALIGN=center><B>Business Description:</TH></TR>
<TR ALIGN=center><TD COLSPAN=2>
	<TABLE BORDER=1 CELLPADDING=4><TR BGCOLOR=#ffffdd><TD>$_</TD></TR></TABLE>
</TD></TR>

EOF
	}

	print <<EOF if $Rec{'Discount'} > 0;

<TR><TD COLSPAN=2 ALIGN=center>
	We offer Letterhead Website Members a
	<BIG><B>$Rec{'Discount'}</B>%</BIG> discount.
</TD></TR>
EOF

	print <<EOF if $Rec{'AdMsg'};
<TR><TD COLSPAN=2 ALIGN=center>
	<TABLE><TR>
		<TD>Ad Message: </TD>
		<TD BGCOLOR=#bbccff><A HREF="sdb.cgi?Shop=$in{Shop}"><FONT SIZE=+1 FACE=Arial><B>$Rec{'AdMsg'}</B></FONT></A></TD>
	</TR></TABLE>
</TD></TR>
EOF

	print <<EOF;
<TR><TD>&nbsp;</TD></TR>

<TR><TD ALIGN=center COLSPAN=2><B>Member Since</B>: $Rec{'Joined'}</TD></TR>
</TABLE>
EOF

	$db->Close();
}

###############################################################################
# Formats the data from any field with the type 'D' = Date

sub TypeMap_D
{
	my( $yyyy, $mm, $dd ) = unpack( 'A4A2A2', $_[0] );
	$mm = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec)[$mm-1];
	return "$dd-$mm-$yyyy";
}

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

sub FieldMap_Phone
{
	my $phone = shift;
return $phone;
	$phone =~ s/\D//g;
	$phone = "519$phone" if( length( $phone ) == 7 );
	return "(".substr($phone,0,3).") ".substr($phone,3,3)."-".substr($phone,6,4) if $phone;
}

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

sub MyOpenDb
{
	my $name = shift;
	my $db = new Pdb( 'data' );

	if( $db->Open( $name ) )
	{
		if( $name eq 'Suppliers' )
		{
			$db->{TypeMap}{D} = "main::TypeMap_D";
			$db->{FieldMap}{Phone} = "main::FieldMap_Phone";
			$db->{FieldMap}{Fax} = "main::FieldMap_Phone";
		}

		return $db;
	}
	else
	{
		return undef;
	}
}

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