#!/usr/bin/perl -I.
# Dreamcast Version
# SONIC ADVENTURE
# MiniGame Rankings
# 


use strict;

use CGI;
use	DC;
use POSIX	'strftime';
use DB;


## Set up variables
use vars	(	'$dc',	# DC object
				'@IN', '@BINDATA', '$PDATA', '$TIME', '$CHAR', '$GAME_ID', '@oldDATA', '$allrank', '$todayrank',
				'$errorURL', '$cgiPath', '$date',
				'$EventID', '$Chara', '$validcountry', '$contest', '$contestdesc',
				'@CharaName', '@TimeTbl',
				'$mode', '$MAX', '$START', '$END', '$UserKey', '$MaxRec', '$nextflag',
			);

$MAX = 10;		# Default number of menu choices

@CharaName = ( 'Sonic', '', 'Tails',
              'Knuckles', '', 'Amy',
              'E-102 Gamma', 'Big' );

# Time Attack Related Data
@TimeTbl = (
		# Character, Screen Shot, Music
		"/images/minigame/sponsor_",		"/images/minigame/sshot_", "file:/sonicadv/highway1.adx"
        );

#...............................................
# Handling time
	$date = strftime("UPLOADED ON %m/%d/%Y, %I:%M %p (%Z)", localtime);

	my $q = new CGI;
	$dc = new DC($q);
	$dc->q->import_names('IN');

	$errorURL = "minigame.html";
	$cgiPath = "/cgi-bin/soa/sonicadv/minigame.cgi";

	$nextflag = 1;

	if($dc->q->param('command') eq "")
	{
		&check_data(1);		# First time through
	} else {
		&check_data(0);
	}
    
	if ($dc->q->param('command') eq 'menu')
	{
		my $cookie = $dc->q->cookie(-name => 'minigame',
									-value   => $dc->q->param('EVENT'),
									-expires => '+1d',
									-path    => '/cgi-bin/soa/sonicadv');

		#print $dc->q->header(-cookie => $cookie). "\n";
		print "Set-Cookie: ".$cookie."\n";	
		print "Cache-control: no-cache\n";

		# Menu template
		if ($contest == 0)
		{
			$dc->output_form("html/minigame_menu.html");
		}
		elsif ($contest == 1)
		{
			$dc->output_form("html/minigame_menu_pending.html");
		}
		elsif ($contest == 2)
		{
			$dc->output_form("html/minigame_menu_winners.html");
		}
		else
		{
			# Set up the error message
			$dc->q->param('Error', "There is no Minigame Contest of this type at this time. ");

			$dc->output_form("html/minigame_menu_closed.html");
		}
	} elsif($dc->q->param('command') eq 'form') {
		# Form output again
		$dc->output_form("html/minigame_form.html");
	} elsif($dc->q->param('command') eq "") {
		# Form output again
		$dc->output_form("html/minigame_form.html");
	} elsif ($dc->q->param('command') eq 'search') {
		&check_search;

		# Form output again
		$dc->output_form("html/minigame_search.html");
	} elsif ($dc->q->param('command') eq 'view') {
		&check_search;

		&output_records(&read_data());
	} elsif ($dc->q->param('command') eq 'verify') {
		# Record data into Database
		my ($dbh, $errN, $errstr, @row, $key);
		
		
		# Read user information from the table
		$key = $dc->make_key($IN::mailid);

		($dbh, $errstr) = DB::openOracleConnection();
		if( !$dbh )
		{
			$dc->error("[minigame] Error connecting to database: $errstr");
		}

		# Update user table information
		($errN, $errstr, @row) = DB::getRow_UserByUK( $dbh, $dc->DBaseTable('USER'), $key );
		if ($errN)
		{
			DB::closeOracleConnection( $dbh );
			$dc->error("[minigame] Fetching user key: $errN .... $errstr", $errorURL);
		}

		($errN, $errstr)       = DB::modifyRow_UserByEmail( $dbh, $dc->DBaseTable('USER'), $IN::mailid, $dc->q->param('NAME'), $dc->q->param('CITY'), $IN::STATE, $IN::COUNTRY, $IN::MAIL, $row[$dc->UserOff('GAME')], $row[$dc->UserOff('BIRTH')], $row[$dc->UserOff('PARENT')], $row[$dc->UserOff('BLOCK')], $row[$dc->UserOff('P1EMAIL')], $row[$dc->UserOff('P2EMAIL')], time, $row[$dc->UserOff('PENDING')], $row[$dc->UserOff('EMBLEMS')], $row[$dc->UserOff('GOLD')], $row[$dc->UserOff('SILVER')], $row[$dc->UserOff('BRONZE')], $row[$dc->UserOff('BLUERIB')] );
		if ($errN)
		{
			DB::closeOracleConnection( $dbh );
			$dc->error("[minigame] Unable to update user info: $errN .... $errstr", $errorURL);
		}

		DB::closeOracleConnection( $dbh );

		# Enter the data into the MiniGame Database
		my $added = new_record($key);

		$allrank = determine_rank($key, $EventID, "ALL");
		$todayrank = determine_rank($key, $EventID, "TODAY");

		# Display Record
		&output_verify($added);
	}

exit(0);

#--------------------------------------------------------
# Data Check
#--------------------------------------------------------
sub check_data
{
	my $first = shift;

	my $MAIL = "";
    my $Warning = "";
	my $Message;
	my ($dbh, $errN, $errstr, @row, $key, $val);

	if($dc->q->param('command') eq "")
	{
		my $level = $dc->q->cookie(-name=>'minigame');
		if ($level eq "")
		{
			$dc->error("Cookie of \"minigame\" has not been set.<BR>Please make sure your Dreamcast clock is correct.", $errorURL);
		}

		$dc->q->param('EVENT', $level);
	}

    $EventID = $dc->q->param('EVENT');
    if($EventID <= 0)
	{
        $dc->error("Invalid event was chosen.", $errorURL);
    }
 
	# Now that the stage has been verified, it now needs to check to see if it live.
	my $adminkey = $dc->get_key($dc->DBaseTable('ADMIN'));

	($dbh, $errstr) = DB::openOracleConnection();
	if( !$dbh )
	{
		$dc->error("[minigame] Error connecting to database: $errstr", $errorURL);
	}

	# Read the current contest controlling entry in the database
	($errN, $errstr, @row) = DB::getRow_RacingByUKandEVENT( $dbh, $dc->DBaseTable('RACING'), $adminkey, $EventID );
	if ($errN)
	{
		DB::closeOracleConnection( $dbh );
		$dc->error("[minigame] Fetching MiniGame Event Info \#$EventID: $errN .... $errstr", $errorURL);
	}
	
	if ($row[$dc->RaceOff('KEY')] eq $adminkey)
	{
		$validcountry = $row[$dc->RaceOff('CHAR')];
		$contest = $row[$dc->RaceOff('TIME')];
		$contestdesc = $row[$dc->RaceOff('COMMENT')];
	}
	else
	{
		$validcountry = -2;
		$contest = -1;
		$contestdesc = "";
	}
	DB::closeOracleConnection( $dbh );

	$dc->q->param('CharFile', $TimeTbl[0].$EventID.".gif");
	$dc->q->param('StageFile', $TimeTbl[1].$EventID.".gif");
	$dc->q->param('AdxFile', $TimeTbl[2]);
	$dc->q->param('EventFile', "sonicadv_$EventID");
	$dc->q->param('Title', $contestdesc);
	$dc->q->param('EventID', $EventID);

	# Read in the message text file
	open(MESSAGE, "../../../minigame/text/$EventID.txt");
	$Message = <MESSAGE>;
	close(MESSAGE);

	$dc->q->autoEscape(0);
	$dc->q->param('Message', $Message);
	$dc->q->autoEscape(1);

	# Make sure that correct country is viewing the contest.
	my $country = $dc->get_browser();
	if ($country == -1)
	{
		# Set up the error message
		$dc->q->param('Error', "Only owners of Sonic Adventure can enter this contest. ");

		# Invalid browser
		$dc->output_form("html/minigame_menu_closed.html");
		exit(0);
	}
	elsif (($validcountry != -1) && ($country != $validcountry))
	{
		if ($country == 0)
		{
			# Set up the error message
			$dc->q->param('Error', "Sorry, United States players cannot participate in this contest.");
		}
		elsif ($country == 1)
		{
			# Set up the error message
			$dc->q->param('Error', "Sorry, European players cannot participate in this contest.");
		}
		elsif ($country == 2)
		{
			# Set up the error message
			$dc->q->param('Error', "Sorry, Japanese players cannot participate in this contest.");
		}

		# Wrong browser for the minigame
		$dc->output_form("html/minigame_menu_closed.html");
		exit(0);
	}

	# Ensure user isn't trying to enter a contest that is closed or pending
	if ($IN::command eq "")
	{
		if (($contest != 0) && ($contest != 2))
		{
			# Menu template
			if ($contest == 1)
			{
				$dc->output_form("html/minigame_menu_pending.html");
				exit(0);
			}
			else
			{
				$dc->output_form("html/minigame_menu_closed.html");
				exit(0);
			}
		}
	}

	if (($IN::command eq "") || ($IN::command eq "form") || ($IN::command eq "verify"))
	{
		# Don't bother processing if just viewing the Minigame Rankings

		# Data Decode
		if( &decode($dc->q->param('chaodata')) != 0) {
			$dc->error("Something wrong with your ranking data.<BR>Please recreate the Ranking upload file and try again.", $errorURL);
		}

		# Hardware ID decode - Not Used
		# &decode_hwid(substr($dc->q->param('dcid'),0,12));

		if ($GAME_ID != $EventID)
		{
			$dc->error("Upload file \"$GAME_ID\" does not match this contest.<BR>Be sure to download the correct event file and try again.", $errorURL);
		}

		# Distinction between Application Types
		$dc->q->param('Time', $dc->calc_int_time($TIME));

		$Chara = $CharaName[$CHAR];
		$dc->q->param('CharaName', $Chara);

		# Key Acquisition
		$MAIL = $dc->q->param('mailid');
		$MAIL =~ y/A-Z/a-z/;
		$dc->q->param('mailid', $MAIL);
		if($MAIL eq "" || $MAIL !~ /[A-Za-z0-9_][-A-Za-z0-9:\._%]*@[-A-Za-z0-9][-A-Za-z0-9\.]*[-A-Za-z0-9]\.[A-Za-z0-9][-A-Za-z0-9\.]*[A-Za-z0-9]/) {
			$dc->error("Something wrong with E-mail address \"$MAIL\".<BR>Please make sure there are no spaces at the end of your E-mail address.", $errorURL);
		}

		if ($first == 1)
		{
			# Read user information from the table
			$key = $dc->get_key($MAIL);

			if ($key ne "")
			{
				($dbh, $errstr) = DB::openOracleConnection();
				if( !$dbh )
				{
					$dc->error("[minigame] Error connecting to database: $errstr", $errorURL);
				}

				($errN, $errstr, @row) = DB::getRow_UserByUK( $dbh, $dc->DBaseTable('USER'), $key );
				if ($errN)
				{
					DB::closeOracleConnection( $dbh );
					$dc->error("[minigame] Fetching user key: $errN .... $errstr", $errorURL);
				}

				DB::closeOracleConnection( $dbh );

				$dc->q->param('NAME', $row[$dc->UserOff('NAME')]);		# Name
				$dc->q->param('CITY', $row[$dc->UserOff('CITY')]);		# City
				$dc->q->param('STATE', $row[$dc->UserOff('STATE')]);	# State
				$dc->q->param('COUNTRY', $row[$dc->UserOff('COUNTRY')]);# Country
				$dc->q->param('MAIL', $row[$dc->UserOff('MFLAG')]);		# Message Flag
			}
			else
			{
				$dc->q->param('NAME', "");		# Name
				$dc->q->param('CITY', "");		# City
				$dc->q->param('STATE', "");		# State
				$dc->q->param('COUNTRY', "");	# Country
			}

			# Set default to No
			if ($dc->q->param('MAIL') ne 'Y')
			{
				$dc->q->param('MAIL', 'N');
			}
		}
		else
		{
			if($dc->q->param('NAME') eq "") {
				$Warning .= "Oops, you forgot to tell us your name!<BR>";
				$dc->q->param('command', 'form');
			}
			$dc->q->param('NAME', $dc->smut_check($dc->q->param('NAME')));

			if($dc->q->param('CITY') eq "") {
				$Warning .= "Your city was not entered.<BR>";
				$dc->q->param('command', 'form');
			}
			$dc->q->param('CITY', $dc->smut_check($IN::CITY));

			if($IN::COUNTRY eq "") {
				$Warning .= "Your country was not entered.<BR>";
				$dc->q->param('command', 'form');
			}

			if (($IN::COUNTRY eq "US") && ($IN::STATE eq "")) {
				$Warning .= "State must be entered if from the Unitied States.<BR>";
				$dc->q->param('command', 'form');
			} elsif (($IN::COUNTRY ne "US") && ($IN::STATE ne "")) {
				$Warning .= "You must not select a state if your country is not the United States.<BR>";
				$dc->q->param('command', 'form');
			}

			if($IN::MAIL ne "Y") {
				$dc->q->param('MAIL','N');
			}
		}

		my $trunc = substr($dc->q->param('COMMENT'),0,127);
		$dc->q->param('COMMENT', $dc->smut_check($trunc));

		# Set up the error message
		$dc->q->param('Warning', $Warning);
	}
}

#--------------------------------------------------------
# Additional New Data
#--------------------------------------------------------
sub new_record {
	my $UserKey = shift;

	# Record data into Database
	my ($dbh, $errN, $errstr, @row, $newentry);
					
	($dbh, $errstr) = DB::openOracleConnection();
	if( !$dbh )
	{
		$dc->error("[minigame] Error connecting to database: $errstr");
	}

	# Retrieve Awards
	($errN, $errstr, @row) = DB::getRow_UserByUK( $dbh, $dc->DBaseTable('USER'), $UserKey );
	if ($errN)
	{
		DB::closeOracleConnection( $dbh );
		$dc->error("[minigame] Fetching user Info: $errN .... $errstr", $errorURL);
	}

	$dc->q->param('EMBLEMS', $row[$dc->UserOff('EMBLEMS')]);
	$dc->q->param('GOLD', $row[$dc->UserOff('GOLD')]);
	$dc->q->param('SILVER', $row[$dc->UserOff('SILVER')]);
	$dc->q->param('BRONZE', $row[$dc->UserOff('BRONZE')]);
	$dc->q->param('BLUERIB', $row[$dc->UserOff('BLUERIB')]);
				
	# Update user table information
	($errN, $errstr, @oldDATA) = DB::getRow_RacingByUKandEVENT( $dbh, $dc->DBaseTable('RACING'), $UserKey, $EventID );
	if ($errN)
	{
		DB::closeOracleConnection( $dbh );
		$dc->error("[minigame] Fetching Minigame Racing info: $errN .... $errstr", $errorURL);
	}
	
	if ($oldDATA[$dc->RaceOff('KEY')] ne $UserKey)
	{
		# New Record so go ahead and store it
		$newentry = 1;

		($errN, $errstr)       = DB::insertRow_Racing( $dbh, $dc->DBaseTable('RACING'), $UserKey, $EventID, 0, $TIME, $CHAR, $dc->q->param('COMMENT'), time );
		if ($errN)
		{
			DB::closeOracleConnection( $dbh );
			$dc->error("[minigame] Unable to create Minigame Racing info: $errN .... $errstr", $errorURL);
		}
	}
	else
	{
		$newentry = 0;

		# First need to see if the current time is better than the one already stored
		if ($oldDATA[$dc->RaceOff('TIME')] > $TIME) {
			# Renew Data for Time Attack
			$newentry = 1;
		}

		# If so then modify existing record
		if ($newentry == 1)
		{
			($errN, $errstr)       = DB::modifyRow_RacingByUKandEVENT( $dbh, $dc->DBaseTable('RACING'), $UserKey, $EventID, 0, $TIME, $CHAR, $dc->q->param('COMMENT'), time );
			if ($errN)
			{
				DB::closeOracleConnection( $dbh );
				$dc->error("[minigame] Unable to modify Minigame Racing info: $errN .... $errstr", $errorURL);
			}
		}
	}

	DB::closeOracleConnection( $dbh );

	return ($newentry);
}

#------------------------------------------------
# Determine output criteria
#------------------------------------------------
sub determine_rank {
	my $UserKey = shift;
	my $EventID = shift;
	my $mode = shift;

	my ($dbh, $sth, $errN, $errstr, @row, $key, $adminkey);
	my $rank = 0;
	my $currank = 0;
	my $searchtime = 0;
					
	# Read user information from the table
	# Administration name uses completely unique and illegal characters so it can't be duplicated
	$adminkey = $dc->get_key($dc->DBaseTable('ADMIN'));
		
	($dbh, $errstr) = DB::openOracleConnection();
	if( !$dbh )
	{
		$dc->error("[admin_wrank] Error connecting to database: $errstr");
	}

	if ($mode eq "TODAY")
	{
		$searchtime = (24*60*60);
	}
	else
	{
		# 5 Years in seconds
		$searchtime = (5*365*24*60*60);
	}

	($errN, $errstr, $sth) = DB::getRow_RacingByEVENT( $dbh, $dc->DBaseTable('RACING'), $EventID, $searchtime  );
	if ($errN)
	{
		DB::closeOracleConnection( $dbh );
		$dc->error("[minigame] Unable to get Minigame Racing Events: $errN .... $errstr", $errorURL);
	}

    while( (@row) = DB::getNextRow_Racing($sth) )
	{
		$key = $row[$dc->RaceOff('KEY')];
		if (($key ne "") && ($key ne $adminkey))
		{
			++$rank;
			if ($key eq $UserKey)
			{
				$currank = $rank;
			}
		}
	}

	DB::closeOracleConnection( $dbh );

	# Side effect is total number of records have been read
	$MaxRec = $rank;

	return ($currank);
}

#------------------------------------------------
# Decode
#------------------------------------------------
sub decode {
    my $srcdata = shift;

	my $errorNum = 0;
	my $i;

    my (@XOR_CODE) = (65,84,69,90);     # 0x5A455441
    my (@PLUS_VAL) = (65,78,65,78);     # 0x4E414E41

    # BASE64Decode
	@BINDATA = ();
    @BINDATA = $dc->decode_base64($srcdata);

    my @tmp_val = (0,0,0,0);
    for(my $i=0;$i<20;$i++) {
        my $tmp_val2 = 0;
        for(my $j=0;$j<4;$j++) {
            $BINDATA[$i*4+$j] ^= ($tmp_val[$j] ^ $XOR_CODE[$j]);
            $tmp_val[$j] = ($tmp_val[$j] + $PLUS_VAL[$j] + $tmp_val2);
            $tmp_val2 = $tmp_val[$j]>>8;
            $tmp_val[$j] &= 255;
        }
    }
 
    my $CRC = ($BINDATA[1]<<8)+$BINDATA[0];
    if($CRC != $dc->crc(\@BINDATA)) {
        $dc->error("CRC Check Error!<BR>Minigame Ranking data is corrupted.", $errorURL);
		$errorNum = 1;
    }

    my $DATA_ID = sprintf "%02X%02X%02X%02X",$BINDATA[7],$BINDATA[6],$BINDATA[5],$BINDATA[4];
    if($DATA_ID ne 'B5D8B4DD') {
        $dc->error("Something wrong with Minigame Ranking data ID.\"$DATA_ID\"", $errorURL);
		$errorNum = 1;
    }

    $PDATA = "";
    for($i=8;$i<68;$i++) {
        $PDATA .= pack("c",$BINDATA[$i]);
    }
    $GAME_ID = ($BINDATA[71]<<24)+($BINDATA[70]<<16)+($BINDATA[69]<<8)+$BINDATA[68];
    $TIME = ($BINDATA[75]<<24)+($BINDATA[74]<<16)+($BINDATA[73]<<8)+$BINDATA[72];
    $CHAR = ($BINDATA[79]<<24)+($BINDATA[78]<<16)+($BINDATA[77]<<8)+$BINDATA[76];

    return($errorNum);
}

#--------------------------------------------------------
# Result Output
#--------------------------------------------------------
sub output_verify {
	my $newRecord = shift;

	my $AdxFile = $dc->q->param('AdxFile');

    print "Content-type: text/html\n\n";
    print <<EOF;

<html>
<head>
<title>
Sonic Adventure Online - Minigame Ranking Validation
</title>
<meta name="x-uirequest" content="urlbaroff">
<script LANGUAGE = "JavaScript">
<!--
        if (document.images) {
            img1on = new Image(); 
            img1on.src = "file:/button_back_on.gif";   
            img1off = new Image(); 
            img1off.src = "file:/button_back.gif"; 
        }

function imgOn(imgName) {
        if (document.images) {
            document[imgName].src = eval(imgName + "on.src");
        }
}

function imgOff(imgName) {
        if (document.images) {
            document[imgName].src = eval(imgName + "off.src");
        }
}

// -->
</script>
<BGSOUND SRC="$AdxFile">
</head>
<body x-marginleft=0 x-margintop=0   background="file:/bg_scroller.gif" bgcolor="#000000" marginheight=0 marginwidth=0 topmargin=0 leftmargin=0>
<center>
<img src="file:/blank_dot.gif" width=1 height=30 border=0 alt=""><br>
<table cellspacing=0 cellpadding=5 border=0 width=590><tr><td align=center valign=top bgcolor="#000033"><table cellspacing=0 cellpadding=0 border=0 width=580><tr><td align=left valign=top bgcolor="#ffffff">

<!-- HEADER IMAGE -->
<!-- choose from below... -->
<!-- header_chao_showoff.gif -->
<!-- header_events.gif -->
<!-- header_world_rankings.gif -->

<img src="/images/header_minigame.gif" width=580 height=150 border=0 alt=""><br>

<!-- END HEADER IMAGE -->

<table cellspacing=0 cellpadding=0 border=0 width=580><tr><td align=left valign=top width="10">
<img src="file:/blank_dot.gif" width=10 height=1 border=0 alt="">
</td>
<td align=left valign=top width=560>

<!-- BEGIN CONTENT HERE -->
EOF
	if ($newRecord == 1)
	{
		print "Congratulations!<p>\n\n";

	}
	else
	{
		my $char = $oldDATA[$dc->RaceOff('CHAR')];
		my $value = $oldDATA[$dc->RaceOff('TIME')];

		print "The new time of ".$dc->q->param('Time')." will not be recorded <BR>\n";
		print "because your previous time was faster.<BR>\n";
		print "Here is your current record:<p>\n";

		$dc->q->param('Time', $dc->calc_int_time($value));

		$dc->q->param('COMMENT', $oldDATA[$dc->RaceOff('COMMENT')]);
	}

	print "You place #$allrank in ".$dc->q->param('Title')." Rankings!<br>\n";
	print "You place #$todayrank in Today's Rankings!<p>\n";

	print <<EOF;
<CENTER>
<TABLE border=0 cellpadding=5 cellspacing=0 width=560 BGCOLOR="#CCCCCC">
<TR>
<TD BGCOLOR="#666666"><FONT COLOR="#ffffff"></FONT></td>
<td align=left valign=top colspan=3 bgcolor="#666666">
<FONT COLOR="#ffffff">
EOF

	print $dc->q->param('Title')."<br>";

	print $dc->q->param('Time')." using ".$dc->q->param('CharaName');

	print <<EOF;
</FONT></TD>
</TR>
<TR><TD valign=top width=60>
EOF

	if ($dc->Flags($IN::COUNTRY) ne "")
	{
		print "<img src=\"/images/flags/".$dc->Flags($IN::COUNTRY)."\" width=40 height=20 border=0>";	
	} else {
		# Draw the generic flag
		print "<img src=\"/images/flags/flag_other.gif\" width=40 height=20 border=0>";
	}

	print "</TD><td align=left valign=middle colspan=2>";
	print $dc->q->param('NAME')."<BR>\n";

	if ($dc->q->param('MAIL') eq "Y")
	{
		print "</TD><TD VALIGN=\"top\" ALIGN=\"right\">".$dc->q->param('mailid')."</TD></TR>\n";
	} else {
		print "</TD><TD VALIGN=\"top\" ALIGN=\"right\">Hidden</TD></TR>\n";
	}

	print "<TR><TD><BR></TD><td align=left valign=top colspan=3>".$dc->q->param('CITY').", ";
	if ($dc->q->param('STATE') ne "") {
		printf "%s, ", $dc->state_name($dc->q->param('STATE'));
	}
	printf "%s\n", $dc->country_name($dc->q->param('COUNTRY'));


	print <<EOF;
</TR>
<TR><TD valign=top width=60 bgcolor="#dddddd">
EOF
	if ($allrank == 1)
	{
		print "<img src=\"/images/wrank/gold_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}
	elsif ($allrank == 2)
	{
		print "<img src=\"/images/wrank/silver_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}
	elsif ($allrank == 3)
	{
		print "<img src=\"/images/wrank/bronze_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}
	elsif ($todayrank == 1)
	{
		print "<img src=\"/images/wrank/flag_1_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}
	elsif ($todayrank == 2)
	{
		print "<img src=\"/images/wrank/flag_2_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}
	elsif ($todayrank == 3)
	{
		print "<img src=\"/images/wrank/flag_3_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
	}


	print "</TD><TD colspan=\"3\" BGCOLOR=\"#DDDDDD\">Awards:<br>\n";
	my $count = 0;
	my $loop;

	if ($dc->q->param('EMBLEMS') == 130)
	{
		# User gets emblem award if has all 130
		print "<img src=\"/images/wrank/emblem_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		++$count;
	}

	for ($loop = 0; $loop < $dc->q->param('GOLD'); ++$loop)
	{
		print "<img src=\"/images/wrank/gold_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		++$count;
		if ($count >= 8)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=5 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $dc->q->param('SILVER'); ++$loop)
	{
		print "<img src=\"/images/wrank/silver_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		++$count;
		if ($count >= 8)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=5 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $dc->q->param('BRONZE'); ++$loop)
	{
		print "<img src=\"/images/wrank/bronze_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		++$count;
		if ($count >= 8)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=5 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $dc->q->param('BLUERIB'); ++$loop)
	{
		print "<img src=\"/images/wrank/ribbon_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		++$count;
		if ($count >= 8)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=5 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	print "<p>\nComments:<BR>";
	print $dc->q->param('COMMENT');

	print <<EOF;
</TD></TR>
</TABLE>
</CENTER>
&nbsp;<BR>
EOF

	print <<EOF;
<!-- END CONTENT HERE -->
&nbsp;<br>
<a href="/minigame.html"  onMouseOver="imgOn('img1')" onMouseOut="imgOff('img1')"><img src="file:/button_back.gif" width=81 height=24 border=0 alt="" name="img1"></a><P>				
</td><td align=left valign=top width="10">
<img src="file:/blank_dot.gif" width=10 height=1 border=0 alt="">
</td>
</tr>
</table>
</tr>
</tr>
</table>
</td>
</tr>
</table>
<br>&nbsp;
</center>
</body>
</html>
EOF

}

######################################################################
# Display contents of World Rankings
######################################################################

#--------------------------------------------------------
# Data Check
#--------------------------------------------------------
sub check_search {
	my ($errN, $errstr, $dbh, $sth, @wrank);
	my ($Assort, $Stage, $Chara, $val);

	$dc->q->param('message', "You can search for rankings here. Search by Email or go through the ranks.  ");

	if($IN::max ne "") {
		$MAX = $IN::max;
		if($MAX<=0) {
			# Set default maximum size
			$MAX=10;
		}
	}
		
	$START=0;
	if($IN::start ne "") {
		$START = ($IN::start - 1);
		if($START<0) {
			$START=0;
		}
	}

	# Save original Maximum Record value
	my $OldMax = $MaxRec;

	# Determine total number of records for All time and Today
	&determine_rank("", $EventID, "ALL");
	$dc->q->param("maxall", $MaxRec);
	&determine_rank("", $EventID, "TODAY");
	$dc->q->param("maxtoday", $MaxRec);

	# Restore original Maximum Records value
	$MaxRec = $OldMax;

	#Initialize base values
	$dc->q->param('max', $MAX);
	$dc->q->param('start', $START + 1);

	if ($IN::mode eq "TODAY") {
		$mode = "TODAY";
	} else {
		$mode = "ALL";
		$dc->q->param('mode', "ALL");
	}
		
	if($IN::mailid ne "") {
		$UserKey = $dc->get_key($IN::mailid);
		if ($UserKey eq "")
		{
			$dc->q->param('message', "<font color=\"#ff0000\">Sorry, no matches were found containing <b>$IN::mailid</b>.</font><p>Please try again. ");
		
			# Terminate the search
			$dc->output_form("html/minigame_search.html");
			undef($UserKey);
			exit(0);
		}
		else
		{
			($dbh, $errstr) = DB::openOracleConnection();
			if( !$dbh )
			{
				$dc->error("[minigame] Error connecting to database: $errstr", $errorURL);
			}

		    ($errN, $errstr, @wrank) = DB::getRow_RacingByUKandEVENT( $dbh, $dc->DBaseTable('RACING'), $UserKey, $EventID );
			if ($errN)
			{
				DB::closeOracleConnection( $dbh );
				$dc->error("[minigame] Fetching user info: $errN .... $errstr", $errorURL);
			}

			DB::closeOracleConnection( $dbh );

			if (($wrank[$dc->RaceOff('KEY')] ne $UserKey))
			{
				$dc->q->param('message', "<font color=\"#ff0000\">Sorry, no matches were found containing <b>$IN::mailid</b>.</font><p>Please try again. ");

				# Terminate the search
				$dc->output_form("html/minigame_search.html");
				undef($UserKey);
				exit(0);
			}
		}
	}
}

#--------------------------------------------------------
# Read Key Data
#--------------------------------------------------------
sub read_data {
	my $key = shift;
	my ($errN, $errstr, $dbh, $sth, @row);

	($dbh, $errstr) = DB::openOracleConnection();
	if( !$dbh )
	{
		$dc->error("[minigame] Error connecting to database: $errstr", $errorURL);
	}

	if($UserKey eq "") {
		# Calculate the maximum number of records
		&determine_rank("", $EventID, $dc->q->param('mode'));

		if($START < $MaxRec) {
			if(($MaxRec-$START)>($MAX)) {
				$END=$START+$MAX;
				$nextflag=0;
			} else {
				$END=$MaxRec;
				$nextflag=1;
			}
		}
	}

	return $dbh;
}

#--------------------------------------------------------
# HTML Output
#--------------------------------------------------------
sub output_records {
	my $dbh = shift;

	my ($errN, $errstr, $sth, @user, @race);
	my $loop = 0;
	my $adminkey = $dc->get_key($dc->DBaseTable('ADMIN'));
	my $AdxFile = $dc->q->param('AdxFile');
	my $searchtime = 0;

    print "Content-type: text/html\n";
    print <<EOF;

<html>
<head>
<title>
Sonic Adventure Online - MiniGame Time Attack
</title>
<meta name="x-uirequest" content="urlbaroff">
<script LANGUAGE = "JavaScript">
<!--
        if (document.images) {
            img1on = new Image(); 
            img1on.src = "file:/button_back_on.gif";   
            img1off = new Image(); 
            img1off.src = "file:/button_back.gif"; 
        }

function imgOn(imgName) {
        if (document.images) {
            document[imgName].src = eval(imgName + "on.src");
        }
}

function imgOff(imgName) {
        if (document.images) {
            document[imgName].src = eval(imgName + "off.src");
        }
}
// -->

</script>
<BGSOUND SRC="$AdxFile">
</head>
<body x-marginleft=0 x-margintop=0   background="file:/bg_scroller.gif" bgcolor="#000000" marginheight=0 marginwidth=0 topmargin=0 leftmargin=0>
<center>
<img src="file:/blank_dot.gif" width=1 height=30 border=0 alt=""><br>
<table cellspacing=0 cellpadding=5 border=0 width=590><tr><td align=center valign=top bgcolor="#000033"><table cellspacing=0 cellpadding=0 border=0 width=580><tr><td align=left valign=top bgcolor="#ffffff">

<!-- HEADER IMAGE -->
<!-- choose from below... -->
<!-- header_chao_showoff.gif -->
<!-- header_events.gif -->
<!-- header_world_rankings.gif -->

<img src="/images/header_minigame.gif" width=580 height=150 border=0 alt=""><br>

<!-- END HEADER IMAGE -->

<table cellspacing=0 cellpadding=0 border=0 width=580><tr><td align=left valign=top width="10">
<img src="file:/blank_dot.gif" width=10 height=1 border=0 alt="">
</td>
<td align=left valign=top width=560>

<!-- BEGIN CONTENT HERE -->
EOF

	print "<p>".$contestdesc.".<BR>";

	print <<EOF;
What is your ranking?
<p>
<a href="#bottom">BOTTOM</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
EOF

	if ($UserKey eq "")
	{
		&output_link;
	}

	print "<br><img src=\"file:/blank_dot.gif\" height=\"10\" width=\"1\"><br>";
	
	if ($dc->q->param('mode') eq "TODAY")
	{
		$searchtime = (24*60*60);
	}
	else
	{
		# 5 Years in seconds
		$searchtime = (5*365*24*60*60);
	}

	($errN, $errstr, $sth) = DB::getRow_RacingByEVENT( $dbh, $dc->DBaseTable('RACING'), $EventID, $searchtime );
	if ($errN)
	{
		DB::closeOracleConnection( $dbh );
		$dc->error("[minigame] Unable to get Minigame Events: $errN .... $errstr", $errorURL);
	}

	if($UserKey ne "") {
		my $Rank = 0;
	    while( (@race) = DB::getNextRow_Racing($sth) )
		{
			if ($race[$dc->RaceOff('KEY')] eq $adminkey)
			{
				#Skip that record since it is the Admin record
				(@race) = DB::getNextRow_Racing($sth);
			}

			if ($race[$dc->RaceOff('KEY')] eq $UserKey)
			{
				($errN, $errstr, @user) = DB::getRow_UserByUK( $dbh, $dc->DBaseTable('USER'), $UserKey );
				if ($errN)
				{
					DB::closeOracleConnection( $dbh );
					$dc->error("[minigame] Fetching user info: $errN .... $errstr", $errorURL);
				}
				&build_table($Rank, \@user, \@race);
			}
			++$Rank;
		}
	} else {
		for($loop=0;$loop<$END;$loop++) {
			(@race) = DB::getNextRow_Racing($sth);
			if ($race[$dc->RaceOff('KEY')] eq $adminkey)
			{
				#Skip that record since it is the Admin record
				(@race) = DB::getNextRow_Racing($sth);
			}
			if ($loop >= $START)
			{
				($errN, $errstr, @user) = DB::getRow_UserByUK( $dbh, $dc->DBaseTable('USER'), $race[$dc->RaceOff('KEY')] );
				if ($errN)
				{
					DB::closeOracleConnection( $dbh );
					$dc->error("[minigame] Fetching user info: $errN .... $errstr", $errorURL);
				}
				&build_table($loop, \@user, \@race);
			}
		}
	}

	DB::closeOracleConnection( $dbh );

	if ($UserKey eq "")
	{
		&output_link;
		print "&nbsp;<BR>\n";
	}

    print <<EOF;
<!-- END CONTENT HERE -->
&nbsp;<BR>
<a name="bottom"></a><a href="/minigame.html"  onMouseOver="imgOn('img1')" onMouseOut="imgOff('img1')"><img src="file:/button_back.gif" width=81 height=24 border=0 alt="" name="img1"></a><P>				
</td><td align=left valign=top width="10">
<img src="file:/blank_dot.gif" width=10 height=1 border=0 alt="">
</td>
</tr>
</table>
</tr>
</tr>
</table>
</td>
</tr>
</table>
<br>&nbsp;
</center>
</body>
</html>
EOF

}

sub build_table {
	my $rank = shift;
	my $user = shift;
	my $race = shift;

	print "<TABLE border=0 cellpadding=5 cellspacing=0 width=560 bgcolor=\"#CCCCCC\">\n";
	print "<TR>\n";
	printf "<TD BGCOLOR=\"#666666\"><FONT COLOR=\"#ffffff\">%d.</FONT></TD>\n",$rank+1;
	printf "<td align=left valign=top colspan=3 bgcolor=\"#666666\"><FONT COLOR=\"#ffffff\">".$dc->calc_int_time($race->[$dc->RaceOff('TIME')])." using %s</FONT></TD>\n",
	$CharaName[$race->[$dc->RaceOff('CHAR')]];
	print "</TR>\n<TR>\n";
	if ($dc->Flags($user->[$dc->UserOff('COUNTRY')]) ne "")
	{
		print "<TD valign=top width=60><img src=\"/images/flags/".$dc->Flags($user->[$dc->UserOff('COUNTRY')])."\" width=40 height=20 border=0></TD>\n";	
	} else {
		# Draw the generic flag
		print "<TD valign=top width=60><img src=\"/images/flags/flag_other.gif\" width=40 height=20 border=0></TD>\n";
	}
	print "<td align=left valign=middle colspan=2>$user->[$dc->UserOff('NAME')]<br>\n";
	print "$user->[$dc->UserOff('CITY')], ";
	if ($user->[$dc->UserOff('STATE')] ne "") {
		printf "%s, ", $dc->state_name($user->[$dc->UserOff('STATE')]);
	}
	printf " %s</TD>\n", $dc->country_name($user->[$dc->UserOff('COUNTRY')]);
	if($user->[$dc->UserOff('MFLAG')] eq "Y") {
		print "<TD width=40 ALIGN=\"right\"><A HREF=\"mailto:$user->[$dc->UserOff('EMAIL')]\"><IMG src=\"file:/icon_mail.gif\" border=0></A></TD>\n";
	} else {
		print "<TD width=40 ALIGN=\"right\"><BR></TD>\n";
	}
	print "</TR>\n";

	print "<TR><TD valign=top width=60 bgcolor=\"#dddddd\">";
	if ($dc->q->param('mode') eq "TODAY")
	{
		if ($rank == 0)
		{
			print "<img src=\"/images/wrank/flag_1_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
		elsif ($rank == 1)
		{
			print "<img src=\"/images/wrank/flag_2_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
		elsif ($rank == 2)
		{
			print "<img src=\"/images/wrank/flag_3_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
	}
	else
	{
		if ($rank == 0)
		{
			print "<img src=\"/images/wrank/gold_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
		elsif ($rank == 1)
		{
			print "<img src=\"/images/wrank/silver_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
		elsif ($rank == 2)
		{
			print "<img src=\"/images/wrank/bronze_big.gif\" width=50 height=50 border=0 hspace=5 align=\"top\">";
		}
	}

	print "</td><TD colspan=\"3\" BGCOLOR=\"#DDDDDD\">Awards:<br>";

	my $count = 0;
	my $loop;

	if ($user->[$dc->UserOff('EMBLEMS')] == 130)
	{
		# User gets emblem award if has all 130
		print "<img src=\"/images/wrank/emblem_small.gif\" width=25 height=25 border=0 hspace=2 align=\"top\">";
		++$count;
	}

	for ($loop = 0; $loop < $user->[$dc->UserOff('GOLD')]; ++$loop)
	{
		print "<img src=\"/images/wrank/gold_small.gif\" width=25 height=25 border=0 hspace=2 align=\"top\">";
		++$count;
		if ($count >= 16)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=2 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $user->[$dc->UserOff('SILVER')]; ++$loop)
	{
		print "<img src=\"/images/wrank/silver_small.gif\" width=25 height=25 border=0 hspace=2 align=\"top\">";
		++$count;
		if ($count >= 16)
		{
			print "<BR><img src=\"file:/blank_small.gif\" height=2 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $user->[$dc->UserOff('BRONZE')]; ++$loop)
	{
		print "<img src=\"/images/wrank/bronze_small.gif\" width=25 height=25 border=0 hspace=2 align=\"top\">";
		++$count;
		if ($count >= 16)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=2 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	for ($loop = 0; $loop < $user->[$dc->UserOff('BLUERIB')]; ++$loop)
	{
		print "<img src=\"/images/wrank/ribbon_small.gif\" width=25 height=25 border=0 hspace=2 align=\"top\">";
		++$count;
		if ($count >= 16)
		{
			print "<BR><img src=\"file:/blank_dot.gif\" height=2 width=1 border=0><br>\n";
			$count = 0;
		}
	}

	print "\n&nbsp;<BR>\nComments:<BR>$race->[$dc->RaceOff('COMMENT')]</TD></TR>\n";
	print "</TABLE>\n";
	print "&nbsp;<BR>\n";
}

sub output_link {
	# Link Menu Output
	my $str = "";
	my $prank = 0;
	my $nrank = 0;
		
	if($START > 0) {
		$prank=$START-$MAX+1;
		if($prank<0) { $prank=0; }
		$str= 'command=view&max=' . $MAX . '&start=' . $prank . '&EVENT='.$dc->q->param('EVENT') .
              '&mode='. $dc->q->param('mode');
		print "[<A HREF=\"$cgiPath?$str\">Higher Ranks</A>]\n";
	}
	if($nextflag==0) {
		$nrank=$START+$MAX+1;
		$str= 'command=view&max=' . $MAX . '&start=' . $nrank . '&EVENT='.$dc->q->param('EVENT') .
              '&mode='. $dc->q->param('mode');
		print "[<A HREF=\"$cgiPath?$str\">Lower Ranks</A>]\n";
	}
}

#------------------------ EOF --------------------------
