#!/usr/bin/perl
# CGI přístup k databázi her. Generuje jak seznamy, tak stránky o konkrétních hrách.
# (c) 2002 - 2006 Daniel Zeman
# Licence: GNU GPL
# prosinec 2002: vytvořeno
# 30.12.2003: přechod na UTF-8
# 11.12.2005: data už se neberou z textových souborů, ale z MySQL serveru

use utf8;
use Encode;
use DBI;
# Přidat Danovy sdílené knihovny. Skript běžící pod uživatelem apache by je jinak nenašel.
BEGIN {unshift(@INC, "/home/dan/lib") unless(grep {$_ =~ m-/home/dan/lib-} @INC);}
use mysql;
# Přinutit Perl, aby UTF8 vypisoval jako UTF8 a nevymýšlel pro mě "vhodné" osmibitové kódování.
binmode(STDOUT, ":utf8");
# Kvůli sestavení parametrů; čtení parametrů zatím probíhá nějak pravěce.
require("./dancgi.pm");
use pomoc;
# Danovo české třídění.
use csort;
use kecy;
use katalog;
use kosik;
use objednavka;



# Zapamatovat si, kdy jsme s generováním stránky začali, abychom na konci mohli
# zjistit, jak dlouho nám to trvalo.
$starttime = time();



# Přečíst parametry.
dancgi::cist_parametry(\%pole);
dancgi::cist_formular_post(\%pole) if($pole{formular});
# Robotům odmítnout přístup, jestliže si chtějí něco strčit do košíku.
use norobot;
if(exists($pole{kosik}) && !norobot::proverit())
{
    norobot::ohlasit_chybu();
    exit(0);
}



# Zjistit cestu pro odkazování na statické stránky hrejsi.
open(KONFIG, "../cgi.cfg");
while(<KONFIG>)
{
    if(m/(\S+)\s*=\s*([^\r\n]*)/)
    {
        $konfig{$1} = $2;
    }
}
close(KONFIG);
$koren_hrejsi = $konfig{ccesta_html_www};
$koren_system = $konfig{scesta_html_www};
# Pro ladící účely si nachystat výpis parametrů na výstup.
$ladeni = 0;
if($ladeni)
{
    foreach($key, sort(keys(%pole)))
    {
        $dbg_parametry .= "$key = $pole{$key}\n";
    }
    $dbg_parametry = "<pre>$dbg_parametry</pre>\n";
}
# Parametry, které se nemají propagovat do všech odkazů vedoucích odsud dál,
# je potřeba přestěhovat z hashe %pole někam jinam, kde je najdou pouze funkce,
# které je potřebují pro výrobu této stránky, ale ne pro konstrukci odkazů z ní.
$hledat = $pole{hledat}; # globální proměnná
delete($pole{hledat});
if($pole{hra} eq "objednavka")
{
    $objednany_kosik = $pole{kosik}; # globální proměnná
    delete($pole{kosik});
}
# Připojit se k databázi her.
# Pokud je skript spuštěn webovým serverem (uživatel www-data), měl by mít dostatečná práva pro přístup k databázi.
# Pokud je ale spuštěn uživatelem dan@kub.cz, práva nemá a musí se databázi hlásit jako root. V tom případě je potřeba,
# aby příslušné heslo bylo v proměnné prostředí DBI_ROOT_PASS.
if($ENV{USER} eq "dan")
{
    if(!exists($ENV{DBI_ROOT_PASS}))
    {
        die("Pri spusteni jinym uzivatelem nez www-data musi byt v promenne prostredi DBI_ROOT_PASS heslo roota do databaze.\n");
    }
    $dbi_uzivatel = "root";
    $dbi_heslo = $ENV{DBI_ROOT_PASS};
}
$databaze = DBI->connect("DBI:mysql:hry", $dbi_uzivatel, $dbi_heslo)
  or print STDERR ("Nelze se pripojit k databazi: $DBI::errstr\n");
# Nastavit kódování klienta, spojení a výsledků.
$databaze->prepare("SET NAMES 'utf8'")->execute();
vypsat_stranku();



###############################################################################
# Podprogramy
###############################################################################



#------------------------------------------------------------------------------
# Vypíše kostru stránky. Volá podřízené funkce pro jednotlivé části stránky.
#------------------------------------------------------------------------------
sub vypsat_stranku
{
    vypsat_zahlavi();
    print("  <table border=\"0\" width=\"100%\">\n");
    print("    <tr>\n");
    print("      <td align=\"center\" valign=\"top\" width=\"15%\">\n");
    vypsat_odkazy_na_palubu();
    print(katalog::seznam_her($databaze));
    print("      </td>\n");
    print("      <td align=\"center\" valign=\"top\" width=\"65%\">\n");
    # Vnořit tabulku do pravé buňky.
    print("        <table border=\"0\" width=\"100%\">\n");
    print("          <tr>\n");
    print("            <td align=\"center\" valign=\"top\">\n");
    vypsat_uvod_obchodu();
    print("            </td>\n");
    print("            <td align=\"center\" valign=\"top\" bgcolor=lightgreen>\n");
    vypsat_poradnu();
    print("            </td>\n");
    print("          </tr>\n");
    print("          <tr valign=\"top\">\n");
    vypsat_prostredek_stranky();
    vypsat_pravy_okraj();
    print("          </tr>\n");
    print("        </table>\n");
    print("      </td>\n");
    print("    </tr>\n");
    print("  </table>\n");
    # Zjistit, jak dlouho nám to trvalo, a vypsat to na konec stránky.
    my $hlaseni = sestavit_hlaseni_o_trvani_programu($starttime);
    print("  <div align=right><address>$hlaseni</address></div>\n");
    # Vypsat závěr stránky.
    vypsat_zapati();
}



#------------------------------------------------------------------------------
# Provede počáteční úkony, nezávislé na tom, jaký pohled uživatel zvolil.
# Pozor! (léto 2007) Ve skutečnosti i tady musíme vědět, jaký pohled uživatel
# zvolil. Pokud si řekl o konkrétní hru, chceme, aby v názvu stránky bylo
# "koupit hru tu a tu". To kvůli indexování roboty.
# Načte parametry a vypíše začátek HTML stránky.
#------------------------------------------------------------------------------
sub vypsat_zahlavi
{
    # Poslat MIME záhlaví dokumentu.
    print("Content-Type: text/html; charset=utf-8\n\n");
    # Poslat začátek stránky.
    print <<EOF
<html>
  <head>
EOF
    ;
    # Nedovolit robotům indexovat stránku, na které je něco v košíku.
    if(exists($pole{kosik}))
    {
        # index/noindex ... indexovat tuto stránku?
        # follow/nofollow ... sledovat odkazy z této stránky?
        # noindex,nofollow
        print("    <meta name=\"robots\" content=\"noindex\">\n");
    }
    # Sestavit název stránky. Pokud je stránka cílena na určitou hru, musí být název hry obsažen v názvu.
    my $nazev_stranky;
    if(exists($pole{hra}))
    {
        my $odpoved = mysql::dotaz($databaze, "nazev", "hry WHERE kod='$pole{hra}'");
        if(scalar(@{$odpoved}))
        {
            my $nazev_hry = $odpoved->[0]{nazev};
            $nazev_stranky = "Koupit $nazev_hry (obchod)";
        }
        else
        {
            # Nebyl nalezen název hry podle kódu. Nejspíš šlo o pseudokód, např. "novinky" nebo "poradna".
            $nazev_stranky = "Deskové hry: obchod: $pole{hra}";
        }
    }
    else
    {
        $nazev_stranky = "Deskové hry: obchod";
    }
    print <<EOF
    <meta http-equiv="Content-Language" content="cs">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>$nazev_stranky</title>
    <meta name="description" content="Obchod s hrami, Portál o deskových hrách. Pravidla, recenze, akce, e-obchod, pozvánky, turnaje, informace o deskových hrách.">
    <meta name="keywords" content="prodej, nákup, obchod, e-obchod, on-line obchod, obchod s hrami, objednávky, košík, košíček, objednat, hračky, deskove hry, hry, deskové hry, stolní hry, společenské hry, Klub deskových her Paluba, Klub Paluba, pravidla, turnaje, games, board games, akce, pozvánky, recenze, Othello, Abalone, Carcassonne, Osadníci, Bang, Vrhcáby, Scrabble, Zatre.">
  </head>
  <body>
EOF
    ;
}



#------------------------------------------------------------------------------
# Vypíše závěr stránky HTML.
#------------------------------------------------------------------------------
sub vypsat_zapati
{
    # Poslat konec stránky.
    print <<EOF
  </body>
</html>
EOF
    ;
}


#------------------------------------------------------------------------------
# Vypíše přehled poraden v horním proužku.
#------------------------------------------------------------------------------
sub vypsat_poradnu
{
    print(odkazpar("<font color=green size=+1><b>Herní poradna:</b></font>", \%pole, "hra=poradna"), "\n");
    print("<br><font color=green>Hry pro:</font>\n");
    print("<table width=\"100%\">\n");
    print("<tr><td>", odkazpar("<font color=green>celou rodinu </font>", \%pole, "hra=rodina"), "\n");
    print("    <td>", odkazpar("<font color=green>děti 2-7 let </font>", \%pole, "hra=deti"), "\n");
    print("<tr><td>", odkazpar("<font color=green>fajnšmekry </font>", \%pole, "hra=experti"), "\n");
    print("    <td>", odkazpar("<font color=green>dva </font>", \%pole, "hra=pro2"), "\n");
    print("<tr><td>", odkazpar("<font color=green>party a mejdany </font>", \%pole, "hra=mejdan"), "\n");
    print("</table>\n");
}



#------------------------------------------------------------------------------
# Vypíše úvodní text obchodu s hrami.
#------------------------------------------------------------------------------
sub vypsat_uvod_obchodu
{
    print("<h3>\n");
    print(odkazpar("<font color=red>NOVINKY</font>", \%pole, "hra=novinky"), " | \n");
    print(odkazpar("DODACÍ PODMÍNKY", \%pole, "hra=obecne"), " | \n");
    print(odkazpar("SLEVY", \%pole, "hra=slevy"), " | \n");
    print(odkazpar("CENÍK", \%pole, "hra=cenik"), " | \n");
    print(odkazpar("SLOVENSKO", \%pole, "hra=slovensko"), "| \n");
    print(odkazpar("<font color=green>PORADNA</font>", \%pole, "hra=poradna"), " \n");
    print("</h3>\n");
    print("<h1>Obchod s&nbsp;hrami</h1>\n");
#     print("<h3><font color=red><h3>Ve dnech 30.9. - 8.10.2006 se v Praze uskuteční 6. ročník mezinárodního festivalu her <a href=http://www.deskohrani.cz/>Deskohraní</a>.</font></p>\n");

#    print("<h3><font color=red>Objednávky přijaté v době 5. - 20.8.2006 budou vyřízeny až po 21.8., </br> tudíž je obdržíte až koncem srpna či začátkem září. O přesném termínu dodání budete vyrozuměni po 21.8.2006. Děkujeme za pochopení. Osobní nákup na Palubě je možný v době otvíracích hodin. Více na <a href=http://www.paluba.cz/>www.paluba.cz</a>.</font></h3>\n");
}



#------------------------------------------------------------------------------
# Vypíše odkazy na Palubu.
#------------------------------------------------------------------------------
sub vypsat_odkazy_na_palubu
{
    print("<p>Hry si můžete koupit jak ");
    print("<a href=\"http://www.paluba.cz\">na&nbsp;Palubě,</a>");
#     print("</br><img src=\"$koren_hrejsi/obr/logo.gif\" height=50 align=center>");
    print(" tak ");
    print(odkazpar("zde na dobírku.", \%pole, "hra=obecne"));
}



#------------------------------------------------------------------------------
# Vypíše prostředek stránky
#------------------------------------------------------------------------------
sub vypsat_prostredek_stranky
{
    if($pole{hra} eq "" && $hledat eq "")
    {
        prostredek_novinky();
    }
    elsif($pole{hra} eq "obecne")
    {
        prostredek_obecny();
    }
    elsif($pole{hra} eq "novinky")
    {
        prostredek_novinky();
    }
    elsif($pole{hra} eq "poradna")
    {
        prostredek_poradna();
    }
    elsif($pole{hra} eq "deti")
    {
        prostredek_poradna_deti();
    }
    elsif($pole{hra} eq "rodina")
    {
        prostredek_poradna_rodina();
    }
    elsif($pole{hra} eq "pro2")
    {
        prostredek_poradna_pro2();
    }
    elsif($pole{hra} eq "experti")
    {
        prostredek_poradna_experti();
    }
    elsif($pole{hra} eq "mejdan")
    {
        prostredek_poradna_mejdan();
    }
    elsif($pole{hra} eq "slevy")
    {
        prostredek_slevy();
    }
    elsif($pole{hra} eq "cenik")
    {
        prostredek_cenik();
    }
    elsif($pole{hra} eq "cenikk")
    {
        prostredek_cenik_klubovy();
    }
    elsif($pole{hra} eq "objednavka")
    {
        prostredek_objednavka();
    }
    elsif($pole{hra} eq "slovensko")
    {
        prostredek_slovensko();
    }
    elsif($hledat ne "")
    {
        prostredek_hledani($hledat);
    }
    else
    {
        prostredek_hra($pole{hra});
    }
}



#------------------------------------------------------------------------------
# Vypíše obecný prostředek, když není vybrána konkrétní hra (dodací podmínky).
#------------------------------------------------------------------------------
sub prostredek_obecny
{
    print("        <td align=\"center\" valign=\"top\" width=\"70%\">\n");
    kecy::obecne();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek novinky, když není vybrána konkrétní hra.
#------------------------------------------------------------------------------
sub prostredek_novinky
{
print <<EOF
      <tr valign="top">
        <td valign="top" WIDTH="70%">
EOF
;
    print(katalog::novinky($databaze));
    print("</td>");
print <<EOF
        </td>
EOF
    ;
}



#------------------------------------------------------------------------------
# Vypíše prostředek s informacemi o podmínkách zasílání na Slovensko.
#------------------------------------------------------------------------------
sub prostredek_slovensko
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::slovensko();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když není vybrána konkrétní hra.
#------------------------------------------------------------------------------
sub prostredek_poradna
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když jsou vybrány rodinné hry.
#------------------------------------------------------------------------------
sub prostredek_poradna_rodina
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna_rodina();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když jsou vybrány hry pro malé děti.
#------------------------------------------------------------------------------
sub prostredek_poradna_deti
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna_deti();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když jsou vybrány hry pro dva hráče.
#------------------------------------------------------------------------------
sub prostredek_poradna_pro2
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna_pro2();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když jsou vybrány hry pro fajnšmekry.
#------------------------------------------------------------------------------
sub prostredek_poradna_experti
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna_experti();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek Herní poradna, když jsou vybrány hry na mejdan.
#------------------------------------------------------------------------------
sub prostredek_poradna_mejdan
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::poradna_mejdan();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek slevy, když není vybrána konkrétní hra.
#------------------------------------------------------------------------------
sub prostredek_slevy
{
    print("      <tr valign=\"top\">\n");
    print("        <td valign=\"top\" width=\"70%\">\n");
    kecy::slevy();
    print("        </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek, když je vybrán ceník.
#------------------------------------------------------------------------------
sub prostredek_cenik
{
    # Vypsat ceník.
    print <<EOF
          <td align="center" valign="top" WIDTH="70%">
EOF
    ;
    print(katalog::cenik($databaze));
    print <<EOF
          </td>
EOF
    ;
}



#------------------------------------------------------------------------------
# Vypíše prostředek, když je vybrán ceník pro kluby.
#------------------------------------------------------------------------------
sub prostredek_cenik_klubovy
{
    # Vypsat ceník.
    print <<EOF
          <td align="center" valign="top" WIDTH="70%">
EOF
    ;
    print(katalog::klubovy_cenik($databaze));
    print <<EOF
          </td>
EOF
    ;
}



#------------------------------------------------------------------------------
# Vypíše prostředek, když je vybrána konkrétní hra.
#------------------------------------------------------------------------------
sub prostredek_hra
{
    my $hra = shift;
    print(katalog::hra($databaze, $hra));
}



#------------------------------------------------------------------------------
# Vypíše prostředek s výsledky hledání.
#------------------------------------------------------------------------------
sub prostredek_hledani
{
    my $retezec = shift;
    print("<tr><td>\n");
    print("<h2>Výsledky hledání řetězce '$retezec' v&nbsp;katalogu</h2>\n");
    print(katalog::hledat($databaze, $retezec));
    print("</td>\n");
}



#------------------------------------------------------------------------------
# Vypíše prostředek, když došlo k objednávce.
#------------------------------------------------------------------------------
sub prostredek_objednavka
{
    print("<td align=center valign=top width=\"70%\">\n");
    my $objednavka = objednavka::zjistit($objednany_kosik, \%pole, $databaze);
    print(objednavka::zpracovat($objednavka, $databaze));
    # Ukončit prostřední buňku.
    print("</td>\n");
}



#------------------------------------------------------------------------------
# Vypíše pravý okraj stránky s výjimkou odkazů na Palubu vpravo nahoře.
#------------------------------------------------------------------------------
sub vypsat_pravy_okraj
{
    if($pole{kosik} eq "")
    {
        kraj_obecny();
    }
    else
    {
        kraj_kosik();
    }
}



#------------------------------------------------------------------------------
# Vypíše obecný kraj, když není vybrána konkrétní hra.
#------------------------------------------------------------------------------
sub kraj_obecny
{
    print("            <td align=center valign=top>\n");
    if(length($pole{hra})==3)
    {
        print("<div align=left>\n");
        print(katalog::podobne($databaze, $pole{hra}));
        print("</div>\n");
    }
    kecy::obecne();
    print("            </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše kraj, když je něco v košíku.
#------------------------------------------------------------------------------
sub kraj_kosik
{
    print("            <td valign=top>\n");
    if(length($pole{hra})==3)
    {
        print("<div align=left>\n");
        print(katalog::podobne($databaze, $pole{hra}));
        print("</div>\n");
    }
    print("<h2>Obsah vašeho košíku</h2>\n");
    print(kosik::dopocitat_a_zobrazit($databaze, $pole{kosik}, \%pole, 1));
    print("<h3>Chcete-li do košíku něco přidat, zvolte si hru v&nbsp;levém sloupci. Pokud jste již s&nbsp;obsahem košíku spokojeni, vyplňte prosím následující údaje:</h3>\n");
    # Vytisknout objednávkový formulář.
    print(objednavka::formular(\%pole));
    print("            </td>\n");
}



#------------------------------------------------------------------------------
# Vypíše dobu, po kterou program běžel. K tomu potřebuje dostat časové otisky
# začátku a konce.
#------------------------------------------------------------------------------
sub sestavit_hlaseni_o_trvani_programu
{
    my $starttime = shift;
    my $stoptime = time();
    my $cas = $stoptime-$starttime;
    my $hod = int($cas/3600);
    my $min = int(($cas%3600)/60);
    my $sek = $cas%60;
    my $hlaseni;
    if($hod==0)
    {
        if($min==0)
        {
            $hlaseni = sprintf("Program běžel $sek vteřin%s.\n", $sek==1 ? "u" : $sek>=2 && $sek<=4 ? "y" : "");
        }
        else
        {
            $hlaseni = sprintf("Program běžel %d:%02d minut.\n", $min, $sek);
        }
    }
    else
    {
        $hlaseni = sprintf("Program běžel %2d:%02d:%02d hodin.\n", $hod, $min, $sek);
    }
    return $hlaseni;
}
