package ONO::FW::Edu::Apps::Modules::Hangman;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2022-2026 Jos Kirps and The Joopita Project [ASBL]
# Copyright (C) 2011-2022 Jos Kirps and Joopita Research ASBL
# Copyright (C) 2006-2011 Jos Kirps and The Joopita Project
# Copyright (C) 2001-2006 Jos Kirps and The WobbleWolf Project
#
# This file, as well as many other parts of the ONO Software Project or
# related elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
#: This module is a front end application module wrapper that has been
#: created for the Morzino Project (morzino.com) and that has been released
#: as Open Source software.
#:
#: Note that this is NOT a self-contained application, it is only a wrapper
#: that makes heavy use of the ONO Perl Framework application engine.
use strict;
use ONO::FW::Edu::Apps::ToolBox;
use ONO::FW::Edu::Apps::Variation;
use ONO::Lib::Encoding::HTML;
use ONO::FW::Apps::ToolBox;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::FW::Apps::Core;
use ONO::FW::Apps::Core::Graphics;
use ONO::FW::Apps::Core::Lang;
use ONO::Lib::Parser;
use ONO::FW::Apps::PDF;
use ONO::IO;
use ONO::DB;
use ONO::Lib::SQL::TableCreate;
use ONO::Lib::Basic;
sub learn {
my (
$self,
$option,
$vars_ref,
$HTTP,
$BASE,
) = @_;
################################################################
# INIT - BEGIN
################################################################
my (
$db,
$community,
$action_url,
$form,
$format,
$canvas,
$pdfkey,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp,
$lang,
$BLK_ref,
$vars_ref,
) = ONO::FW::Apps::Core->init($vars_ref);
my %vars = %$vars_ref;
my %BLK = %$BLK_ref;
my $app = "Hangman";
my $WEB;
ONO::FW::Apps::Core->now("",$app,$vars{'app_lang'});
$vars{'app_input_print_options_title_default'} = ucfirst $BLK{$app};
if (ONO::IO->devstation) {
$vars{'username'} = "jos";
}
if (ONO::FW::Apps::Core->running(\%vars,$db)) {
$vars{'wordlist_force_loading'} = 1;
}
$vars{'wordlist_max_words'} = 100;
my (
$RETURN,$WORDLIST_ref,$TRANS_ref,$IMGS_ref,
$USE_GROUPS,$USE_GROUPS_ALT,$USE_GROUPS_LU,$USE_GROUPS_CUSTOM_ref,
$CACHE_WORDS,$CACHE_TRANS,$CACHE_IMGS,
$use_language1,$use_language2,
$use_images,$use_images_reverse,$use_images_forced,$use_custom_groups,$use_lu,
$get_words,$words_found,$multi_frame_custom_width,$hide_flags,
) = ONO::FW::Apps::Core::Lang->lang_load_wordlist($db,$community,\%vars);
$WEB .= $RETURN;
my @WORDLIST = @$WORDLIST_ref;
my @TRANS = @$TRANS_ref;
my @IMGS = @$IMGS_ref,
my @USE_GROUPS_CUSTOM = @$USE_GROUPS_CUSTOM_ref;
$WEB .= qq~<bgimage="/images/app_backgrounds/hangman_main.jpg" alt="">~;
if (ONO::FW::Apps::Core->running(\%vars,$db) && $words_found) {
#############################################################
# ONLINE TRAINING
#############################################################
$WEB .= ONO::FW::Apps::Core->blockbackbutton($BASE,$vars_ref);
$WEB .= qq~<$form>
<input type="hidden" name="output_web_is_running" value="running">
<input type="hidden" name="output_web_cache_words" value="$CACHE_WORDS">
<input type="hidden" name="output_web_cache_trans" value="$CACHE_TRANS">
<input type="hidden" name="output_web_cache_imgs" value="$CACHE_IMGS">
~;
$WEB .= ONO::FW::Apps::Core->input_vars(\%vars,"f");
if ($vars{'current_question_number'} < 1) {
$vars{'current_question_number'} = 1;
}
if ($vars{'app_input_number_of_questions'} > $words_found) {
$vars{'app_input_number_of_questions'} = $words_found;
}
my $wrong_total = 0;
if ($vars{'output_web_continue'}) {
$vars{'current_question_number'}++;
$vars{'chars'} = "";
$wrong_total = $vars{'wrong_total'};
}
if (ONO::FW::Apps::Core->question_progress_done($vars{'app_input_number_of_questions'},$vars{'current_question_number'})) {
$vars{'output_progress_done'}++;
$WEB .= qq~<div class="p20"><div class="box_paper w80 auto trans90">~;
$WEB .= ONO::FW::Apps::Core->question_progress_done_msg(
$app,
$db,
$community,
$form,
$action_url,
$vars{'app_input_number_of_questions'},
$wrong_total,
$lang,
$BLK_ref,
$vars_ref,
"R",
);
$WEB .= qq~</div></div>~;
} else {
my $counter;
foreach my $word (@WORDLIST) {
$word =~ s~(\?|\!|\.|\,|\:|\;|\")~~g;
$word =~ s~ ~ ~g;
$counter++;
if ($counter == $vars{'current_question_number'}) {
$word =~ s~\^(.*)$~~;
$word =~ s~\((.*)\)$~~;
$word =~ s~ $~~;
if (ONO::IO->devstation) {
# $word = "über-morgen";
}
my $word_no_umlauts = ONO::Lib::Basic->umlaut_simplify($word,1);
my $answer;
if ($vars{'answer_key'} =~ /[A-Za-z]/) {
$answer = $vars{'answer_key'};
}
if ($vars{'answer_key'} =~ /(Ü|Ö|Ä|ü|ö|ä|é|è|ß)/) {
$answer = ONO::Lib::Basic->umlaut_simplify($vars{'answer_key'},1);
}
my @keys = ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
foreach my $key (@keys) {
if ($vars{"answer_$key"}) {
$answer = $key;
}
}
$answer = lc $answer;
$answer =~ s~[^a-z]~~g;
if ($vars{'chars'} !~ /$answer/i) {
$vars{'chars'} .= $answer;
}
my $STATS = ONO::FW::Apps::Core->question_progress($vars{'app_input_number_of_questions'},$vars{'current_question_number'});
$STATS .= ONO::FW::Apps::Core->stats("",\%BLK,"ecm");
my $wrong = 0;
my ($GOOD,$BAD,@umlauts_found);
for (my $i = 0; $i < length $vars{'chars'}; $i++) {
my $USE = substr($vars{'chars'},$i,1);
if ($word !~ /$USE/i && $word_no_umlauts !~ /$USE/i) {
$BAD .= qq~$USE ~;
$wrong++;
$wrong_total++;
} else {
$GOOD .= qq~$USE ~;
}
}
my $correct = 0;
my $is_umlaut = 0;
my $word_length = length $word;
my $word_length_real = length $word;
my $WORD;
for (my $i = 0; $i < $word_length; $i++) {
if ($is_umlaut) {
$is_umlaut = 0;
$word_length_real--;
} else {
my $USE = substr($word,$i,1);
my $UML = substr($word,$i,2);
my $SIM = "#";
if ($UML !~ /[A-Za-z]/) {
if (ONO::Lib::Basic->umlaut($UML)) {
$USE = $UML;
$SIM = ONO::Lib::Basic->umlaut_simplify($UML);
$is_umlaut = 1;
}
}
my $CHAR = " ";
my $LINE = "background-color:#ffffff;border-top:1px solid #eeeeee;border-left:1px solid #eeeeee;border-right:1px solid #eeeeee;border-bottom:2px solid #aaaaaa";
if ($USE eq " " || $USE eq "'" || $USE eq "-") {
$LINE = "";
if ($USE eq "'") {
$CHAR = "'";
}
if ($USE eq "-") {
$CHAR = "-";
}
}
my $USE_UMLAUT;
if (ONO::Lib::Basic->umlaut($USE)) {
if ($vars{'chars'} =~ /a/ && ($USE eq "Ä" || $USE eq "ä" || $USE eq "â" || $USE eq "ã" || $USE eq "à")) {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /o/ && ($USE eq "Ö" || $USE eq "ö" || $USE eq "ô" || $USE eq "õ")) {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /e/ && ($USE eq "ë" || $USE eq "ê" || $USE eq "é" || $USE eq "è")) {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /i/ && ($USE eq "ï" || $USE eq "î")) {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /u/ && ($USE eq "Ü" || $USE eq "ü" || $USE eq "û")) {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /c/ && $USE eq "ç") {
$USE_UMLAUT = $USE;
}
if ($vars{'chars'} =~ /s/ && $USE eq "ß") {
$USE_UMLAUT = $USE;
}
}
if (($USE && $vars{'chars'} =~ /$USE/i) || ($SIM && $vars{'chars'} =~ /$SIM/i) || $USE_UMLAUT) {
$correct++;
$CHAR = $USE;
if ($USE_UMLAUT) {
$CHAR = $USE_UMLAUT;
}
} else {
if ($wrong > 10) {
$CHAR = qq~<span class="bold green">$USE<span>~;
}
}
$WORD .= qq~<td class="large" style="padding:5px 10px 5px 10px;$LINE">$CHAR</td><td> </td>~;
if ($i > 1 && $i%18 == 0) {
$WORD .= qq~</tr><tr>~;
}
}
}
my $test = $word;
$test =~ s~( |\')~~g;
my $todo = length $test;
$todo = $todo - $correct - $word_length + $word_length_real;
$STATS = ONO::FW::Apps::Core->stats_replace(
$STATS,
$correct,
$wrong_total,
$todo,
$wrong,
);
my $ENTRY_STYLE1 = "width:1px;height:1px";
my $ENTRY_STYLE2 = "width:50px;top:-40px";
if (ONO::IO->devstation) {
$ENTRY_STYLE1 = "";
$ENTRY_STYLE2 = "width:50px;top:500px";
}
my $ENTRY = qq~<input type="text" id="answer_key_id" name="answer_key" value="" maxlength="1" style="$ENTRY_STYLE1" onkeyup="onojs_submit();">~;
my $BUTTON;
foreach my $key (@keys) {
my $button_color = "";
if ($GOOD =~ /$key/i) {
$button_color = "_green";
}
if ($BAD =~ /$key/i) {
$button_color = "_red";
}
$BUTTON .= qq~<td>
<input type="submit" name="answer_$key" value="$key" class="button$button_color button_small" style="padding-left:8px;padding-right:8px">
</td>
~;
}
my $boxcolor = "paper";
$answer =~ s~[^0-9]~~g;
if ($todo < 1) {
$boxcolor = "green";
$ENTRY = "";
$BUTTON = qq~<td><input type="submit" name="output_web_continue" value="$BLK{'next'}..." class="button_green"></td>~;
}
if ($wrong > 10) {
$boxcolor = "red";
$ENTRY = "";
$BUTTON = qq~<td><input type="submit" name="output_web_continue" value="$BLK{'next'}..." class="button_green"></td>~;
}
if ($GOOD) {
$GOOD = qq~<div class="box_green pad10 auto large" style="width:200px">
$GOOD
</div>
~;
}
if ($BAD) {
$BAD = qq~<div class="box_red pad10 auto large" style="width:200px">
$BAD
</div>
~;
}
if (ONO::IO->devstation) {
$WORD .= qq~<td>$word</td>~;
}
$WEB .= qq~$STATS
<input type="hidden" name="chars" value="$vars{'chars'}">
<input type="hidden" name="current_question_number" value="$vars{'current_question_number'}">
<input type="hidden" name="wrong_total" value="$wrong_total">
<table class="wide_table mt10">
<tr class="vtop">
<td class="w33 p20">
$GOOD
</td>
<td class="w33 p20">
<div class="box_paper auto rel trans90" style="width:200px;height:200px;padding:10px 0px 0px 10px">
<img class="block200 abs trans10" src="/images/hangman/hangman11.png" style="top:5px;left:5px" alt="">
<img class="block200 abs" src="/images/hangman/hangman$wrong.png" style="top:5px;left:5px" alt="">
</div>
</td>
<td class="w33 p20">
$BAD
</td>
</tr>
</table>
<div class="box_$boxcolor pad5 trans95 abs" style="width:880px;top:350px;left:10px">
<table class="default_table auto" style="margin-bottom:20px">
<tr>
$WORD
</tr>
</table>
<table class="default_table auto">
<tr>$BUTTON</tr>
</table>
</div>
<div class="auto abs" style="$ENTRY_STYLE2">$ENTRY</div>
<onload:focus:form:answer_key_id>
<onclick:focus:form:answer_key_id>
<script>onojs_focus('answer_key_id');</script>
~;
}
}
}
$WEB .= qq~</form>~;
$WEB .= ONO::FW::Apps::Core->vardump($vars_ref);
$WEB = ONO::FW::Edu::Apps::ToolBox->apps_gate($WEB,$vars_ref);
if ($vars{'output_web'}) {
ONO::FW::Apps::Core->varstore($vars{'username'},$vars{'virclass'},$vars{'anonymous'},\%vars);
}
} else {
#############################################################
# EXERCISE SETUP
#############################################################
if (!$vars{'app_input_number_of_questions'}) {
$vars{'app_input_number_of_questions'} = 10;
}
$vars{'lang_default_setup_config_max_cats'} = 20;
$vars{'output_web_custom_text'} = $BLK{'start_game'};
my (
$default_ref,$default_lessons,$all_lessons,$custom_lessons,$LU,
) = ONO::FW::Apps::Core::Lang->lang_default_setup_config(\%vars);
my @default = @$default_ref;
$vars{'software_base'} = $BASE;
my $CONF .= ONO::FW::Apps::ToolBox->conf_input("langs", $BLK_ref,\%vars,"ips","$default[0];en:de:fr$LU");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("selections", $BLK_ref,\%vars,"Nl",$BLK{'lists'},$default_lessons,$all_lessons,"$BLK{'Add_a_list'}::$custom_lessons",22);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("difficulty", $BLK_ref,\%vars,"i",5,3);
$WEB .= qq~<div class="box_paper trans50 abs" style="top:32px;right:32px">
<img class="block256 trans80" src="/images/hangman/hangman11.png" alt="">
</div>
~;
$WEB .= ONO::FW::Apps::Core->conf_box(
$db,
$community,
$app,
$form,
"",
$action_url,
$CONF,
$lang,
$BLK_ref,
\%vars,
"o-ls-N-LT",
);
$WEB .= ONO::FW::Apps::Core->vardump($vars_ref);
$WEB = ONO::FW::Edu::Apps::ToolBox->apps_gate($WEB,$vars_ref);
}
my ($status,$WEB) = ONO::Lib::Parser->parse($WEB,$vars_ref);
my $VARIATION = ONO::FW::Edu::Apps::Variation->variation();
if ($community eq "school") {
$WEB = ONO::Lib::Encoding::HTML->encode($WEB);
}
return $WEB;
}
###################################################################
#### THAT'S IT :-D
###################################################################
1;
__END__