ONO::FW::Edu::Apps::Modules::MathOnesTens

package ONO::FW::Edu::Apps::Modules::MathOnesTens;
################################################################################
# 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::Modules::WorksheetMaker::Input;

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::Lib::Parser;
use ONO::FW::Apps::PDF;
use ONO::IO;

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 = "math_onestens";

ONO::FW::Apps::Core->now("",$app,$vars{'app_lang'});

my ($num_comma,$num_delimiter) = ONO::FW::Apps::Core->local_comma_delimiter(ONO::FW::Apps::Core->detect_local($vars{'app_lang'}),$vars_ref);

my $WEB;

$WEB .= ONO::FW::Apps::Core->output_paper_save($pdfkey,$BLK_ref,\%vars,$HTTP,$BASE,"$year$mon$mday");

my $offset_y = 47.5;
my $offset_y2 = 2;

$vars{'app_input_op_mul'} = 0;
$vars{'app_input_op_div'} = 0;

my @txt = (
"ones",
"tens",
);

if ($vars{'app_lang'} eq "de" || $vars{'app_lang'} eq "lu") {
@txt = (
"Einer",
"Zehner",
)
}

if ($vars{'app_lang'} eq "fr") {
@txt = (
"uns",
"diszaines",
)
}

if ($vars{'app_input_print_options_title'} =~ /onestens/) {
$vars{'app_input_print_options_title'} = ucfirst "$txt[0] & $txt[1]";
}

if (ONO::FW::Apps::Core->running(\%vars,$db)) {

$WEB .= ONO::FW::Apps::Core->blockbackbutton($BASE,$vars_ref);

(
$vars{'app_input_range_from'},
$vars{'app_input_range_to'},

) = ONO::FW::Apps::Core->range_check(
50,
100,
$vars{'app_input_range_from'},
$vars{'app_input_range_to'},
);

#############################################################
# WORKSHEET MAKER
#############################################################

if ($vars{'output_worksheet_maker'}) {

$vars_ref = ONO::FW::Edu::Apps::Modules::WorksheetMaker::Input->vars(\%vars);
%vars = %$vars_ref;

}

#############################################################
# ONLINE TRAINING
#############################################################

if ($vars{'output_web'} || $vars{'output_paper'}) {

my $question_number = ONO::FW::Apps::Core->question_number($vars{'output_web_question_number'});

my (
$op_symbol_opts,$focus_on,
$page,$pages,%cache,
$whilecounter,$stats_switches,
$PDF_OPTS,
$stat_todo,$stat_todo_total,
);

my $questions_per_page = 1;

if ($vars{'output_paper'}) {

$PDF_OPTS = ONO::FW::Apps::Core->headers_options($BLK_ref,$vars_ref);

ONO::FW::Apps::PDF->new("$BASE/pdf/pdf-$pdfkey.pdf","",$format);

$vars{'app_input_multiple_questions_per_page'}++;
$questions_per_page = 12;
if ($vars{'app_input_op_add'} || $vars{'app_input_op_sub'}) {
$questions_per_page = 4;
}
$op_symbol_opts = "p";

}

foreach my $copy (ONO::FW::Apps::Core->unique_copies($vars{'app_input_print_options_unique_copies'})) {

my (@op,@op_symbol,@num1,@num2,@res);

my ($pdf_x,$pdf_y) = (23.5,38);
my (@corr_cache,@corr_cache_add);

if ($vars{'output_paper'}) {

if ($copy > 1) {
ONO::FW::Apps::PDF->page("",$format);
}
ONO::FW::Apps::Core->headers(\%vars,$format);
ONO::FW::Apps::PDF->title($vars{'app_input_print_options_title'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core->unique_copies_info($canvas,$copy,$vars_ref);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"HV",$vars_ref);

# ONO::Lib::PDF::ToolBox->canvas_test($canvas);

&draw_boxes("",$canvas,0,$offset_y,$offset_y2);

}

if (ONO::FW::Apps::Core->question_progress_done($vars{'app_input_number_of_questions'},$question_number) || $vars{'output_web_finish'}) {

$vars{'output_progress_done'}++;

$WEB .= ONO::FW::Apps::Core->question_progress_done_msg($app,$db,$community,$form,$action_url,$vars{'app_input_number_of_questions'},$vars{'output_web_mistakes'},$lang,$BLK_ref,$vars_ref);

} else {

if ($vars{'output_web'}) {

$WEB .= qq~<$form>~;

$WEB .= ONO::FW::Apps::Core->timer($vars{'output_web'},$vars{'output_web_timer_start'});

$op_symbol_opts = "c";

$WEB .= qq~<div class="w100 abs hide" style="top:0px;height:42px;background-color:#663333"></div>
<div class="w100 abs hide" style="top:380px;height:100px;background-color:#663333"></div>
<div class="inline abs" style="top:400px;left:10px">
~;
$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"ctmW$stats_switches");
$WEB .= qq~</div>~;

$WEB .= ONO::FW::Apps::Core->question_progress($vars{'app_input_number_of_questions'},$question_number,"","");


}

for (my $i = 0; $i < $questions_per_page; $i++) {

my $mode = &mode("",$vars{'app_input_options_draw'},$vars{'app_input_options_write'});

if ($vars{'app_input_op_add'} || $vars{'app_input_op_sub'}) {

if (!$op[$i]) {
$op[$i] = ONO::FW::Apps::Core->random_operation(ONO::FW::Apps::Core->get_operations(\%vars));
}
$op_symbol[$i] = ONO::FW::Apps::Core->operation_symbol($op[$i],$op_symbol_opts);

if ($op[$i] eq "add") {

($num1[$i],$num2[$i],$res[$i],$cache{'num1'},$cache{'num2'}) = ONO::FW::Apps::Core->generate_add($i,$num1[$i],$num2[$i],$op[$i],$res[$i],$cache{'num1'},$cache{'num2'},\%vars);

}

if ($op[$i] eq "sub") {

($num1[$i],$num2[$i],$res[$i],$cache{'num1'},$cache{'num2'}) = ONO::FW::Apps::Core->generate_sub($i,$num1[$i],$num2[$i],$op[$i],$res[$i],$cache{'num1'},$cache{'num2'},\%vars);

}

ONO::Lib::PDF::Draw->text_math_symbol($canvas,57,$i*$offset_y+18+$offset_y2,3,$op_symbol[$i]);
ONO::Lib::PDF::Draw->text_math_symbol($canvas,118,$i*$offset_y+18+$offset_y2,3,"=");

} else {

if ($vars{'output_web_cache_num1_0'}) {

$num1[$i] = $vars{'output_web_cache_num1_0'};

} else {

$num1[$i] = ONO::FW::Apps::Core->random_number($vars{'app_input_range_from'},$vars{'app_input_range_to'},0,100,$vars_ref);

}

}

# output paper

if ($vars{'output_paper'}) {

$corr_cache[$i] = "$op[$i]\^$op_symbol[$i]\^$num1[$i]\^$num2[$i]\^$res[$i]\^$pdf_x\^$pdf_y\^";

my @opts = ($num1[$i]);
my $opts_counter;
if ($vars{'app_input_op_add'} || $vars{'app_input_op_sub'}) {
@opts = ($num1[$i],$num2[$i],$res[$i]);
}

foreach my $opt (@opts) {

if ($opts_counter) {
$mode = &mode("",$vars{'app_input_options_draw'},$vars{'app_input_options_write'});
}

if ($opt < 10) {

my ($cx,$cy) = (0,27);
for (my $b2 = 0; $b2 < $opt; $b2++) {

if ($b2 > 4) {
$cx = 13.75;
$cy = 24;
}

my $X = $pdf_x-$cx+($b2*2.75)+($opts_counter*60)+9;
my $Y = $pdf_y-$cy;

@corr_cache_add = (@corr_cache_add,"circle:$X:$Y");

if ($mode eq "write" && $opts_counter < 2) {

my $BLACK = ONO::FW::Apps::Core::Graphics->pdf_black();

ONO::Lib::PDF::Draw->circle($canvas,$X,$Y,1,1,$BLACK,$BLACK);
}

}

if ($mode eq "draw" && $opts_counter < 2) {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($opts_counter*60)+10,$pdf_y+1,$opt,"c");
}

} else {

for (my $b = 0; $b < 2; $b++) {
my ($cx,$cy) = (21,27);
for (my $b2 = 0; $b2 < substr($opt,$b,1); $b2++) {

if ($b2 > 4) {
$cx = 34.75;
$cy = 24;
}

my $X = $pdf_x-$cx+($b2*2.75)+($b*21)+($opts_counter*60)+9;
my $Y = $pdf_y-$cy;

if ($mode eq "write" && $opts_counter < 2) {

my $BLACK = ONO::FW::Apps::Core::Graphics->pdf_black();

ONO::Lib::PDF::Draw->circle($canvas,$X,$Y,1,1,$BLACK,$BLACK);
}

@corr_cache_add = (@corr_cache_add,"circle:$X:$Y");

}
}

if ($mode eq "draw" && $opts_counter < 2) {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($opts_counter*60)+10-12,$pdf_y+1,substr($opt,0,1),"c");
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($opts_counter*60)+10,$pdf_y+1,substr($opt,1,1),"c");
}

}

$opts_counter++;

}

$pdf_y = $pdf_y + $offset_y;
if (($i+1)%4 == 0) {
$pdf_y = $pdf_y + 8;
}

if ($pdf_y > 190) {
$pdf_x = $pdf_x + 60;
$pdf_y = 38;
}

}


if ($vars{'output_web'}) {

$stat_todo++;

$vars{"output_web_answer_$i"} =~ s~[^0-9]~~gi;

if ($vars{"output_web_answer"}) {

if ($vars{"output_web_answer"} != $vars{"output_web_cache_num1_0"}) {

$vars{'output_web_mistakes'}++;
$vars{'output_web_answer_status'} = 2;
$op[$i] = $vars{"output_web_cache_op_$i"};
$num1[$i] = $vars{"output_web_cache_num1_$i"};
$num2[$i] = $vars{"output_web_cache_num2_$i"};
$res[$i] = $vars{"output_web_cache_res_$i"};

} else {

$question_number++;
$vars{'output_web_answer_status'} = 1;
$vars{'output_web_answer'} = "";

}

}

if ($vars{'output_web_answer_status'} != 1) {

$WEB .= qq~<input type="hidden" name="output_web_cache_num1_0" value="$num1[0]">~;

}

$WEB .= ONO::FW::Apps::Core->multi_frame_end($vars{'output_web_finish'},$vars{'app_input_multiple_questions_per_page'});

$WEB .= ONO::FW::Apps::Core->input_vars(\%vars);

my $ROWS;
for (my $r = 0; $r < 10; $r++) {
$ROWS .= qq~ <tr style="height:32px;background-image:url('/images/abacus/bar.png')">~;
for (my $c = 0; $c < 16; $c++) {
my $IMG = qq~<img class="block24" src="/ono/osr/images/spacer/trans.gif" alt="">~;
my $color = "white";

if ($num1[0]+1 > ($r+1)*10 && $c < 10) {
if ($c > 4) {
$color = "black";
}
$IMG = qq~<img class="block24 auto" src="/images/abacus/bullet_$color.png" alt="">~;
}
if ($num1[0]+1 > $r*10 && $num1[0] < ($r+1)*10) {
if ($c < $num1[0]-$r*10) {
if ($c > 4) {
$color = "black";
}
$IMG = qq~<img class="block24 auto" src="/images/abacus/bullet_$color.png" alt="">~;
}
my $rest = $num1[0]-$r*10;
$rest = 10-$rest;
if ($c > 15-$rest) {
if ($c > 10) {
$color = "black";
}
$IMG = qq~<img class="block24 auto" src="/images/abacus/bullet_$color.png" alt="">~;
}
}
if ($num1[0]-1 < $r*10 && $c > 5) {
if ($c > 10) {
$color = "black";
}
$IMG = qq~<img class="block24 auto" src="/images/abacus/bullet_$color.png" alt="">~;
}
$ROWS .= qq~ <td class="p0"><div class="rel" style="top:4px">$IMG</div></td>~;
}
$ROWS .= qq~ </tr>~;
}

$WEB .= qq~<table class="wide_table mb10">
<tr>
<td class="p10"></td>
<td class="p10 w10 p0" style="background-color:#663333"></td>
<td class="w80 p0 bg_fabric"><table class="wide_table">$ROWS</table></td>
<td class="p10 w10 p0" style="background-color:#663333"></td>
<td class="p10"></td>
</tr>
<tr>
<td></td>
<td class="p5" style="background-color:#663333"></td>
<td class="bg_fabric"></td>
<td class="p5" style="background-color:#663333"></td>
<td></td>
</tr>
</table>
~;

my $ANSWER;
if ($vars{'output_web_answer_status'} == 1) {
$ANSWER = qq~<td><div class="ml20 bold green">$num1[0]</div></td>~;
}

$WEB .= ONO::FW::Apps::Core->check_single(
$ANSWER,
"",
50,
2,
$BLK_ref,
\%vars,
"CnM",
);

$WEB .= qq~ <bgimage="/images/app_backgrounds/math_games_wood.jpg" alt="">
</form>
~;

if (ONO::IO->devstation) {
$WEB .= qq~<div class="bg_paper bo center mt20">debug: $num1[0]</div>~;
}

}

}

}

if (ONO::FW::Apps::Core->print_corrections("$BASE/pdf/pdf-$pdfkey-corr.pdf","",$format,$vars_ref)) {

ONO::FW::Apps::Core->headers(\%vars,$format,"c");
ONO::FW::Apps::PDF->title($BLK{'Corrections'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core->unique_copies_info($canvas,$copy,$vars_ref);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"CHV",$vars_ref);

# ONO::Lib::PDF::ToolBox->canvas_test($canvas);

&draw_boxes("",$canvas,1,$offset_y,$offset_y2);

for (my $c = 0; $c < $questions_per_page; $c++) {

my ($op,$op_symbol,$num1,$num2,$res,$pdf_x,$pdf_y) = split(/\^/,$corr_cache[$c]);

if ($num1[$c] < 10) {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+10,$pdf_y+1,$num1[$c],"c");
} else {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+10-12,$pdf_y+1,substr($num1[$c],0,1),"c");
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+10,$pdf_y+1,substr($num1[$c],1,1),"c");
}

if ($vars{'app_input_op_add'} || $vars{'app_input_op_sub'}) {
my $counter;
foreach my $opt ($num2[$c],$res[$c]) {
$counter++;
if ($opt < 10) {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($counter*60)+10,$pdf_y+1,$opt,"c");
} else {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($counter*60)+10-12,$pdf_y+1,substr($opt,0,1),"c");
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+($counter*60)+10,$pdf_y+1,substr($opt,1,1),"c");
}
}
}

ONO::Lib::PDF::Draw->text_math_symbol($canvas,57,$c*$offset_y+18+$offset_y2,3,$op_symbol[$c]);
ONO::Lib::PDF::Draw->text_math_symbol($canvas,118,$c*$offset_y+18+$offset_y2,3,"=");

}

foreach my $add (@corr_cache_add) {

my @ap = split(/:/,$add);
if ($ap[0] eq "circle") {
ONO::Lib::PDF::Draw->circle($canvas,$ap[1],$ap[2],1,1,1);
}

}

}

}

if ($vars{'output_web'}) {

$WEB = ONO::FW::Apps::Core->stats_replace($WEB,$question_number-1,0,$vars{'app_input_number_of_questions'}-$question_number+1,$vars{'output_web_mistakes'});

}

if ($vars{'output_paper'}) {

ONO::FW::Apps::PDF->end;

$WEB .= ONO::FW::Apps::Core->output_paper($pdfkey,\%BLK,\%vars,$HTTP,$BASE);

}

}

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'} = 20;
}

# "screen:320:50:50::math_abacus_screenshot_1.jpg",

$WEB .= ONO::FW::Apps::Core->infopics(
"sheet:168:180:110:15:math_onestens_sheet_1.jpg",
"sheet:168:40:140:-10:math_onestens_sheet_1.jpg",
);

if (!$vars{'app_input_options_draw'} && !$vars{'app_input_options_write'}) {
$vars{'app_input_options_write'}++;
}

my @options = (
"write:$vars{'app_input_options_write'}:$BLK{'write'}",
"draw:$vars{'app_input_options_draw'}:$BLK{'draw'}",
);

my $CONF .= ONO::FW::Apps::ToolBox->conf_input("range", $BLK_ref,\%vars,"",1,100,100);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
if ($vars{'output_paper'}) {
$CONF .= ONO::FW::Apps::ToolBox->conf_input("ops", $BLK_ref,\%vars,"","as");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("checks", $BLK_ref,\%vars,"",$BLK{'options'},"options",@options);
}

$WEB .= ONO::FW::Apps::Core->conf_box(
$db,
$community,
$app,
$form,
"",
$action_url,
$CONF,
$lang,
$BLK_ref,
\%vars,
"p-ncdi-CDI-lsu-N",
);

# "op-ncdi-CDI-lsu-N",

if (!$vars{'exercise'}) {
$WEB .= ONO::FW::Apps::Core->info_display(
ONO::FW::Apps::Core->info("info_online_print",$vars{'app_lang'}),
ONO::FW::Apps::Core->info("info_indiv_diff", $vars{'app_lang'}),
);
}

}

my ($status,$WEB) = ONO::Lib::Parser->parse($WEB,$vars_ref);

$WEB .= ONO::FW::Apps::Core->vardump($vars_ref);

$WEB = ONO::FW::Edu::Apps::ToolBox->apps_gate($WEB,$vars_ref);

return $WEB;

}

###################################################################
# SUBS
###################################################################

sub mode {

my $mode = "write";
if ($_[1]) {
$mode = "draw";
}
if ($_[1] && $_[2] && int(rand(100)) > 50) {
$mode = "write";
}

return $mode;

}

sub draw_boxes {

my $offset_y = $_[3];
my $offset_y2 = $_[4];

for (my $y = 0; $y < 4; $y++) {
my $off_x = 9;
for (my $x = 0; $x < 6; $x++) {
if ($x == 2 || $x == 4) {
$off_x = $off_x + 18;
}

my ($GREY1,$GREY2);

if (!$_[2]) {

($GREY1,$GREY2) = (ONO::FW::Apps::Core::Graphics->pdf_grey(),ONO::FW::Apps::Core::Graphics->pdf_grey());

}

ONO::Lib::PDF::Draw->rect( $_[1], $x*21+$off_x, $y*$offset_y+6+$offset_y2,($x*21)+16+$off_x, ($y*$offset_y)+27+$offset_y2, 0.5,"",$GREY1,2);

if ($x%2 == 0) {
ONO::Lib::PDF::Draw->rect( $_[1], ($x*21)+9+$off_x, ($y*$offset_y)+32+$offset_y2,($x*21)+16+$off_x, ($y*$offset_y)+39+$offset_y2, 0.5,"",$GREY2,1);
} else {
ONO::Lib::PDF::Draw->rect( $_[1], $x*21+$off_x, ($y*$offset_y)+32+$offset_y2,($x*21)+7+$off_x, ($y*$offset_y)+39+$offset_y2, 0.5,"",$GREY2,1);
}
}
}

}

###################################################################
#### THAT'S IT :-D
###################################################################

1;

__END__