#!/usr/bin/perl -w
# shows the tournament table page with top results
# for bubble shooter
# params: l=level; s=sort mode

use strict;
use CGI qw(:standard -no_xhtml -oldstyle_urls);
use CGI::Carp;
#use CGI::Pretty;
use Fcntl qw(:DEFAULT :flock);

$CGI::POST_MAX = 1024;

use vars qw($game $from $level $now $addr $webroot %games %best @best
            $points_name $sort %sort $maxname $maxmess $ptitle $pkeyword
	    $pdescript $css_url $maxpoint $def_icon @def_icon $def_cc $def_mess);

$webroot = "/var/www/vhosts/bshooter";  # we use the Absolutist site structure
$maxname = 23;
$maxmess = 77;
$css_url = 'http://bshooter.com/bubshooter.css';
$maxpoint = 1000000000;
$def_mess = " &nbsp; ";
$def_cc = "_bs";
$def_icon = "bs03";
@def_icon = qw(bs01 bs02 bs03 bs04 bs05 bs06);

# data for all the games
%games = (
  bsh => {name => 'Bubble Shooter',
          file => "$webroot/result.dt",
          levels => {
	    1=>'Strategy Novice', 2=>'Strategy Expert', 3=>'Strategy Master',
	    4=>'Arcade Novice', 5=>'Arcade Expert', 6=>'Arcade Master',
	    7=>'Sniper Novice', 8=>'Sniper Expert', 9=>'Sniper Master',
	    10=>'Marathon Novice', 11=>'Marathon Expert',
	    12=>'Marathon Master', 13=>'Strategy Easy', 14=>'Arcade Easy',
	    15=>'Sniper Easy', 16=>'Marathon Easy'},
          backw => {7=>1, 8=>1, 9=>1, 15=>1},
	  deflevel => 1,
	  shown => 20},
);

$pkeyword = 'bubble shooter bubbles pack contest tournament prizes awards pentix mosaic columns arcade puzzle board games';

$pdescript = 'Online Tournament: Best results for Bubble Shooter Game Contest - play and win awards and prizes!';

# allowed sorting modes
%sort = (
 'R'  => 'Recent',
 '0'  => 'All Time',
 '1'  => 'Daily',
 '7'  => 'Weekly',
 '30' => 'Monthly',
);

# get parameters;
$game  = 'bsh';                    # name of the game
$level = param('l') || 0;          # a number 1-n, 0 = default, or none
$sort  = param('s');               # default = R = last submissions
$sort = 'R' unless defined $sort   # if =N, sort by resuld for N days, 0=all
               and $sort{$sort};
$now   = time();
$addr  = remote_addr() || "-";

srand(time*$$);

$ptitle = "$games{$game}->{name} Online Tournament: Best results for "
        . "$games{$game}->{name} Game Contest - play and win awards and prizes!";

# now level: if there are levels for this game, check if level is
# correct, if no - set default
if (%{$games{$game}->{levels}}) {
    unless (exists $games{$game}->{levels}->{$level}) {
        $level = $games{$game}->{deflevel};
    }
    param('l', $level);
} else {
    $level = 0;
}

open  RES, $games{$game}->{file} or RiP("$games{$game}->{file}: $!", "");
flock RES, LOCK_SH;
# pick one best for every name
# %best is indexed by name -> [time, point, cc, messg]
while (<RES>) {
    next if is_bad_word($_);
    chomp;
    my ($r_when,$r_addr,$name,$point,$r_level,$client,$messg,$cc,$icon)
        = split /\t/;
    next unless $r_level == $level;
    next if is_bad_num($point);
    $cc ||= $def_cc;
    $messg ||= $def_mess;          # defaults for old results
    $icon ||= rand_element(@def_icon);
    $icon = rand_element(@def_icon) unless -s "$webroot/images/smile/$icon.gif";
    if (uc $sort eq 'R') {  # here we show last results in order of submission
        next if defined $best{$name} and $best{$name}->[0] > $r_when;
        $best{$name} = [$r_when,$point,$cc,$messg,$icon];
    } else {                # here we sort by result for given period
        next if $sort and $now - $r_when > $sort*3600*24;  # too old
        next if defined $best{$name}                       # already have
	     and better($best{$name}->[1],$point) > 0;     # better than this -
	     #   same will replace as they are in order of submit
        $best{$name} = [$r_when,$point,$cc,$messg,$icon];
    }
}
flock RES, LOCK_UN;
close RES;

warn scalar keys %best, " entries in best table\n";

# sort by result, then by abc, and put tops in array
if (uc $sort eq 'R') {
    foreach (sort {better($best{$b}->[0],$best{$a}->[0])
                   or $a lt $b} keys %best) {
        push @best, ["__FLG__".img({src=>"../images/b_news.jpg",  #JN было: src=>"/images/flg/$best{$_}->[2].gif",
	                            alt=>"$best{$_}->[2]", align=>'center'}),
	             "__NAM__$_",
		     "__PTS__".$best{$_}->[1],
		     "__SML__".img({src=>"../images/k_reg.gif",  #JN было: src=>"/images/smile/$best{$_}->[4].gif",
	                            alt=>"$best{$_}->[4]", align=>'center'}),
		     "__MSG__".$best{$_}->[3]
		    ];
        last if @best == $games{$game}->{shown};
    }
} else {  # everything else is descending, when sorted by time as well
    foreach (sort {better($best{$b}->[1],$best{$a}->[1])
             or $a lt $b} keys %best) {
        push @best, ["__FLG__".img({src=>"../images/b_news.jpg",  #JN было: {src=>"/images/flg/$best{$_}->[2].gif",
	                            alt=>"$best{$_}->[2]", align=>'center'}),
	             "__NAM__$_",
		     "__PTS__".$best{$_}->[1],
		     "__SML__".img({src=>"../images/k_reg.gif",  #JN было: {src=>"/images/smile/$best{$_}->[4].gif",
	                            alt=>"$best{$_}->[4]", align=>'center'}),
		     "__MSG__".$best{$_}->[3]
		    ];
        last if @best == $games{$game}->{shown};
    }
}

# build the table which we'll print below
my $TABLE = TR({-valign=>'middle'},
 	       [(
		 map { &td($_) } @best
	       )]
	    );
# flags are centered
$TABLE =~ s|<td(.*?)>__FLG__(.*?)</td>|<td$1 align="center" width=30>$2</td>|g;
# names are left-aligned and short
$TABLE =~ s|<td(.*?)>__NAM__(.*?)</td>|"<td$1 align='left' width=170> ".&shorten($2).'</td>'|eg;
# points are right-aligned
$TABLE =~ s|<td(.*?)>__PTS__(.*?)</td>|<td$1 align="right" width=70>$2 </td>|g;
# smilies are centered
$TABLE =~ s|<td(.*?)>__SML__(.*?)</td>|<td$1 align="center" width=20>$2</td>|g;
# messages are smaller font
$TABLE =~ s|<td(.*?)>__MSG__(.*?)</td>|"<td$1><font size=-2>".&tidify($2,30).'</font></td>'|eg;  #"

# build the select things
my $SELECT = TR({-valign=>'middle'},
                td({-align=>'center'},
	           startform,
  	           $games{$game}->{deflevel} ?
                   ("Level: ",
                   popup_menu(-name => 'l',
                              -value => [sort { $games{$game}->{levels}->{$b}
			                    cmp $games{$game}->{levels}->{$a} }
			                 keys %{$games{$game}->{levels}}],
		              -default => $games{$game}->{deflevel},
		              -labels => $games{$game}->{levels},
                   ), "&nbsp;&nbsp;&nbsp;")
		   : "",
                   "Show: ",
                   popup_menu(-name => 's',
                              -value   => ['R','1','7','30','0'],
		              -default => 'R',
		              -labels  => \%sort,
                   ), " results &nbsp;&nbsp;&nbsp;",
#		   submit(-name=>'submit', -value=>'Refresh'),
                   image_button(-name=>'refresh',
                                -src=>'/images/b_refresh.gif',
                                -align=>'middle',
				-alt=>'Refresh',
				-border=>0,
				-id=>'btn_refresh',
				-width => 105,
				-height=>  21,
				-onMouseOver=>q|swapImage('btn_refresh', '/images/b_refresh_h.gif');|,
				-onMouseOut =>q|restoreImage('btn_refresh');|,
				),
                   endform
	        )
	     );
(my $SELECT2 = $SELECT) =~ s/\bbtn_refresh\b/btn_refresh1/g;

# show the page, no caching
print header(-type=>'text/html',
             -expires=>'-1d',
	     -meta=>{-keywords=>$pkeyword, -description=>$pdescript},
      );

print start_html(-title => $ptitle,
                 -bgcolor => '#C5C4FE',
		 -leftmargin  => 0, -topmargin    => 20,
		 -marginwidth => 0, -marginheight => 0,
                 -style  => {-src=>$css_url},
		 -script => {-language=>'JAVASCRIPT', -src=>'/bubshooter.js'},
                 -onLoad => qq|preloadImages('/images/b_refresh_h.gif');|,
      );

print my_header();

print table({-align=>'center', -border=>'0', -cellpadding=>'7', -width=>'88%',
             -class=>'txt'},
            TR(td({-align=>'center'},
                  b("$games{$game}->{name} $games{$game}->{levels}->{$level} World Cup:",
		    "$sort{$sort}", $sort eq 'R'?'':"Top", "Scorers")),
	    ),
            $SELECT,
      ),
      table({-align=>'center', -border=>'0', -cellpadding=>'0', -width=>'88%',
             -class=>'txt'},
            TR({-valign=>'top'},
	       th({-align=>'center'},
	          ['', 'Name', 'Pts', '', 'Message']
	       )
	    ),
            $TABLE,
      ),
      table({-align=>'center', -border=>'0', -cellpadding=>'7', -width=>'88%',
             -class=>'txt'},
            $SELECT2,
      );

print my_footer();

print end_html;

exit;


sub better {   # 1 if first is better than second
    if (defined $games{$game}->{'backw'}->{$level}) {
        return $_[1] <=> $_[0];    # sorted backwards
    } else {
        return $_[0] <=> $_[1];    # normal way - bigger is better
    }
}

sub shorten {   # shortens very long names to fit in table
    my $name =  $_[0];
    $name =~ s/\s+$//;
##    $name =~ s/^\s*[sht]_[TPMCB]\w+(\s+|$)//;   # drop levels???
    $name ||= 'anonymous';
    $name = substr($name, 0, 22) . '...' if 22 < length $name;
    return $name;
}

sub tidify {  # splits very long names to fit in table
    my ($str, $max) = @_;
    $max = 13 if $max =~ /\D/;
    $str =~ s/(\S{$max})/$1 /g;
    return $str;
}

sub rand_element {  # returns random value from an array
    my @arr = @_ or return undef;
    return $arr[ int rand(@arr) ];
}

sub is_bad_word {
    my $name = $_[0];
    return 1 if $name =~ /fuck|penis|cocksuck|bitch|sucker/i;
    return 0;
}

sub is_bad_num {
    my $point = $_[0];
    return 1 if $point =~ /(\d)\1{5,}/   # like 3333333
             or $point > $maxpoint;      # too many
    return 0;
}

sub RiP {  ## something is very wrong - die and show error page
           ## 1st arg is system error, second is message for user
    my $sys_err = shift || "something is wrong";
    my @usr_msg = @_;
    @usr_msg = "Tournament server is busy or overloaded. "
              ."Sorry for the inconvenience, please come later."
    unless @usr_msg;
    print header(-type=>'text/html', -expires=>'-1d');
    print start_html(-title => $usr_msg[0],
                     -bgcolor => '#C5C4FE',
	  	     -leftmargin  => 0, -topmargin    => 20,
		     -marginwidth => 0, -marginheight => 0,
                     -style => {-src=>$css_url},
          );
    print my_header();
    print join '<br>', @usr_msg;
    print my_footer();
    print end_html;
    die "$sys_err\n";
}

sub my_header {
return <<'_END_HEADER_';
<table width="778" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr valign="top">
    <td width="23" align="left" background="/images/mid2_in.gif"><img src="/images/mid1_in.gif" width="23" height="17"></td>
    <td background="/images/fon_top.gif"><img src="/images/spacer.gif" width="720" height="1"></td>
    <td width="35" align="right" background="/images/fon_right.gif"><img src="/images/corn1.gif" width="35" height="17"></td>
  </tr>
  <tr>
    <td width="23" align="left" background="/images/mid2_in.gif">&nbsp;</td>
    <td bgcolor="#B3B3FB"><SCRIPT LANGUAGE=JavaScript1.1>
<!--
var MM_contentVersion = 5;
var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
if ( plugin ) {
		var words = navigator.plugins["Shockwave Flash"].description.split(" ");
	    for (var i = 0; i < words.length; ++i)
	    {
		if (isNaN(parseInt(words[i])))
		continue;
		var MM_PluginVersion = words[i];
	    }
	var MM_FlashCanPlay = MM_PluginVersion >= MM_contentVersion;
}
else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0
   && (navigator.appVersion.indexOf("Win") != -1)) {
	document.write('<SCR' + 'IPT LANGUAGE=VBScript\> \n'); //FS hide this from IE4.5 Mac by splitting the tag
	document.write('on error resume next \n');
	document.write('MM_FlashCanPlay = ( IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & MM_contentVersion)))\n');
	document.write('</SCR' + 'IPT\> \n');
}
if ( MM_FlashCanPlay ) {
		document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
	document.write('  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" ');
	document.write(' ID="flash" WIDTH="700" HEIGHT="107" ALIGN="">');
	document.write(' <PARAM NAME=movie VALUE="/images/flash_in.swf"> <PARAM NAME=quality VALUE=high> <PARAM NAME=bgcolor VALUE=#C5C4FE>  ');
	document.write(' <EMBED src="/images/flash_in.swf" quality=high bgcolor=#C5C4FE  ');
	document.write(' swLiveConnect=FALSE WIDTH="700" HEIGHT="107" NAME="flash" ALIGN=""');
	document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">');
	document.write(' </EMBED>');
	document.write(' </OBJECT>');
} else{
	document.write('<IMG SRC="/images/flash_in.jpg" WIDTH="700" HEIGHT="107" usemap="#flash" BORDER=0>');
}
//-->
</SCRIPT><NOSCRIPT><IMG SRC="/images/flash.jpg" WIDTH="350" HEIGHT="525" usemap="#flash" BORDER=0></NOSCRIPT>
</td>
    <td width="35" align="right" background="/images/fon_right.gif">&nbsp;</td>
  </tr>
  <tr valign="bottom">
    <td width="23" align="left" background="/images/mid2_in.gif"><img src="/images/mid3_in.gif" width="23" height="13"></td>
    <td background="/images/fon_bot.gif"><img src="/images/spacer.gif" width="720" height="1"></td>
    <td width="35" align="right" background="/images/fon_right.gif"><img src="/images/corn2.gif" width="35" height="13"></td>
  </tr>
</table>
<img src="/images/spacer.gif" width="10" height="10">
<table width="778" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr valign="top">
    <td width="23" align="left" background="/images/mid2_in.gif"><img src="/images/mid1_in.gif" width="23" height="17"></td>
    <td background="/images/fon_top.gif"><img src="/images/spacer.gif" width="720" height="1"></td>
    <td width="35" align="right" background="/images/fon_right.gif"><img src="/images/corn1.gif" width="35" height="17"></td>
  </tr>
  <tr>
    <td width="23" align="left" background="/images/mid2_in.gif">&nbsp;</td>
    <td valign="top" bgcolor="#B3B3FB">

<br />
<div align="center">
<script type="text/javascript"><!--
google_ad_client = "pub-7772984219050257";
/* bs_leaderboard - 728x90, 12.05.2009, blends with bg */
google_ad_slot = "7805299841";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br />



_END_HEADER_
}

sub my_footer {
return <<_END_FOOTER_;

<br />
<div align="center">
<script type="text/javascript"><!--
google_ad_client = "pub-7772984219050257";
/* bs_leaderboard - 728x90, 12.05.2009, blends with bg */
google_ad_slot = "7805299841";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<br />

    </td>
    <td width="35" align="right" background="/images/fon_right.gif">&nbsp;</td>
  </tr>
  <tr valign="bottom">
    <td width="23" align="left" background="/images/mid2_in.gif"><img src="/images/mid3_in.gif" width="23" height="13"></td>
    <td background="/images/fon_bot.gif"><img src="/images/spacer.gif" width="720" height="1"></td>
    <td width="35" align="right" background="/images/fon_right.gif"><img src="/images/corn2.gif" width="35" height="13"></td>
  </tr>
</table>
<div align="center" class="txt2"><font color="#FFFFFF"><a href="/download.html">Download</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/screenshot.html">Screenshots</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/cgi-bin/tournament.pl">Tournament</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/support.html">Support</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/cgi-bin/wp_reg_bs.pl?tick=awgBUBL">Full Version</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/news.html">News</a></font>
<br><font class="txt2">&copy; BShooter.com 2003-2005</font>
<MAP NAME="flash">
  <area shape="rect" coords="49,55,155,96"  href="/">
  <area shape="rect" coords="163,54,287,97" href="/download.html">
  <area shape="rect" coords="294,52,437,95" href="/screenshot.html">
  <area shape="rect" coords="445,50,588,92" href="/cgi-bin/tournament.pl">
  <area shape="rect" coords="595,50,700,92" href="/support.html">
</MAP>
_END_FOOTER_
}
