#!/usr/bin/perl
# Zobrazí nebo zpracuje přihlašovací formulář.
# Copyright © 2004-2018 Dan Zeman <zeman@ufal.mff.cuni.cz>
# Licence: GNU GPL

# 4.7.2013: organizační tým by nebyl šťastný, kdyby si každý rok nevynutil přeprogramování práce se vstupným a startovným
# 4.7.2014: přidávám možnost zaškrtnout členství v České federaci Zatre

use utf8; # říct Perlu, že konstantní řetězce ve zdrojáku jsou v UTF
use Encode; # funkce pro překódování
use DBI; # spolupráce se serverem MySQL
# Říct Perlu, kde najde Danovy sdílené knihovny.
# CGI skripty běží pod uživatelem apache, který nemá tyto knihovny v cestě.
use lib '/s/w/lib/dan';
use lib '/s/w/lib/cgi/mso';
use dancgi; # čtení parametrů z webu nebo z ARGV
use dzsql; # Danovy funkce pro práci s MySQL
use cas; # práce s daty a časem
use jazyky; # jazykové verze textů
use csort; # jazykově závislé řazení podle abecedy
use mso; # funkce pro generování stránek o olympiádě
binmode(STDOUT, ':utf8'); # říct Perlu, že UTF chceme i na výstupu

###################################################################
# vypnutí a zapnutí přihlášky pomocí proměnné       prihlasovani_otevreno

# Připojit se k databázi.
$databaze = mso::pripojit_se_k_databazi();


# Načíst parametry z URL.
dancgi::cist_parametry(\%konfig);
# Umožnit volat skript z příkazového řádku a předat parametry tam (např. perl partie.pl zdroj=cas).
dancgi::rozebrat_parametry($ARGV[0], \%konfig);
# Načíst formulář.
if($konfig{co} eq 'zpracuj')
{
    dancgi::cist_formular_post(\%konfig);
}
if($konfig{jazyk} eq '')
{
    $konfig{jazyk} = 'cs';
}
$jazyky::jazyk = $konfig{jazyk};
# Vždy se lze přihlásit pouze na jeden ročník: ten nejbližší, který bude, případně
# ten, který právě probíhá. Zjistit, který ročník to je, a přepsat parametr rok,
# ať už tam měl uživatel cokoli.
$ted = cas::ted();
$roky = mso::dotazat_se_databaze($databaze, 'rok', 'konec', 'vcasne_prihlasky_do', 'rocniky ORDER BY rok');
for(my $i = 0; $i<=$#{$roky}; $i++)
{
    $konfig{rok} = $roky->[$i]{rok};
    $konfig{vcas} = $roky->[$i]{vcasne_prihlasky_do};
    if($ted->{eden} <= cas::datum2eden($roky->[$i]{konec}))
    {
        last;
    }
}



if($konfig{co} ne 'zpracuj')
{
    zobrazit_prihlasku($databaze, \%konfig);
}
else
{
    zpracovat_prihlasku($databaze, \%konfig);
}



###############################################################################
# PODPROGRAMY
###############################################################################



#------------------------------------------------------------------------------
# Zobrazí přihláškový formulář.
#------------------------------------------------------------------------------
sub zobrazit_prihlasku
{
    my $databaze = shift;
    my $konfig = shift;
    mso::vypsat_stranku(
    {
        "nazev"  => "MSO: $konfig->{rok}: ".jazyky::zjistit("Prihlaska"),
        "nadpis" => jazyky::zjistit("prihlaska_nadpis", $konfig->{rok}),
#        "telo"   => sestavit_identifikacni_formular($konfig),
        "telo"   => prihlaska($databaze, $konfig),
        "rok"    => $konfig->{rok}
    });
}



#------------------------------------------------------------------------------
# Vypíše první část přihlášky, kterou se uživatel identifikuje systému.
# Identifikace se provádí pomocí jména, příjmení a e-mailové adresy. Pokud
# se zjistí, že uživatel není v databázi, budou následovat další dotazy, aby
# se zjistilo, proč tam není a zda ho máme zavést jako novou osobu.
#------------------------------------------------------------------------------
sub sestavit_identifikacni_formular
{
    ###!!! Tato funkce zatím nevyužívá modul jazyky, takže není dostupná anglicky.
    my $konfig = shift;
    my $html;
    $html .= "<p>Uveďte prosím své základní identifikační údaje.\n";
    $html .= "   Systém se vás podle nich pokusí najít v&nbsp;naší databázi z&nbsp;minulých let,\n";
    $html .= "   nebo vás do databáze přidá. Poté budete mít možnost se přihlásit na jednotlivé turnaje.</p>\n";
    $html .= "<p>Vyplněním a odesláním formuláře nám (Klubu deskových her Paluba) dáváte souhlas, abychom vaše údaje\n";
    $html .= "   elektronicky zpracovávali a uchovávali v&nbsp;míře nezbytně nutné pro\n";
    $html .= "   organizaci turnajů, zveřejňování jejich výsledků a informování jejich účastníků.\n";
    $html .= "   S&nbsp;vaší e-mailovou adresou bude nakládáno jako s&nbsp;citlivým údajem,\n";
    $html .= "   který samozřejmě nezveřejníme v&nbsp;žádném seznamu účastníků ani jinak nepředáme\n";
    $html .= "   třetím osobám. Sami ji můžeme využít k&nbsp;tomu, abychom vás informovali\n";
    $html .= "   o turnajích, na které jste se přihlásili, o festivalu jako takovém\n";
    $html .= "   a případně v&nbsp;budoucnu o dalších podobných akcích. Pokud o informace\n";
    $html .= "   ztratíte zájem, můžete nám souhlas odebrat, když nám napíšete,\n";
    $html .= "   abychom váš e-mail z&nbsp;databáze vyřadili.</p>\n";
    $html .= "<p>Vaše jméno, příjmení, město a zemi považujeme za méně citlivé údaje,\n";
    $html .= "   které vás osobně neidentifikují (ve stejném městě může bydlet i váš jmenovec),\n";
    $html .= "   a hodláme je proto zveřejnit jak na seznamu hráčů přihlášených na určitý turnaj,\n";
    $html .= "   tak později ve výsledkové listině, pokud se turnaje opravdu zúčastníte.</p>\n";

     $html .= "<p>Nezapomeňte navštívit naši stránku <a href=https://www.facebook.com/deskohrani/>Deskohraní na Facebooku.</a></p>\n";

    $html .= "<form method=\"post\" action=\"".mso::url("telo=prihlaska.pl", "co=zpracuj")."\" target=\"_top\">\n";
    $html .= "  <table>\n";
    $html .= "    <tr>\n";
    $html .= "      <td><b>".jazyky::zjistit("krestni_jmeno")."</b><br/><input type=\"text\" name=\"jmeno\" value=\"$konfig->{jmeno}\" size=\"30\"/></td>\n";
    $html .= "      <td><b>".jazyky::zjistit("prijmeni")."</b><br/><input type=\"text\" name=\"prijmeni\" value=\"$konfig->{prijmeni}\" size=\"30\"/></td>\n";
    $html .= "      <td rowspan=\"2\" valign=\"top\">".jazyky::zjistit("prihlaska_diakritika")."</td>\n";
    $html .= "    </tr>\n";
    $html .= "    <tr>\n";
    $html .= "      <td colspan=\"2\"><b>".jazyky::zjistit("email")."</b><br/><input type=\"text\" name=\"email\" value=\"$konfig->{email}\" size=\"67\"/></td>\n";
    $html .= "    </tr>\n";
    $html .= "  </table>\n";
    $html .= "  <p>\n";
    $html .= "    <input type=\"submit\" value=\"".jazyky::zjistit("odeslat")."\"/>\n";
    $html .= "    <input type=\"reset\"  value=\"".jazyky::zjistit("vymazat")."\"/>\n";
    $html .= "  </p>\n";
    $html .= "</form>\n";
    return $html;
}

#------------------------------------------------------------------------------
# Vypíše přihlašovací formulář.
#------------------------------------------------------------------------------
sub prihlaska
{
    my $databaze = shift;
    my $konfig = shift;
    my $stranka;
    # Přečíst tabulku akcí.
    my $akce = mso::nacist_akce($databaze, $konfig->{rok});
    ### Jakub: nastavení parametrů jsem přemístil nahoru, aby se dalo použít dřív.
    ###!!! DOČASNĚ NEZOBRAZOVAT ŽÁDNÉ AKCE, ABY SE NEDALO HLÁSIT, DOKUD NEBUDOU STRÁNKY PŘIPRAVENÉ NA NOVÝ ROČNÍK.
    my $prihlasovani_otevreno = 1;
    ###!!! Výjimka za účelem ladění: IP adresa Zemanových může všechno.
    ###!!! Místo porovnání na rovnost regulární výraz, protože kolem adresy mohou být mezery.
    ###!!! Na novém kubu nefunguje standardní proměnná REMOTE_ADDR, je v ní local 127.0.0.1.
    if(!$prihlasovani_otevreno && $ENV{HTTP_X_REAL_IP} =~ m/91\.201\.20\.97/)
    {
        $prihlasovani_otevreno = 1;
    }
    if(!$prihlasovani_otevreno)
    {
        $stranka .= jazyky::zjistit("prihlaska_uvod_neaktivni");
    }
    # Vypsat formulář přihlášky.
    $stranka .= jazyky::zjistit("prihlaska_uvod", $konfig->{vcas});
    my $parametry = dancgi::sestavit_parametry_odkaz(\%main::konfig, "telo=prihlaska.pl", "co=zpracuj");
    $stranka .= "<form class=\"prihlaska\" method=\"post\" action=\"index.pl?$parametry\">\n";
    $stranka .= "  <table>\n";
    $stranka .= "    <tr>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("krestni_jmeno")."</b><br/><input type=\"text\" name=\"jmeno\"/></td>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("prijmeni")."</b><br/><input type=\"text\" name=\"prijmeni\" /></td>\n";
    $stranka .= "      <td style=\"padding-left:20px\" rowspan=\"3\" valign=\"top\">".jazyky::zjistit("prihlaska_diakritika")."\n";
    $stranka .= "        <p><a href=\"#soukromi\">".jazyky::zjistit("nadpis_soukromi")."</a></p>\n";
    $stranka .= "      </td>\n";
    $stranka .= "    </tr>\n";
    $stranka .= "    <tr>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("obec")."</b><br/><input type=\"text\" name=\"obec\" /></td>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("zeme")."</b><br/>\n";
    $stranka .= "        <select name=\"zeme\">\n";
    # Sestavit seznam zemí na výběr.
    my $nazev_jazyk = jazyky::zjistit("klic_nazev");
    my $pole_zemi = mso::dotazat_se_databaze($databaze, "kod", $nazev_jazyk, "zeme");
    # Seřadit země podle abecedy.
    foreach my $z (@{$pole_zemi})
    {
        $z->{trid} = csort::zjistit_tridici_hodnoty($z->{$nazev_jazyk}, $jazyky::jazyk);
    }
    my @zeme_serazene = map{my $sel = $_->{kod} eq "CZE" ? " selected=\"selected\"" : ""; "          <option value=\"$_->{kod}\"$sel>$_->{$nazev_jazyk}</option>\n"}(sort{$a->{trid} cmp $b->{trid}}(@{$pole_zemi}));
    $stranka .= join("", @zeme_serazene);
    $stranka .= "        </select>\n";
    $stranka .= "      </td>\n";
    $stranka .= "    </tr>\n";
    $stranka .= "    <tr>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("email")."</b><br/><input type=\"text\" name=\"email\"/></td>\n";
    $stranka .= "      <td><b>".jazyky::zjistit("poznamka")."</b><br/><input type=\"text\" name=\"poznamka\" size=\"67\"/></td>\n";
    $stranka .= "    </tr>\n";

    $stranka .= "    <tr>\n";
    $stranka .= "      <td>\n";
    $stranka .= "        <b>".jazyky::zjistit("pohlavi")."</b><br/>\n";
    $stranka .= "        <input type=\"radio\" name=\"pohlavi\" value=\"muž\"/> ".jazyky::zjistit("muz")."<br/>\n";
    $stranka .= "        <input type=\"radio\" name=\"pohlavi\" value=\"žena\"/> ".jazyky::zjistit("zena")."\n";
    $stranka .= "      </td>\n";
    $stranka .= "      <td>\n";
    $stranka .= "        <b>".jazyky::zjistit("kategorie")."</b><br/>\n";
    $stranka .= "        <input type=\"radio\" name=\"kategorie\" value=\"dítě\"/> ".jazyky::zjistit("dite")."<br/>\n";
    $stranka .= "        <input type=\"radio\" name=\"kategorie\" value=\"student, důchodce\"/> ".jazyky::zjistit("student")."<br/>\n";
    $stranka .= "        <input type=\"radio\" name=\"kategorie\" value=\"normální\" checked=\"checked\"/> ".jazyky::zjistit("dospely")."<br/>\n";
    $stranka .= "      </td>\n";
    $stranka .= "      <td>\n";
    $stranka .= "        <b>".jazyky::zjistit("clenstvi")."</b><br/>\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clenpaluba\"   value=\"1\"/>&nbsp;Duha&nbsp;DĚSÍR\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clenscrabble\" value=\"1\"/>&nbsp;ČAS\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clendama\"     value=\"1\"/>&nbsp;ČFD\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clendama2\"    value=\"1\"/>&nbsp;ČUD<br />\n"; # Když nezalomíme řádek natvrdo, udělá to Firefox klidně tam, kde je &nbsp;!
    $stranka .= "        <input type=\"checkbox\" name=\"clengo\"       value=\"1\"/>&nbsp;ČAGo\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clenothello\"  value=\"1\"/>&nbsp;ČFO\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clenzatre\"    value=\"1\"/>&nbsp;ČFZ\n";
    $stranka .= "        <input type=\"checkbox\" name=\"clenhadanka\"  value=\"1\"/>&nbsp;SČHaK\n";
    $stranka .= "      </td>\n";
    $stranka .= "    </tr>\n";
    $stranka .= "  </table>\n";

    my $parametry = dancgi::sestavit_parametry_odkaz($konfig, "telo=propozice.pl", "hra=pet", "turnaj=oly");
    $stranka .= jazyky::zjistit("prihlaska_prohlaseni", $parametry);
    # Na přihlášce seřadit akce podle názvu hry a akce.
    @{$akce} = sort
    {
        my $vysledek = $a->{_nazev_hry_tridici} cmp $b->{_nazev_hry_tridici};
        unless($vysledek)
        {
            $vysledek = $a->{_nazev_akce_tridici} cmp $b->{_nazev_akce_tridici};
        }
        return $vysledek;
    }
    (@{$akce});
    $stranka .= "  <table border=\"0\">\n";
    # Vypsat akce, na které se přijímají přihlášky předem.
    # Vynechat volitelné turnaje, akce pro kvalifikované a vůbec akce, které vyžadují zvláštní zpracování.
    foreach my $a (@{$akce})
    {
        if($a->{prihlasky} =~ m/^(předem|možné)$/)
        {
            # Zablokovat přihlašování na akce, u nichž byla naplněna nebo překročena kapacita.
            my $disabled = "";
            my $sql = "SELECT kapacita FROM akce WHERE (rok = '$konfig->{rok}') AND (kod_hry = '$a->{kod_hry}') AND (kod_turnaje = '$a->{kod_turnaje}');";
            my $dtz = $databaze->prepare($sql);
            $dtz->execute();
            my @radek = $dtz->fetchrow_array();
            my $kapacita = $radek[0];
            my $pocet;
            # Nulová kapacita znamená neomezená kapacita.
            if($kapacita>0)
            {
                ###!!! Seznam přihlášených bych si měl na začátku načíst jen jednou pro všechny akce a duplikáty bych měl odstraňovat taky jen jednou.
                # Nechat si spočítat přihlášené pomocí SQL by bylo složité, protože přihlášky jsou uložené ve dvou různých
                # tabulkách a druhá tabulka může obsahovat duplikáty záznamů z té první i svých vlastních.
                # Načíst přihlášky vyexportované z Accessu.
                my $prihlasky = mso::dotazat_se_databaze($databaze, "jmeno", "prijmeni", "rok", "kod_hry", "kod_turnaje", "prihlasky WHERE (rok = '$konfig->{rok}') AND (kod_hry = '$a->{kod_hry}') AND (kod_turnaje = '$a->{kod_turnaje}')");
                # Načíst přihlášky, které ještě v Accessu nejsou, ale přihlašovací skript je uložil do MySQL.
                my $prihlasky1 = mso::dotazat_se_databaze($databaze, "jmeno", "prijmeni", "rok", "kod_hry", "kod_turnaje", "prihlasky_auto AS prihlasky INNER JOIN osoby_auto ON prihlasky.datum_prihlasky = osoby_auto.cas_odeslani_access WHERE (rok = '$konfig->{rok}') AND (kod_hry = '$a->{kod_hry}') AND (kod_turnaje = '$a->{kod_turnaje}')");
                # Nahashovat si přihlášky z Accessu (neměly by obsahovat duplikáty).
                my %duplikaty;
                foreach my $prihlaska (@{$prihlasky})
                {
                    my $klic = $prihlaska->{jmeno}." ".$prihlaska->{prijmeni}." ".$prihlaska->{kod_hry}.$prihlaska->{kod_turnaje};
                    $duplikaty{$klic}++;
                    $pocet++;
                }
                # Přidat automatické přihlášky, které nejsou duplikáty.
                foreach my $prihlaska (@{$prihlasky1})
                {
                    my $klic = $prihlaska->{jmeno}." ".$prihlaska->{prijmeni}." ".$prihlaska->{kod_hry}.$prihlaska->{kod_turnaje};
                    $duplikaty{$klic}++;
                    if($duplikaty{$klic}==1)
                    {
                        push(@{$prihlasky}, $prihlaska);
                        $pocet++;
                    }
                }
                $disabled = " disabled=\"disabled\"" if($pocet>=$kapacita);
            }
            my $nazev_jazyk = jazyky::zjistit("klic_nazev");
            if($prihlasovani_otevreno)
            {
                $stranka .= "    <tr><td valign=\"bottom\">$a->{_nazev_hry}: </td>";
                $stranka .= "<td valign=\"bottom\"><input type=\"checkbox\" name=\"turn$konfig->{rok}$a->{kod_hry}$a->{kod_turnaje}\" ";
                $stranka .= "value=\"$a->{$nazev_jazyk}\"$disabled/> $a->{_nazev_odkaz_propozice} ($pocet/$kapacita)</td>";
                my $cas = $a->{zacatek};
                $cas =~ s/:00$//; # umazat vteřiny začátku
                $cas .= ' &ndash; ';
                $cas .= $a->{konec};
                $cas =~ s/:00$//; # umazat vteřiny konce
                # Umazat datum konce, jestliže se shoduje s datem začátku.
                $cas =~ s/(\d+\.\d+\.\d+ )(\d+:\d+ &ndash; )\1/$1$2/;
                $cas =~ s/ /&nbsp;/g; # zakázat zalomení řádku
                $stranka .= "<td align=\"right\" valign=\"bottom\" style='text-align:right'>$cas</td>";
                $stranka .= "</tr>\n";
            }
        }
    }
    $stranka .= "  </table>\n";
    # Volitelné akce: zjistit, jaké skupiny volitelných akcí existují.
    my %skupiny;
    foreach my $a (@{$akce})
    {
        if($a->{prihlasky} =~ m/^volitelny(\d+)$/)
        {
            $skupiny{$1}++;
        }
    }
    my @skupiny = sort {$a <=> $b} keys(%skupiny);
    # Vypsat volitelné akce.
    if(@skupiny)
    {
        $stranka .= "  <h2>".jazyky::zjistit("prihlaska_volitelne_discipliny")."</h2>\n";
        $stranka .= "  <p>".jazyky::zjistit("prihlaska_vol_vysvetleni")."</p>\n";
        foreach my $skupina (@skupiny)
        {
            $stranka .= "  <h2>".jazyky::zjistit("prihlaska_volitelna_disciplina")." $skupina</h2>\n";
            $stranka .= "  <table border=\"0\">\n";
            $stranka .= "    <tr>\n";
            $stranka .= "      <th>".jazyky::zjistit("prihlaska_vol_akce")."</th>\n";
            $stranka .= "      <th>".jazyky::zjistit("prihlaska_vol_volim_prijdu")."</th>\n";
            $stranka .= "      <th>".jazyky::zjistit("prihlaska_vol_nevolim_prijdu")."</th>\n";
            $stranka .= "      <th>".jazyky::zjistit("prihlaska_vol_neprijdu")."</th>\n";
            $stranka .= "    </tr>\n";
            foreach my $a (@{$akce})
            {
                if($a->{prihlasky} eq "volitelny$skupina")
                {
                    $stranka .= "    <tr>\n";
                    $stranka .= "      <td valign=\"bottom\">$a->{_nazev_odkaz_propozice}</td>\n";
                    $stranka .= "      <td valign=\"bottom\"><input type=\"radio\" name=\"turn$konfig->{rok}$a->{kod_hry}$a->{kod_turnaje}\" value=\"$a->{$nazev_jazyk} = 2\"/></td>\n";
                    $stranka .= "      <td valign=\"bottom\"><input type=\"radio\" name=\"turn$konfig->{rok}$a->{kod_hry}$a->{kod_turnaje}\" value=\"$a->{$nazev_jazyk} = 1\"/></td>\n";
                    $stranka .= "      <td valign=\"bottom\"><input type=\"radio\" name=\"turn$konfig->{rok}$a->{kod_hry}$a->{kod_turnaje}\" value=\"$a->{$nazev_jazyk} = 0\"/></td>\n";
                    $stranka .= "    </tr>\n";
                }
            }
            $stranka .= "  </table>\n";
        }
    }
    # Vypsat akce, do kterých se můžou přihlásit pouze kvalifikovaní.
    $stranka .= "  ".jazyky::zjistit("prihlaska_prohlaseni_registrace");
    if($prihlasovani_otevreno)
    {
        $stranka .= "  <table border=\"0\">\n";
        foreach my $a (@{$akce})
        {
            if($a->{"prihlasky"} eq "kvalifikovaní registrace")
            {
                my $nazev_jazyk = jazyky::zjistit("klic_nazev");
                $stranka .= "    <tr><td valign=\"bottom\">$a->{_nazev_hry}: </td>";
                $stranka .= "<td valign=\"bottom\"><input type=\"checkbox\" name=\"turn$konfig->{rok}$a->{kod_hry}$a->{kod_turnaje}\" ";
                $stranka .= "value=\"$a->{$nazev_jazyk}\"/> $a->{_nazev_odkaz_propozice}</td></tr>\n";
            }
        }
        $stranka .= "  </table>\n";
    }
    # Přidat možnost započítat vstupné na festival.
    $stranka .= '  '.jazyky::zjistit('prihlaska_prohlaseni_vstupne');
    $stranka .= "  <table border=\"0\">\n";
    # Vstupné na festival je vedeno jako zvláštní akce v tabulce akcí.
    my @ludakce = sort {$a->{kod_turnaje} cmp $b->{kod_turnaje}} (grep {$_->{kod_hry} eq 'lud'} (@{$akce}));
    foreach my $la (@ludakce)
    {
        if($la->{kod_turnaje} =~ m/^l0*(\d+)$/ && $la->{startovne}>0)
        {
            my $den = $1;
            my $datum = $la->{zacatek};
            # Umazat čas začátku.
            if($datum =~ m/^(\d+\.\d+\.\d+)\s+\d+:\d+:\d+$/)
            {
                $datum = $1;
            }
            $stranka .= "    <tr><td><input type=\"checkbox\" name=\"vstup$den\" value=\"$den\" />$datum</td></tr>\n";
        }
    }
    $stranka .= "  </table>\n";
    $stranka .= "  <p><input type=\"checkbox\" name=\"chce_platit_predem\" value=\"1\" /> ".jazyky::zjistit('prihlaska_chci_predem', $konfig->{vcas})."</p>\n";



    # Přidat parametry, které uživatele nezajímají, ale my je potřebujeme.
    $stranka .= "  <input type=\"hidden\" name=\"jazyk\"  value=\"$jazyky::jazyk\"/>\n";
    $stranka .= "  <input type=\"hidden\" name=\"co\"     value=\"zpracuj\"/>\n";
    my $cas = cas::ted()->{rmdhms};
    $stranka .= "  <input type=\"hidden\" name=\"casgen\" value=\"$cas\"/>\n";
    # Přidat tlačítka pro odeslání nebo vymazání formuláře.
    $stranka .= "  <p>\n";
    my $disabled = $prihlasovani_otevreno ? '' : ' disabled';
    $stranka .= "    <input type=\"submit\" value=\"".jazyky::zjistit("odeslat")."\"$disabled />\n";
    $stranka .= "    <input type=\"reset\"  value=\"".jazyky::zjistit("vymazat")."\"/>\n";
    $stranka .= "  </p>\n";
    $stranka .= "</form>\n";

    $stranka .= "      <a href=\"#\" name=\"soukromi\"></a><h3 id=\"soukromi\">".jazyky::zjistit("nadpis_soukromi")."</h3>\n";
    $stranka .= "      <p>".jazyky::zjistit("prihlaska_soukromi")."</p>\n";

    return $stranka;
}



#==============================================================================
# Funkce pro zpracování vyplněné přihlášky
#==============================================================================



#------------------------------------------------------------------------------
# Zkontroluje údaje na přihlášce, uloží je do databáze, pošle je e-mailem
# organizátorům a uživateli vygeneruje odpověď.
#------------------------------------------------------------------------------
sub zpracovat_prihlasku
{
    my $databaze = shift;
    my $konfig = shift;
    # Údaje s přihláškou jsou v hashi %{$konfig} pohromadě s případnými dalšími
    # parametry skriptu. Přidat mezi údaje datum a čas odeslání přihlášky.
    $konfig->{casode} = cas::ted()->{rmdhms};
    # Klárka ještě potřebuje čas odeslání přihlášky ve formátu shodném s Accessem.
    if($konfig->{casode} =~ m/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/)
    {
        $konfig->{cas_odeslani_access} = sprintf("%d.%d.%d %d:%02d:%02d", $3, $2, $1, $4, $5, $6);
    }
    # Variabilní symbol je stejný jako čas odeslání přihlášky, akorát se na začátku
    # musí umazat rok, aby symbol neměl 14 číslic, ale jen 10.
    $konfig->{vs} = $konfig->{casode};
    $konfig->{vs} =~ s/^\d\d\d\d//;
    # Zkontrolovat přihlášku.
    my $chyby = zkontrolovat_prihlasku($databaze, $konfig);
    # Pokud byla kontrola úspěšná, uložit údaje do databáze a odeslat je e-mailem organizátorům.
    unless(scalar(@{$chyby}))
    {
        ulozit_prihlasku_do_databaze($databaze, $konfig);
        odeslat_prihlasku_e_mailem($databaze, $konfig);
    }
    # Vygenerovat odpověď pro uživatele.
    zobrazit_potvrzovaci_stranku($databaze, $konfig, $chyby);
}



#------------------------------------------------------------------------------
# Zkontroluje údaje z přihlášky a vrátí seznam chyb, které najde.
#------------------------------------------------------------------------------
sub zkontrolovat_prihlasku
{
    my $databaze = shift;
    my $konfig = shift;
    my @chyby;
    # Odstranit z křestního jména přebytečné mezery.
    $konfig->{jmeno} =~ s/^\s+//;
    $konfig->{jmeno} =~ s/\s+$//;
    $konfig->{jmeno} =~ s/\s+/ /g;
    # Zkontrolovat, že křestní jméno není prázdné.
    if($konfig->{jmeno} eq "")
    {
        push(@chyby, "chyba_jmeno");
    }
    # Rozdělit křestní jméno na slova, u každého zajistit první písmeno velké a ostatní malá.
    $konfig->{jmeno} = join(" ", map{m/^(von|van|de[rn]?|d[ia])$/ ? $_ : ucfirst(lc($_))}(split(/\s+/, $konfig->{jmeno})));
    # Odstranit z příjmení přebytečné mezery.
    $konfig->{prijmeni} =~ s/^\s+//;
    $konfig->{prijmeni} =~ s/\s+$//;
    $konfig->{prijmeni} =~ s/\s+/ /g;
    # Zkontrolovat, že příjmení není prázdné.
    if($konfig->{prijmeni} eq "")
    {
        push(@chyby, "chyba_prijmeni");
    }
    # Rozdělit příjmení na slova, u každého zajistit první písmeno velké a ostatní malá.
    $konfig->{prijmeni} = join(" ", map{m/^(von|van|de[rn]?|d[ia]|[yi])$/ ? $_ : ucfirst(lc($_))}(split(/\s+/, $konfig->{prijmeni})));
    # Odstranit z obce přebytečné mezery.
    $konfig->{obec} =~ s/^\s+//;
    $konfig->{obec} =~ s/\s+$//;
    $konfig->{obec} =~ s/\s+/ /g;
    # Zkontrolovat, že obec není prázdná.
    if($konfig->{obec} eq "")
    {
        push(@chyby, "chyba_obec");
    }
    # Rozdělit obec na slova, u každého zajistit první písmeno velké a ostatní malá.
    $konfig->{obec} = join(" ", map{m/^(nad|pod|u|v|na|pri|am|an|der|de|da|di|sur)$/ ? $_ : ucfirst(lc($_))}(split(/\s+/, $konfig->{obec})));
    # Neumožnit obec typu "Praha 3". Zatím jen výčtem, i když by možná šlo zcela zakázat číslice v názvu obce.
    $konfig->{obec} =~ s/^(Praha|Brno|Ostrava|Plzeň|Kladno)\s*\d+.*/$1/;
    # Odstranit z e-mailu přebytečné mezery.
    $konfig->{email} =~ s/^\s+//;
    $konfig->{email} =~ s/\s+$//;
    # E-mail musí vypadat jako běžný e-mail, tj. např. musí obsahovat zavináč a na konci musí být dva znaky nebo vyjmenované domény.
    # Generické domény nejvyššího řádu jsem zjišťoval 24.9.2008 podle Wikipedie (cs:Doména nejvyššího řádu).
    if($konfig->{email} !~ m/(\w|[-\._])+\@(\w|[-\._])+\.(\w\w|aero|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|travel)$/i)
    {
        push(@chyby, "chyba_email");
    }
    # Převést e-mailovou adresu na malá písmena.
    $konfig->{email} = lc($konfig->{email});
    # Zkontrolovat, že pohlaví má povolené hodnoty.
    if($konfig->{pohlavi} !~ m/^(muž|žena)$/)
    {
        push(@chyby, "chyba_pohlavi");
    }
    # Kvůli ověřování a doplňování údajů načíst seznam akcí na daný rok z databáze.
    my $dbakce = mso::dotazat_se_databaze($databaze, 'rok', 'kod_hry', 'kod_turnaje', jazyky::zjistit('klic_nazev'), 'prihlasky', 'zacatek', 'konec', 'konec_kolize', 'plus_vstup', 'startovne', 'startovne_2', 'startovne_3', "akce WHERE rok = '$konfig->{rok}'");
    # Nahašovat databázové akce podle kódu hry a turnaje.
    my %dbakce;
    foreach my $dba (@{$dbakce})
    {
        $dbakce{$dba->{kod_hry}}{$dba->{kod_turnaje}} = $dba;
    }
    # Sestavit seznam akcí, na které se uživatel přihlásil.
    my @akce;
    # Vybudovat si také seznam her, aby se daly dát na začátek mailu pro rychlou informaci.
    my %prihlasene_hry;
    my $celkem_startovne = 0;
    while(my ($klic, $hodnota) = each (%{$konfig}))
    {
        # Zaškrtávátka jednotlivých soutěží mají identifikátor začínající na "turn"
        # a pokračující rokem, kódem hry a kódem turnaje.
        if ($klic =~ m/^turn$konfig->{rok}(\w\w\w)(\w\w\w)/)
        {
            my $hra = $1;
            my $turnaj = $2;
            # Ověřit v databázi, že takový turnaj existuje.
            # (Pokud by neexistoval, je to buď chyba naší aplikace, nebo klient manipuloval s naším formulářem.)
            if(!exists($dbakce{$hra}{$turnaj}))
            {
                push(@chyby, 'chyba_kod_akce');
            }
            # U volitelných turnajů dále zjistit, jaký hlas osoba turnaji dala.
            my $volitelny_turnaj = -1;
            if($dbakce{$hra}{$turnaj}{prihlasky} =~ m/^volitelny(\d+)$/)
            {
                if($hodnota =~ m/^(.*) = ([012])$/)
                {
                    $hodnota = $1;
                    $volitelny_turnaj = $2;
                }
                # Hráč se může k volitelnému turnaji nevyjádřit, ale pak by se tu kód turnaje neměl vůbec objevit.
                # Pokud se objevil, ale z hodnoty není poznat hráčova volba, něco je špatně.
                if($volitelny_turnaj==-1)
                {
                    push(@chyby, 'chyba_hlas_volitelnemu_turnaji');
                }
            }
            # Zjistit, jaké startovné tato osoba za tuto akci platí.
            my $startovne = mso::zjistit_startovne($databaze, $konfig->{rok}, $hra, $turnaj, $konfig->{kategorie}, $konfig);
            $startovne = 0 if(volna_vstupenka($konfig->{email}));
            $celkem_startovne += $startovne;
            push(@akce,
            {
                'rok' => $konfig->{rok},
                'hra' => $hra,
                'turnaj' => $turnaj,
                'nazev' => $hodnota,
                'startovne' => $startovne,
                'plus_vstup' => $dbakce{$hra}{$turnaj}{plus_vstup},
                'zacatek' => $dbakce{$hra}{$turnaj}{zacatek},
                'konec' => $dbakce{$hra}{$turnaj}{konec_kolize}, # konec si ukládáme pouze kvůli kontrole kolizí
                'volitelny_turnaj' => $volitelny_turnaj
            });
            # Zapamatovat si kód hry, pod kterou tato akce patří.
            $prihlasene_hry{$hra}++;
        }
    }
    # Za každý den, ve kterém má zapsaný aspoň jeden turnaj, započítat vstupné na festival.
    # Od roku 2013 se to nově považuje za (a prezentuje jako) součást startovného na turnaj, abychom nerozčilovali hráče, kteří nechtějí do Ludotéky.
    # Druhý a další turnaj ve stejném dni tedy vlastně dostane slevu oproti deklarovanému startovnému.
    # Udělat si přehled dnů a výše vstupného.
    my %dny;
    foreach my $ludokod (keys(%{$dbakce{'lud'}}))
    {
        my $la = $dbakce{'lud'}{$ludokod};
        ###!!! Asi bychom mohli volat funkci mso::zjistit_startovne() stejně jako u normálních akcí nahoře.
        my $vstupne = $konfig->{kategorie} eq 'dítě' ? $la->{startovne_3} : $konfig->{kategorie} eq 'student, důchodce' ? $la->{startovne_2} : $la->{startovne};
        my $den = 0;
        if($ludokod =~ m/^l0*(\d+)$/)
        {
            $den = $1;
        }
        $dny[$den]{akce} = $la;
        # Se dny, kdy je vstupné zdarma pro všechny, budeme zacházet jinak.
        # Poznamenat si to zvlášť a nespoléhat na položku vstupne, protože tu třeba chceme vynulovat kvůli volné vstupence.
        $dny[$den]{zdarma} = $vstupne==0;
        $dny[$den]{vstupne} = volna_vstupenka($konfig->{email}) ? 0 : $vstupne;
    }
    # Zjistit seznam dnů, ve kterých hodlá být na festivalu.
    my $celkem_startovne_pred_slevou = 0;
    foreach my $akce (@akce)
    {
        $akce->{startovne_pred_slevou} = $akce->{startovne};
        if($akce->{plus_vstup} && $akce->{zacatek} =~ m/^\s*(\d+)\.\d+\.\d{4}/)
        {
            # U vícedenních turnajů připočítáváme vstupné pouze za první den turnaje.
            # V dalších dnech dostane hráč vstupné na festival zdarma.
            my $den = $1;
            $dny[$den]{pritomen}++;
            $akce->{startovne_pred_slevou} += $dny[$den]{vstupne};
            unless($dny[$den]{zaplaceno})
            {
                $akce->{startovne} += $dny[$den]{vstupne};
                $celkem_startovne += $dny[$den]{vstupne};
                $dny[$den]{zaplaceno}++;
            }
        }
        $celkem_startovne_pred_slevou += $akce->{startovne_pred_slevou};
    }
    # Kromě toho si hráč mohl nechat započíst vstupné na dny, ve kterých žádný turnaj nehraje.
    while(my ($klic, $hodnota) = each (%{$konfig}))
    {
        # Zaškrtávátka vstupných na jednotlivé dny začínají na 'vstup'.
        if($klic =~ m/^vstup(\d+)/)
        {
            my $den = $1;
            $dny[$den]{pritomen}++;
        }
    }
    # Za všechny dny, kdy bude na festivalu, přidat zvláštní akci, která bude vidět na potvrzovací stránce, v e-mailu a v databázi.
    # Je jedno, zda jde o den, kdy hráčova přítomnost vyplývá z účasti na turnaji, nebo zda si zvlášť zaškrtnul Ludotéku.
    # A je jedno, zda mu vstupné vyjde nulové, protože už je započítáno ve startovném na turnaj.
    # Neobjeví se zde pouze dny, kdy je vstupné zdarma pro všechny (obvykle pondělí až středa).
    foreach my $den (@dny)
    {
        next if($den->{zdarma});
        next unless($den->{pritomen});
        my $la = $den->{akce};
        my $startovne_po_sleve;
        if($den->{zaplaceno})
        {
            $startovne_po_sleve = 0;
        }
        else # dosud nezaplaceno
        {
            $startovne_po_sleve = $den->{vstupne};
            $celkem_startovne += $den->{vstupne};
            $den->{zaplaceno}++;
        }
        push(@akce,
        {
            'rok' => $konfig->{rok},
            'hra' => 'lud',
            'turnaj' => $la->{kod_turnaje},
            'nazev' => $la->{jazyky::zjistit('klic_nazev')},
            'startovne_pred_slevou' => $den->{vstupne},
            'startovne' => $startovne_po_sleve,
            'zacatek' => $la->{zacatek},
            'konec' => $la->{konec_kolize},
            'volitelny_turnaj' => -1
        });
        $celkem_startovne_pred_slevou += $den->{vstupne};
    }
    # Uložit získané seznamy zpět do konfigu, budou se hodit pozdějším funkcím.
    $konfig->{_akce} = \@akce;
    $konfig->{_hry} = \%prihlasene_hry;
    $konfig->{_dny} = \%dny;
    $konfig->{_celkem_startovne} = $celkem_startovne;
    $konfig->{_celkem_startovne_pred_slevou} = $celkem_startovne_pred_slevou;
    # Zkontrolovat, že se přihlásil alespoň na jednu akci.
    if(scalar(@akce)==0)
    {
        push(@chyby, "chyba_zadne_akce");
    }
    # Zkontrolovat, zda se nepřihlásil na akce, které se překrývají.
    my @akce_ktere_se_nesmi_prekryvat = grep {$_->{hra} ne 'lud'} (@akce);
    my $prekryvy = zkontrolovat_prekryv_akci(\@akce_ktere_se_nesmi_prekryvat);
    if(scalar(@{$prekryvy})>0)
    {
        push(@chyby, 'chyba_prekryv_akci');
        $konfig->{_prekryvy} = $prekryvy;
    }
    # Zkusit zjistit databázový kód osoby, pokud už ji známe z dřívějška.
    my $osoby = mso::dotazat_se_databaze($databaze, 'kod', 'jmeno', 'prijmeni', "osoby WHERE (jmeno = '$konfig->{jmeno}') AND (prijmeni = '$konfig->{prijmeni}')");
    my @kody = map{$_->{kod}}(@{$osoby});
    $konfig->{_kody} = \@kody;
    return \@chyby;
}



#------------------------------------------------------------------------------
# Projde seznam akcí a zkontroluje, zda seznam neobsahuje dvě nebo více akcí,
# které se překrývají v čase. Díky tomu budeme moci varovat hráče, který se
# přihlásil na kolidující akce.
#------------------------------------------------------------------------------
sub zkontrolovat_prekryv_akci
{
    my $seznam = shift;
    # Převést všechny časové údaje na celá čísla, která můžeme porovnávat.
    foreach my $akce (@{$seznam})
    {
        $akce->{ezacatek} = cas::datumcas2esek($akce->{zacatek});
        $akce->{ekonec} = cas::datumcas2esek($akce->{konec});
    }
    # Porovnat každé dvě akce a najít překryvy.
    my @prekryvy;
    for(my $i = 0; $i<=$#{$seznam}; $i++)
    {
        for(my $j = 0; $j<=$#{$seznam}; $j++)
        {
            if($i!=$j)
            {
                # Zajímají nás případy, kdy akce j začíná později než akce i (opačné případy potkáme, až se indexy i a j prohodí).
                # Pokud obě akce začínají ve stejnou chvíli, budeme požadovat, aby kód akce j byl v abecedě až po kódu akce i.
                # Na abecední pořadí se díváme proto, abychom tentýž překryv nehlásili dvakrát při pohledu z různých stran.
                my $ai = $seznam->[$i];
                my $aj = $seznam->[$j];
                if($aj->{ezacatek}>$ai->{ezacatek} || $aj->{ezacatek}==$ai->{ezacatek} && $aj->{hra}.$aj->{turnaj} gt $ai->{hra}.$ai->{turnaj})
                {
                    # Jestliže akce i neskončila nejpozději ve chvíli, kdy akce j začala, máme tu překryv.
                    if($aj->{ezacatek}<$ai->{ekonec})
                    {
                        push(@prekryvy, [$ai, $aj]);
                    }
                }
            }
        }
    }
    return \@prekryvy;
}



#------------------------------------------------------------------------------
# Podle e-mailové adresy řekne, zda se má dané osobě vynulovat startovné a/nebo
# vstupné.
#------------------------------------------------------------------------------
sub volna_vstupenka
{
    my $email = shift;
    my @vyvoleni =
    (
        'j@kub.cz',
        'zeman@ufal.mff.cuni.cz',
        'klara@hrejsi.cz',
        'zemanovi@hrejsi.cz',
        'zuzanka@hrejsi.cz',
        'lucinka@hrejsi.cz',
    );
    return (grep {$email eq $_} (@vyvoleni)) ? 1 : 0;
}



#------------------------------------------------------------------------------
# Uloží údaje z přihlášky do databáze MySQL na serveru. Osobní údaje putují do
# tabulky osoby_auto. Údaje o přihláškách (propojení osoby s akcemi) putují do
# tabulky prihlasky_auto.
#------------------------------------------------------------------------------
sub ulozit_prihlasku_do_databaze
{
    my $databaze = shift;
    my $konfig = shift;
    # Před uložením data upravit.
    # Přejmenovat položku cas_odeslani_access na datum_prihlasky.
    $konfig->{datum_prihlasky} = $konfig->{cas_odeslani_access};
    # Údaje o členství nemohou být prázdné řetězce, ale mohou to být nuly.
    foreach my $klub ('paluba', 'scrabble', 'dama', 'dama2', 'go', 'othello', 'zatre', 'hadanka')
    {
        if($konfig->{"clen".$klub} eq "")
        {
            $konfig->{"clen".$klub} = 0;
        }
    }
    # Přidat základní informace o osobě do tabulky osoby_auto.
    my @nazvy = qw(datum_prihlasky jmeno prijmeni obec zeme pohlavi kategorie clenpaluba clenscrabble clendama clendama2 clengo clenothello clenzatre clenhadanka email poznamka cas_odeslani_access vs _celkem_startovne chce_platit_predem);
    my $seznam_poli = join(", ", @nazvy);
    # Řetězcové hodnoty musí být v apostrofech, číselné bez apostrofů.
    # A pozor, chce_platit_predem může být 1 nebo 0, ale ne prázdný řetězec!
    $konfig->{chce_platit_predem} = 0 unless($konfig->{chce_platit_predem});
    my @hodnoty = map{encode("utf8", m/(clen|_celkem_startovne|chce_platit_predem)/ ? $konfig->{$_} : "'$konfig->{$_}'")}(@nazvy);
    my $seznam_hodnot = join(", ", @hodnoty);
    my $dotaz = "INSERT INTO osoby_auto ($seznam_poli) VALUES ($seznam_hodnot);";
    dzsql::do_or_mail($databaze, $dotaz, 'zemanovi@hrejsi.cz');
    open(LOG, ">>prihlasky.log");
    print LOG ("$dotaz\n");
    print LOG ("$DBI::errstr\n");
    # Přidat informace o jednotlivých přihláškách na akce do tabulky prihlasky_auto.
    foreach my $a (@{$konfig->{_akce}})
    {
        # Může se stát, že v databázi je startovné prázdný řetězec (ne nula). To by způsobilo chybu v syntaxi SQL.
        $a->{startovne} = 0 if($a->{startovne} eq "");
        # Připravit hash s daty do databáze.
        my %data =
        (
            "datum_prihlasky" => $konfig->{cas_odeslani_access},
            "rok" => $a->{rok},
            "kod_hry" => $a->{hra},
            "kod_turnaje" => $a->{turnaj},
            "ma_dati" => $a->{startovne},
            "volitelny_turnaj" => $a->{volitelny_turnaj},
        );
        @nazvy = keys(%data);
        $seznam_poli = join(", ", @nazvy);
        # Řetězcové hodnoty musí být v apostrofech, číselné bez apostrofů.
        @hodnoty = map{$_ =~ m/(rok|ma_dati|volitelny_turnaj)/ ? $data{$_} : "'$data{$_}'"}(@nazvy);
        $seznam_hodnot = join(", ", @hodnoty);
        $dotaz = "INSERT INTO prihlasky_auto ($seznam_poli) VALUES ($seznam_hodnot);";
        dzsql::do_or_mail($databaze, $dotaz, 'zemanovi@hrejsi.cz');
        print LOG ("$dotaz\n");
        print LOG ("$DBI::errstr\n");
    }
    close(LOG);
}



#------------------------------------------------------------------------------
# Odešle údaje z přihlášky e-mailem organizátorům.
# Kopie se pošle i přihlášenému, ale e-mail je vždy česky, nelokalizuje se.
#------------------------------------------------------------------------------
sub odeslat_prihlasku_e_mailem
{
    my $databaze = shift;
    my $konfig = shift;
    my $sendmail;
    if(-e "/usr/lib/sendmail")
    {
        $sendmail = "|/usr/lib/sendmail -oi -t";
    }
    else
    {
        $sendmail = ">posledni-prihlaska.txt";
    }
    my $adresat = 'info@deskohrani.cz';
    my $kopie = $konfig->{email};
    # Kopie přihlášek na scrabblové akce posílat Daně Kučové.
    if(grep{$_->{hra} eq "scr"}(@{$konfig->{_akce}}))
    {
        $kopie .= ", dana.kucova\@volny.cz";
    }
    # V předmětu zprávy chceme mít jméno přihlášeného. Protože je ale mnohem
    # obtížnější zajistit správné zobrazení diakritiky v předmětu, raději diakritiku odstraníme.
    my $jmeno_subject = "$konfig->{jmeno} $konfig->{prijmeni}";
    $jmeno_subject =~ tr/ÁČĎÉĚÍŇÓŘŠŤÚŮÝŽáčďéěíňóřšťúůýžß/ACDEEINORSTUUYZacdeeinorstuuyzs/;
    $jmeno_subject = encode("ascii", $jmeno_subject);
    my $mail;
    $mail .= "From: Robot Hrejsi <robot\@hrejsi.cz>\n";
    $mail .= "Reply-to: \"$jmeno_subject\" <$konfig->{email}>\n";
    $mail .= "To: $adresat\n";
    $mail .= "Cc: $kopie\n" if($kopie ne "");
    $mail .= "Subject: MSO prihlaska: $jmeno_subject\n";
    $mail .= "Content-Type: text/plain; charset=\"utf-8\"\n";
    $mail .= "Content-Transfer-Encoding: 8bit\n\n";
    # Sestavit tělo zprávy.
    $mail .= join(", ", sort(keys(%{$konfig->{_hry}})))."\n\n";
    # Pokud se nám podařilo najít osobu toho jména v databázi, vypsat příslušný kód (kódy).
    if(scalar(@{$konfig->{_kody}}))
    {
        $mail .= "Kód: ".join(", ", @{$konfig->{_kody}})."\n";
    }
    $mail .= "Jméno: $konfig->{jmeno} $konfig->{prijmeni}\n";
    $mail .= "Obec: $konfig->{obec} \n";
    $mail .= "Země: $konfig->{zeme} \n";
    $mail .= "Pohlaví: $konfig->{pohlavi} \n";
    $mail .= "Kategorie: $konfig->{kategorie} \n";
    # Připsat organizace, jichž je členem, ostatní neuvádět.
    foreach my $clen ('paluba', 'scrabble', 'dama', 'dama2', 'go', 'othello', 'zatre', 'hadanka')
    {
        if($konfig->{'clen'.$clen})
        {
            $mail .= "Člen $clen: 1\n";
        }
    }
    $mail .= "E-mail: $konfig->{email} \n";
    $mail .= "Poznámka: $konfig->{poznamka}\n";
    $mail .= "Čas odeslání: $konfig->{cas_odeslani_access}\n";
    $mail .= "Variabilní symbol: $konfig->{vs} \n \n";
    $mail .= "Turnaje: \n";
    foreach my $a (@{$konfig->{_akce}})
    {
        my $nazev = $a->{nazev};
        $mail .= "$a->{rok}\t$a->{hra}\t$a->{turnaj}\t$nazev\t$a->{startovne_pred_slevou} => $a->{startovne} Kč\n";
    }
    $mail .= "----------\n";
    my $zlevnene_startovne = $konfig->{_celkem_startovne} * 0.8;
    $mail .= "CELKEM $konfig->{_celkem_startovne_pred_slevou} => $konfig->{_celkem_startovne} Kč (=> $zlevnene_startovne Kč)\n";
    if($konfig->{chce_platit_predem})
    {
        $mail .= "Chci zaplatit startovné předem a získat slevu 20 %.\n";
    }
    $mail .= jazyky::zjistit('potvrzeni_zaplatte_mail', $konfig->{vcas}, $zlevnene_startovne, $konfig->{vs})."\n";
    # Odeslat zprávu organizátorům.
    open(SENDMAIL, $sendmail) or print "Nemůžu najít sendmail: $!\n";
    print SENDMAIL ($mail);
    close(SENDMAIL);
    open(KOPIE, ">posledni-prihlaska.txt");
    print KOPIE ($mail);
    close(KOPIE);
    open(KOPIE, ">>archiv_prihlasek.txt");
    print KOPIE ("----------------------------------------------------------------------\n");
    print KOPIE ($mail);
    close(KOPIE);
}



#------------------------------------------------------------------------------
# Vygeneruje pro uživatele stránku se zprávou o úspěchu či neúspěchu jím
# odeslané přihlášky.
#------------------------------------------------------------------------------
sub zobrazit_potvrzovaci_stranku
{
    my $databaze = shift;
    my $konfig = shift;
    my $chyby = shift;
    my $nadpis;
    my $stranka;
    # Pokud byly v přihlášce nalezeny chyby, upozornit uživatele, že přihláška nebyla přijata.
    if(scalar(@{$chyby}))
    {
        $nadpis = jazyky::zjistit("prihlaska_nadpis_chyba");
        $stranka .= "<h3>".jazyky::zjistit("prihlaska_nadpis2_chyba")."</h3>\n";
        $stranka .= "<ul>\n";
        foreach my $chyba (@{$chyby})
        {
            $stranka .= "  <li>".jazyky::zjistit($chyba)."</li>\n";
            # K některým chybám máme doplňkové údaje.
            if($chyba eq 'chyba_prekryv_akci')
            {
                $stranka .= "    <ul>\n";
                foreach my $prekryv (@{$konfig->{_prekryvy}})
                {
                    $stranka .= "      <li>$prekryv->[0]{nazev} × $prekryv->[1]{nazev}</li>\n";
                }
                $stranka .= "    </ul>\n";
            }
        }
        $stranka .= "</ul>\n";
    }
    # Pokud byla přihláška bez chyb, ukázat uživateli přehled údajů a oznámit mu, že přihláška byla přijata.
    else
    {
        $nadpis = jazyky::zjistit("potvrzeni");
        $stranka .= jazyky::zjistit("potvrzeni_nadpis");
        $stranka .= "<table style='width:auto;border-style:none'><tr><td>".jazyky::zjistit("jmeno").": </td><td>$konfig->{jmeno} $konfig->{prijmeni}</td></tr>\n";
        $stranka .= "  <tr><td>".jazyky::zjistit("obec").": </td><td>$konfig->{obec} </td></tr>\n";
        $stranka .= "  <tr><td>".jazyky::zjistit("zeme").": </td><td>$konfig->{zeme}</td></tr>\n";
        $stranka .= "  <tr><td>E-mail: </td><td>$konfig->{email} </td></tr>\n";
        $stranka .= "  <tr><td>".jazyky::zjistit("poznamka").": </td><td>$konfig->{poznamka}</td></tr>\n";
        my %preklad_kategorii = ("dítě" => "dite", "student, důchodce" => "student", "normální" => "dospely");
        $stranka .= "  <tr><td>".jazyky::zjistit("kategorie").": </td><td>".jazyky::zjistit($preklad_kategorii{$konfig->{kategorie}})."</td></tr>\n";
        # Připsat organizace, jichž je členem, ostatní neuvádět.
        $stranka .= "  <tr><td>".jazyky::zjistit("clenstvi").": </td><td>";
        foreach my $clen ('paluba', 'scrabble', 'dama', 'dama2', 'go', 'othello', 'zatre', 'hadanka')
        {
            if($konfig->{'clen'.$clen})
            {
                $stranka .= $clen.' ';
            }
        }
        $stranka .= "</td></tr>\n";
        $stranka .= "  <tr><td>".jazyky::zjistit("vs").": </td><td>$konfig->{vs}</td></tr>\n";
        if($konfig->{pohlavi} eq "žena")
        {
            $stranka .= "  <tr><td>".jazyky::zjistit("pohlavi").": </td><td>".jazyky::zjistit("zena")."</td></tr>\n";
            $stranka .= "</table>\n";
            $stranka .= "<p>".jazyky::zjistit("prihlasila_jste_se")."</p>\n";
        }
        else
        {
            if($konfig->{pohlavi} ne "")
            {
                $stranka .= "  <tr><td>".jazyky::zjistit("pohlavi").": </td><td>".jazyky::zjistit("muz")."</td></tr>\n";
            }
            $stranka .= "</table>\n";
            $stranka .= "<p>".jazyky::zjistit("prihlasil_jste_se")."</p>\n";
        }
        # Zobrazit seznam akcí, na které se přihlásil. ###!!! Lokalizace!
        $stranka .= "<table style='width:auto;border-style:none'>\n";
        my $trt = "tr style='vertical-align:top'";
        my $tdl = "td style='text-align:left'";
        my $tdr = "td style='text-align:right'";
        $stranka .= "  <$trt><$tdl><b>".jazyky::zjistit('vyuctovani_polozka')."</b></td><$tdl><b>".jazyky::zjistit('vyuctovani_poplatek')."</b></td><$tdl><b>".jazyky::zjistit('vyuctovani_po_sleve')."</b></td></tr>\n";
        foreach my $a (@{$konfig->{_akce}})
        {
            my $nazev = $a->{nazev};
            if($a->{volitelny_turnaj}>=0)
            {
                $nazev .= " = $a->{volitelny_turnaj}";
            }
            $stranka .= "  <$trt><$tdl><b>$nazev</b></td><$tdr> ".jazyky::zjistit('kc_castka_tabulka', $a->{startovne_pred_slevou})."</td><$tdr> ".jazyky::zjistit('kc_castka_tabulka', $a->{startovne})."</td></tr>\n";
        }
        if($konfig->{_celkem_startovne})
        {
            $stranka .= "  <$trt><$tdl><b>".jazyky::zjistit('vyuctovani_celkem')."</b></td><$tdr> ".jazyky::zjistit('kc_castka_tabulka', $konfig->{_celkem_startovne_pred_slevou})."</td><$tdr> ".jazyky::zjistit('kc_castka_tabulka', $konfig->{_celkem_startovne})."</td></tr>\n";
        }
        $stranka .= "</table>\n";
        #if($konfig->{chce_platit_predem})
        {
            my $zlevnene_startovne = $konfig->{_celkem_startovne} * 0.8;
            $stranka .= "<p>".jazyky::zjistit('potvrzeni_zaplatte', $konfig->{vcas}, $zlevnene_startovne, $konfig->{vs})."</p>\n";
        }
    }
    # Obalit stránku jednotným záhlavím a zápatím a poslat ji na výstup.
    mso::vypsat_stranku(
    {
        "nazev"  => "MSO: $konfig->{rok}: ".jazyky::zjistit("Prihlaska"),
        "nadpis" => $nadpis,
        "telo"   => $stranka,
        "rok"    => $konfig->{rok}
    });
}
