#!/usr/bin/perl -w

# foreverstats3.pl
# NDC Code Release 1
#
# Connects to the database holding the statistic data. Builds a
# web page based on a template file.
# This script has limited functionality compared to foreverstats2,
# bus has _much_ cleaner code.
#
#   Copyright (C) 2001 Andreas Ulbrich, Ralf Ertzinger (ndccode@ndc.sh)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

use strict;
use CGI;
use CGI::Debug (report => 'everything', on => 'warnings');
use DBI;

# Define some variables
my $template_path = "templates";
my $scriptpath = "http://www.ndc.sh/cgi-bin/quake/foreverstats3.pl";
my $template_file;
my @main_source;
my %variables;
my @playerdata;

my $CGI_query;

# Info about the script
$variables{parser_selfinfo} = 	"<!--\nThis is the [NDC] foreverstats script, Release 3.0.\n" .
				"Featuring support for selectable viewlimits and player highlighting.\n" .
				"Parsing-Engine: Lilith, Version 1.1.\n" .
				"Output is HTML 4.01 strict compliant.\n\n".
				"Original Release by [NDC]Maria.\n" .
				"Rewrite by [NDC]Sundancer.\n" .
				"Lilith by [NDC]Sundancer.\n" .
				"Source code is available. Contact ndccode\@ndc.sh or see http://www.ndc.sh/ndccode.\n" .
				"//-->";
$variables{scriptpath} = $ENV{REQUEST_URI};

sub parse {

	# This is Lilith. Takes an array on input, and parses it line by line,
	# printing the result to STDOUT.

	# Variables
	my $template_line;
	my @parser_comment;
	my @looparray;
	my $comment;
	my $fullcomment;
	my $replacement;
	my $loop_variable;
	my $in_loop_players = 0;

	LOOP: while ($template_line = shift) {

		if ($template_line =~ /^\s*\<!--loop [\w_]+--\>/) {
			($loop_variable) = ($template_line =~ /<!--loop ([\w_]+)--\>/);
			if ($loop_variable eq "players") {
				$in_loop_players = 1;
			}
			next LOOP;
		}

		if ($template_line =~ /^\s*\<!--endloop [\w_]+--\>/) {
			($loop_variable) = ($template_line =~ /<!--endloop ([\w_]+)--\>/);
			if ($loop_variable eq "players") {
				$in_loop_players = 0;

				# Unroll the loop.
				for (my $i=0;$i<scalar(@playerdata);$i++) {
					$variables{'parser_playerrank'} = $i+1;
					$variables{'parser_playername'} = make_compatible(@{$playerdata[$i]}->[0]);
					$variables{'parser_playerskill'} = @{$playerdata[$i]}->[1];
					$variables{'parser_playerfph'} = @{$playerdata[$i]}->[2];
					$variables{'parser_playermapsplayed'} = @{$playerdata[$i]}->[3];
					$variables{'parser_playermapswon'} = @{$playerdata[$i]}->[4];
					$variables{'parser_playerkills'} = @{$playerdata[$i]}->[5];
					$variables{'parser_playervictims'} = @{$playerdata[$i]}->[6];
					$variables{'parser_playersuicides'} = @{$playerdata[$i]}->[7];
					$variables{'parser_playertime'} = @{$playerdata[$i]}->[8];
					$variables{'parser_playerlastseen'} = @{$playerdata[$i]}->[9];
					parse(@looparray);
				}
			}
			next LOOP;
		}

		# If we are in loopmode, copy lines into an array for later parsing.
		if ($in_loop_players == 1) {
			push @looparray, $template_line;
			next LOOP;
		}

		@parser_comment = ($template_line =~ /\<!--\$([\w_]+)--\>/g);
		foreach $comment ( @parser_comment) {
			if(defined($variables{$comment})) {
				$fullcomment = "\\<!--\\\$" . $comment . "--\\>";
				$replacement = $variables{$comment};
				$template_line =~ s/$fullcomment/$replacement/g;
			}
		}
		print $template_line;
	}
}
		
sub main {

	# Main routine.

	my $template;

	$CGI_query = new CGI;
	$template = ($CGI_query->param('template')?$CGI_query->param('template'):'/foreverstatsstrict.template');
	$template_file = $template_path;
	if ($template =~ /\W/) {
		# template file name contains illegal characters
		$template_file .= "/forerverstatsstrict.template";
	} else {
		$template_file .= $template . ".template";
	}

	if ( ! -e $template_file) {
		$template_file = $template_path . "/foreverstatsstrict.template";
	}

	# Read the contents of the templatefile
	open(TEMPLATE, $template_file) or die "Could not open template file: $!\n";
	@main_source = <TEMPLATE>;
	close(TEMPLATE);
	GetPlayerData();
	print "Content-Type: text/html\n\n";
	parse(@main_source);
}

sub buildsqlquery {

	# Evaluates the parameters and constructs a SQL-query.

	my $operator;
	my $field;
	my $value;
	my $sql_query;

	my %operatormapping = (	'mehrgleich' => '>=',
				'wenigergleich' => '<=',
				'gleich' => '=',
				'mehr' => '>',
				'weniger' => '<' );

	my %fieldmapping = (	'Mapsplayed' => 'fe_MapsPlayed',
				'Mapswon' => 'fe_MapsWon',
				'Kills' => 'fe_Kills',
				'Victims' => 'fe_Victims',
				'Suicides' => 'fe_Suicides' );

	$operator = ($CGI_query->param('sel_operator')?$CGI_query->param('sel_operator'):'mehrgleich');
	$field = ($CGI_query->param('sel_field')?$CGI_query->param('sel_field'):'50');
	$value = ($CGI_query->param('sel_number')?$CGI_query->param('sel_number'):'mehrgleich');

	if(defined($operatormapping{$operator})) {
		$operator = $operatormapping{$operator};
	} else {
		$operator = $operatormapping{'mehrgleich'};
	}

	if(defined($fieldmapping{$field})) {
		$field = $fieldmapping{$field};
	} else {
		$field = $fieldmapping{'Mapsplayed'};
	}

	unless($value=~/\d+/) {
		$value = 50;
	}

	# Build the Query. Hiho.
	$sql_query = 'SELECT nick, fe_skill, fe_fph, fe_mapsplayed, fe_mapswon, fe_kills, fe_victims, fe_suicides, fe_time, date_format(LastSeen, \'%d.%m.%Y\') as date_europe FROM PlayerStats WHERE (' . $field . $operator . $value . ') ORDER BY fe_skill DESC LIMIT 20';

	return $sql_query;
}

sub GetPlayerData {

	# Get the players from the database.

	my $sql_handle;
	my $sql_query;
	my $sql_querystring;
	my @row;
	my $i=0;

	my $sql_user = "";
	my $sql_pass = "";

	$sql_handle = DBI->connect("DBI:mysql:NDC",$sql_user,$sql_pass) or die;
	$sql_querystring = buildsqlquery();
	$sql_query = $sql_handle->prepare($sql_querystring);
	$sql_query->execute or die;

	while (@row = $sql_query->fetchrow_array) {
		$playerdata[$i++] = [ @row ];
	}
	$sql_query->finish;
	$sql_handle->disconnect;
}

sub make_compatible {

	# Takes a string. Converts all suspicious characters into HTML.
	
	my $input;

	$input = shift;
	$input =~ s/&/&amp;/g;
	$input =~ s/\x1c/&middot;/g;
	$input =~ s/</&lt;/g;
	$input =~ s/>/&gt;/g;
	$input =~ s/"/&quot;/g;
	return $input;
}


# This is the main program.

main();
