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

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

my $PageSize = 15;
my $location = 'Location';

$Title = 'Letterheads Around the World';

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

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

$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

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

if( $ENV{DOCUMENT_NAME} eq 'mdb.html' )
{
	print "<H2>Included from mdb.html with '$query'</H2>\n";
	for( sort keys %ENV )
	{
		print "ENV{$_} => '$ENV{$_}'<BR>\n";
	}
}

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

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

$db = MyOpenDb( $database );
$total = $db->{totrec};
$adrot = `/var/www/www.letterville.com/htdocs/AdRot.cgi mdb`;
$adrot =~ s/^Content-type: text\/html\n//s;

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

<HTML>
<HEAD><TITLE>$Title</TITLE></HEAD>
<BODY BACKGROUND="$ImgBack" BGCOLOR="#FFFFFF" $focus>
<CENTER>
<H1>$total $Title</H1>
$adrot
<HR WIDTH=80%>
</CENTER>
EOF

$loc = MyOpenDb( $location );
unless( $loc )
{
	print "<H1>Couldn't open Location 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
{

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;
<CENTER>
<p align="center">
		<a href="http://www.letterville.com/residents">
		<img border="0" src="../meets/support.gif" width="340" height="50" align="center"></a></p>

Please <B>type name</B> and select "<B>Search Now...</B>" button<BR>
<TABLE BORDER=0>
<FORM METHOD=get ACTION="$this" NAME=Search>

<TR>
	<TD><B>Name</B>:</TD>
	<TD><INPUT NAME=Find VALUE="$in{Find}" SIZE=25>
		<FONT SIZE=-2>Matches Shop Name, First or Last Name</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() );
}

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="signup.cgi">New Member Registration</A> |
	<A HREF="../ubb">Bulletin Board</A> |
	<A HREF="events">Events</A> |
	<A HREF="basics/ads.html">Advertising</A> |
	<A HREF="merchants">Sign Supplies</A>
]</H4>
$Ad
<HR>
<FONT SIZE=2>
	Copyright&nbsp;&copy;&nbsp;1997 Letterville.com The Letterhead Website</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=-1>
	<BLINK><BIG><B></B></BIG></BLINK>
</FONT>

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

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

sub BuildList
{
	GetInd( 'Country' );
	my @list;
	@list = @{$Indexes{Country}{$in{Country}}} if $in{Country};		# Start with the list of matches for Country

	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( length( $in{Find} ) >= 2 )	# But if Searching, narrow it down based on matching names (at least 2 characters)
	{
		my @listFound = ();
		foreach $index ( qw( Name FName LName SName Email ) )	# Search those fields
		{
			GetInd( $index );
			foreach $key ( sort keys %{$Indexes{$index}} )
			{
next if length( $key ) < 2;
				foreach $word ( split( ' ', $in{Find} ) )	# Search for each word provided separately
				{
#	print "Word: '$word' in '$in{Find}' at key '$key' of index '$index'<BR>\n";
next if length( $word ) < 2;
					if( $key =~ /$word/i )					# Case insensitive pattern search
					{
						@listFound = ListOr( \@listFound, \@{$Indexes{$index}{$key}} );
					}
				}
			}
			undef $Indexes{$index};	# This one is not needed anymore, purge the memory cache
		}
		@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 SName WPhone WCity WCountry) );
		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'}$Rec{'SName'}</B></TD>
	<TD BGCOLOR=#aaffaa><B>$Rec{'LName'}</B></TD>
	<TD BGCOLOR=#ffeeaa><B><CODE>$Rec{'WPhone'}</CODE></B></TD>
	<TD BGCOLOR=#ffbbaa><B>$Rec{'WCity'}</B></TD>
	<TD BGCOLOR=#ffbbaa><B>$Rec{'WCountry'}</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 Shop 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;
	$Rec{History} =~ s/\n/<BR>/g;

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

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

<TABLE BORDER=0 WIDTH=80%>
<TR><TH ALIGN=right><B>Contact:</TH>
	<TD><H2>$Rec{'FName'}$Rec{'SName'} $Rec{'LName'}</TD>
</TR>
<TR><TH ALIGN=right><B>Email:</TH>
	<TD><H3>$email</TD>
</TR>
<TR><TH ALIGN=right><B>Web Page:</TH>
	<TD><H3>$url</TD>
</TR>
<TR><TH ALIGN=right><B>Phone:</TH>
	<TD><H3>$Rec{'WPhone'}</TD>
</TR>
<TR><TH ALIGN=right><B>Fax:</TH>
	<TD>$Rec{'FPhone'}</TD>
</TR>

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

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

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

<TR VALIGN=top><TH ALIGN=right><B>Business Description:</TH></TR>
<TR ALIGN=center><TD COLSPAN=2>
	<TABLE BORDER=1 CELLPADDING=4><TR BGCOLOR=#eeeeee><TD>$Rec{'Info'}</TD></TR></TABLE>
</TD></TR>

<TR VALIGN=top><TH ALIGN=right><B>Letterhead History:</TH></TR>
<TR ALIGN=center><TD COLSPAN=2>
	<TABLE BORDER=1 CELLPADDING=4><TR BGCOLOR=#eeeeee><TD>$Rec{'History'}</TD></TR></TABLE>
</TD></TR>

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

<TR><TH ALIGN=right><B>Member Since:</TH>
	<TD>$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 FieldMap_Spouse
{
	my $spouse = shift;
	return " & $spouse" if $spouse;
}

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

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

	if( $db->Open( $name ) )
	{
		if( $name eq 'Members' )
		{
			$db->{TypeMap}{D} = "main::TypeMap_D";
			$db->{FieldMap}{WPhone} = "main::FieldMap_Phone";
			$db->{FieldMap}{HPhone} = "main::FieldMap_Phone";
			$db->{FieldMap}{FPhone} = "main::FieldMap_Phone";
			$db->{FieldMap}{SName} = "main::FieldMap_Spouse";
		}

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

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