ONO::FW::Edu::Apps::Modules::GeoCubes

package ONO::FW::Edu::Apps::Modules::GeoCubes;
################################################################################
# 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::Edu::Apps::JS::GeoCubesScript;

use ONO::IO;

use ONO::FW::Apps::ToolBox;
use ONO::FW::Apps::Dev;

use ONO::Lib::Image::Canvas;
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::Lib::UI::Check;
use ONO::Lib::UI::Select;

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

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

my @txt = (
"Geometry Cubes",
"each stack has its own color",
"cubes",
"stacks",
"max stack height",
"allow empty space between stacks",
"display stack height in 3D view",
);

if ($vars{'app_lang'} eq "de") {
@txt = (
"Geometrie Würfel",
"jeder Turm hat seine eigene Farbe",
"Würfel",
"Türme",
"maximale Turmhöhe",
"Leerraum zwischen Türmen zulassen",
"Turmhöhe in der 3D-Ansicht anzeigen",

);
}

if ($vars{'app_lang'} eq "lu") {
@txt = (
"Geometrie Wierfel",
"all Tuerm huet seng eege Faarf",
"Wierfel",
"Tierm",
"maximal Tuermhéicht",
"Eidele Raum tëscht Tierm erlaabt",
"Tuermhéicht an der 3D-Usiicht uweisen",
);
}

if ($vars{'app_lang'} eq "fr") {
@txt = (
"Cubes géométriques",
"chaque tour a sa propre couleur",
"cubes",
"tours",
"hauteur max. des tours",
"spaces vides entre les tours possibles",
"afficher hauteur des tours en vue 3D",
);
}

if (!$vars{'app_input_board_size'}) {
$vars{'app_input_board_size'} = 6;
}
if (!$vars{'app_input_cubes_from'}) {
$vars{'app_input_cubes_from'} = 3;
}
if (!$vars{'app_input_cubes_to'}) {
$vars{'app_input_cubes_to'} = 10;
}
if (!$vars{'app_input_stacks_from'}) {
$vars{'app_input_stacks_from'} = 3;
}
if (!$vars{'app_input_stacks_to'}) {
$vars{'app_input_stacks_to'} = 6;
}
if (!$vars{'app_input_stack_max_height'}) {
$vars{'app_input_stack_max_height'} = 4;
}

my $WEB;

my $AppName = "Geo Cubes";

$vars{'app_input_print_options_title_default'} = $AppName;

$WEB .= qq~<script src="/ono/osr/javascript/three/r134/three.min.js"></script>
<script src="/ono/osr/javascript/three/r134/OrbitControls.js"></script>
<script src="/ono/osr/javascript/three/r134/FontLoader.js"></script>
<script src="/ono/osr/javascript/three/r134/TextGeometry.js"></script>
~;

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

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

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

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

if ($vars{'output_worksheet_maker'}) {

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

}

#############################################################
# WORKSHEET MAKER MODE
#############################################################

my $worksheet_maker_mode;
if ($vars{'output_worksheet_maker'}) { # || ONO::IO->devstation) {
$worksheet_maker_mode = 1;
}

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

if ($vars{'output_web'}) {

if ($vars{'output_web_next_question'}) {
$vars{'output_web_question_number'}++;
}

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

$WEB .= qq~<style>
#gameWrapper {
width: 920px;
height: 480px;
display: flex;
position: relative;
}
#threeContainer {
width: 50%;
height: 100%;
}
#canvas2D {
width: 50%;
height: 100%;
}
#winMessage {
position: absolute;
display: none;
}
#threeContainer .three-canvas {
border-radius: 10px;
}
</style>
~;

my $stacksConnected = 1;
my $stacksColorized = 1;
my $stacksNumbered = 0;

if ($vars{'app_input_stacks_connected'}) {
$stacksConnected = 0;
}
if ($vars{'app_input_stacks_same_color'}) {
$stacksColorized = 0;
}
if ($vars{'app_input_stacks_numbered'}) {
$stacksNumbered = 1;
}

$WEB .= qq~<script>
function correct_next() {
onojs_block('correct_next_message');
}
</script>
~;

$WEB .= ONO::FW::Edu::Apps::JS::GeoCubesScript->code(
$vars{'app_input_mode'},
$vars{'app_input_board_size'},
$vars{'app_input_cubes_from'},
$vars{'app_input_cubes_to'},
$vars{'app_input_stacks_from'},
$vars{'app_input_stacks_to'},
$vars{'app_input_stack_max_height'},
$stacksConnected,
$stacksColorized,
$stacksNumbered,
);

my $INPUT;
foreach my $key (sort keys %vars) {
if ($key =~ /^(app_input|output)_/) {
$INPUT .= qq~<input type="hidden" name="$key" value="$vars{$key}">~;
}
}

$WEB .= qq~<$form>
$INPUT
<div id="correct_next_message" class="hide">
<div class="abs" style="width:920px;top:400px">
<div class="auto w50">
<div class="box_green">
<table class="wide_table">
<tr>
<td><img class="block32 ml10 mr10" src="/ono/osr/images/icons/crystal/32x32/ono/yes.png" alt=""></td>
<td class="w100"><div class="green bold xlarge">$question_number / $vars{'app_input_number_of_questions'}</div></td>
<td><input type="submit" name="output_web_next_question" value="$BLK{'continue'}..." class="button_green button_big mr10"></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</form>
~;

if ($question_number > $vars{'app_input_number_of_questions'}) {

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

}

ONO::FW::Apps::Core->varstore($vars{'username'},$vars{'virclass'},$vars{'anonymous'},\%vars);

}

} else {

#############################################################
# EXERCISE SETUP
#############################################################

my %setup;

my $CONF;

my $MODE = qq~<script>
function app_input_mode_toggle() {
var mode = onojs_getvalue("app_input_mode_id");
if (mode == 0) {
onojs_setvalue("app_input_mode_id","2");
onojs_setsrc("app_input_mode_img_0","$BASE/images/morzino/apps/math_geocubes_mode_2.jpg");
onojs_setsrc("app_input_mode_img_2","$BASE/images/morzino/apps/math_geocubes_mode_0.jpg");
onojs_sethtml("app_input_mode_info_0","3D");
onojs_sethtml("app_input_mode_info_2","2D");
} else {
onojs_setvalue("app_input_mode_id","0");
onojs_setsrc("app_input_mode_img_0","$BASE/images/morzino/apps/math_geocubes_mode_0.jpg");
onojs_setsrc("app_input_mode_img_2","$BASE/images/morzino/apps/math_geocubes_mode_2.jpg");
onojs_sethtml("app_input_mode_info_0","2D");
onojs_sethtml("app_input_mode_info_2","3D");
}
}
</script>
<div onclick="app_input_mode_toggle();" class="cursorlink noselect">
<table class="default_table">
<tr>
<td>
<div class="box_paper block64 p0">
<img id="app_input_mode_img_0" src="$BASE/images/morzino/apps/math_geocubes_mode_0.jpg" class="block64 radius10" alt="">
</div>
</td>
<td>
<img class="block32" src="/ono/osr/images/icons/crystal/32x32/ono/arrow_blue_next.png" alt="">
</td>
<td>
<div class="box_paper block64 p0">
<img id="app_input_mode_img_2" src="$BASE/images/morzino/apps/math_geocubes_mode_2.jpg" class="block64 radius10" alt="">
</div>
</td>
</tr>
<tr>
<td class="center bold"><div id="app_input_mode_info_0">2D</div></td>
<td></td>
<td class="center bold"><div id="app_input_mode_info_2">3D</div></td>
</tr>
</table>
</div>
<input type="hidden" id="app_input_mode_id" name="app_input_mode" value="0">
~;

$CONF .= ONO::FW::Apps::ToolBox->conf_input("custom", $BLK_ref,\%vars,"","",$MODE);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("select", $BLK_ref,\%vars,"","8=8 x 8;6=6 x 6;4=4 x 4",$BLK{'size'},$vars{'app_input_board_size'});
$CONF .= ONO::FW::Apps::ToolBox->conf_input("rangesel", $BLK_ref,\%vars,"",$vars{'app_input_cubes_from'},$vars{'app_input_cubes_to'},20,$txt[2],"","cubes");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("rangesel", $BLK_ref,\%vars,"",$vars{'app_input_stacks_from'},$vars{'app_input_stacks_to'},10,$txt[3],"","stacks");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("selnum", $BLK_ref,\%vars,"",1,5,"nNsS",$vars{'app_input_stack_max_height'},"= $txt[4]","app_input_stack_max_height");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("checkinv", $BLK_ref,\%vars,"S","","stacks_same_color",$vars{'input_stacks_same_color'},$txt[1]);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"S","","stacks_numbered",$vars{'input_app_stacks_numbered'},$txt[6]);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"S","","stacks_connected",$vars{'input_app_stacks_connected'},$txt[5]);

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

$WEB .= qq~ <style>
#canvas2D {
display: none;
}
#winMessage {
display: none;
}
#full3DContainer .three-canvas {
position: absolute;
left:520px;
top:0px;
border-radius: 10px;
overflow: hidden;
background: black;
}
</style>
~;


$WEB .= ONO::FW::Edu::Apps::JS::GeoCubesScript->code(3,8,3,10,3,8,3,1,1,1);

if (!$vars{'exercise'}) {
my $INFO = ONO::FW::Apps::Core->info("info_indiv_diff", $vars{'app_lang'});
my ($status,$INFO) = ONO::Lib::Parser->parse($INFO,$vars_ref);
$WEB .= qq~<div class="cole abs center italic" style="top:10px;left:530px;width:380px">$INFO</div>~;
}

}

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

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

my @INPUT = (
"gameMode",
"boardSize",
"minNumCubes",
"maxNumCubes",
"minNumStacks",
"maxNumStacks",
"maxStackHeight",
"stacksConnected",
"stacksRandomColors",
"stacksNumbered",
);

my @ACTION = (
qq~alert_you_won\^correct_next\^~,
);

$WEB .= ONO::FW::Apps::Dev->js_compiler(
"/cgi-bin/local/perl/school/apps/geocubes.pl",
"ono/sys/ONO/Ext/Morzino/Apps/JS",
"ONO:Ext:Morzino:Apps:Modules:GeoCubes",
"ONO:Ext:Morzino:Apps:JS:GeoCubes",
\@INPUT,
\@ACTION,
);

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

return $WEB;

}

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

1;

__END__