ONO::FW::Edu::Apps::Modules::QRCode

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

use ONO::DB;
use ONO::Lib::SQL::TableCreate;
use ONO::Lib::Basic;
use ONO::Lib::Data::Letters;

use ONO::Lib::UI::Check;

use ONO::Lib::Image::QR;
use ONO::Lib::PDF::Gen;

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

my $WEB;

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

my @txt = (
"QR Code Generator",
"This web app allows to create your own, printable and resuable QR codes.",
"A QR code (Quick Response code) is a barcode-like code that can be used to transfer information, such as web addresses (URLs) for example.",
"QR codes can be read by most smartphones, tablets, and other devices, and scanning them may automatically open a website or a specific link.",
"You may use QR codes to share apps, exercises and other information with students and other users.",
"test link",

"open image",
"download image",
"You must be logged in if you'd like to generate QR codes.",
);
if ($lang eq "de") {
@txt = (
"QR Code Generator",
"Mit dieser Web-App kannst du deine eigenen, druckbaren und wiederverwendbaren QR-Codes erstellen.",
"Ein QR-Code (Quick Response Code) ist ein barcodeähnlicher Code, mit dem Informationen wie zB Webadressen (URLs) übertragen werden können.",
"QR-Codes können von den meisten Smartphones, Tablets und anderen Geräten gelesen werden, und beim Scannen kann automatisch ein Link geöffnet werden.",
"Du kannst QR-Codes erstellen um Apps, Übungen und andere Informationen mit Schülern und anderen Benutzern zu teilen.",
"Testlink",

"Bild öffnen",
"Bild herunterladen",
"Du musst eingeloggt sein, um QR Codes zu generieren.",
);
}

if ($lang eq "lu") {
@txt = (
"QR Code Generator",
"Mat dëser Web-App kanns du eegen, dréckbar a réutilisabel QR Code maachen.",
"E QR Code (Quick Response Code) ass e Barcode-ähnleche Code dee benotzt ka ginn fir Informatioun ze transferéieren, wéi zum Beispill Webadressen (URLen).",
"QR Coden kënne vu de meeschte Smartphones, Tablets an aner Apparater gelies ginn, an et kann automatesch eng Websäit oder e spezifesche Link opgemaach ginn.",
"Du kanns QR Codes benotze fir Apps, Übungen an aner Informatioune mat Schüler an anere Benotzer ze deelen.",
"Testlink",

"Bild opmaachen",
"Bild eroflueden",
"Du muss ageloggt sinn, fir QR Codes ze generéieren.",
);
}

if ($lang eq "fr") {
@txt = (
"Générateur Code QR",
"Cette web app permet de créer vos propres QR codes imprimables et réutilisables.",
"Un code QR (Quick Response code) est un code de type code-barres qui peut être utilisé pour transférer des informations, telles que des adresses Web (URL) par exemple.",
"Les codes QR peuvent être lus par la plupart des smartphones, tablettes et autres appareils, pour ainsi ouvrir un site Web ou un lien spécifique.",
"Vous pouvez utiliser des codes QR pour partager des applications, des exercices et d'autres informations avec des élèves et d'autres utilisateurs.",
"tester le lien",

"ouvrir image",
"télécharger mage",
"Vous devez être connecté si vous souhaitez générer des codes QR.",
);
}

my $NAME = $txt[0];
$vars{'app_input_print_options_title_default'} = $txt[0];


if (ONO::IO->devstation) {
$vars{'username'} = "jos";
}

my $CONF_BOX_TITLE = ONO::FW::Apps::Core->conf_box_title("ono/setup",$BLK{'Setup'});

my $qrcode_generator_run;

if ($vars{'qrgen'} && !$vars{'qrcode_generator_url'}) {
$vars{'qrcode_generator_url'} = $vars{'qrgen'};
}

$vars{'qrcode_generator_url'} =~ s~^(http|https)://~~g;

if ($vars{'app_input_output_format'} eq "pdf") {

if ($vars{'qrcode_generator_protocol'} && ONO::Lib::Basic->valid_url($vars{'qrcode_generator_url'}) && $vars{'qrcode_generator_layout'}) {
$qrcode_generator_run++;
}

} else {

if ($vars{'qrcode_generator_protocol'} && ONO::Lib::Basic->valid_url($vars{'qrcode_generator_url'})) {
$qrcode_generator_run++;
}

}

#if ($vars{'username'} && (ONO::FW::Apps::Core->running(\%vars,$db) || $qrcode_generator_run)) {

if ($vars{'username'} && $qrcode_generator_run) {

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

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

my $URL = "$vars{'qrcode_generator_protocol'}://$vars{'qrcode_generator_url'}";
my $FILE = ONO::Lib::Image::QR->tmp($URL);
my $PRINT;

my $EXT = "jpg";
my $SIZE = 320;
if ($vars{'app_input_output_format'} =~ /^(png|pdf)$/) {
$EXT = $1;
$SIZE = 160;
}

my $RES = qq~<div class="p10 bb">
<table class="wide_table">
<tr>
<td class="w100"><input type="text" name="" value="$URL" class="w98" onclick="this.select();"></td>
<td class="nowrap"><a href="$URL" class="button_green" target="_blank">$txt[5]</a></td>
</tr>
</table>
</div>
<table class="wide_table">
<tr class="vtop">
<td><img class="block" src="/images/qr/tmp/$FILE.$EXT" style="width:${SIZE}px;height:${SIZE}px" alt="QR Code"></td>
<td class="w100">
<div class="p20 mt20">
<div class="inline"><a href="/images/qr/tmp/$FILE.$EXT" class="button_green button_big mb20" target="_blank">$txt[6]</a></div>
<div class="inline"><a href="/download/-/images/qr/tmp/$FILE.$EXT" class="button_green button_big mb20" target="_blank">$txt[7]</a></div>
<div class="inline"><a href="$action_url" class="button_yellow button_big">$BLK{'back'}</a></div>
</div>
</td>
</tr>
</table>
~;

if ($vars{'qrcode_generator_layout'} && $vars{'qrcode_generator_pages'} && ONO::IO->exists("images/qr/tmp/$FILE.jpg")) {

my $canvas = ONO::Lib::PDF::ToolBox->canvas_init_max($format);
my ($size_x,$size_y) = ONO::Lib::PDF::ToolBox->papersize_mm($format,"D");

ONO::Lib::PDF::Gen->open("pdf/pdf-$pdfkey.pdf",0,0,"",$format);

for (my $page = 1; $page < $vars{'qrcode_generator_pages'}+1; $page++) {
if ($page < 11) {
if ($page > 1) {
ONO::Lib::PDF::Gen->page($format);
}
}

# lines

my ($x,$y) = (1,1);
my ($pos_x,$pos_y) = ($size_x/2,$size_y/2);
my ($mul_x,$mul_y) = (1,1);
my $off_x = 20;
my $img_size = 50;
if ($vars{'qrcode_generator_layout'} == 1) {
$img_size = 100;
}
if ($vars{'qrcode_generator_layout'} > 1) {
ONO::Lib::PDF::Draw->line($canvas,0,$size_y/2,$size_x,$size_y/2,0.5);
}
if ($vars{'qrcode_generator_layout'} > 2) {
ONO::Lib::PDF::Draw->line($canvas,$size_x/2,0,$size_x/2,$size_y,0.5);
}
if ($vars{'qrcode_generator_layout'} > 4) {
$img_size = 32;
$off_x = 8;
ONO::Lib::PDF::Draw->line($canvas,0,$size_y/4, $size_x,$size_y/4, 0.5);
ONO::Lib::PDF::Draw->line($canvas,0,$size_y/4*3,$size_x,$size_y/4*3, 0.5);
}

for (my $q = 0; $q < $vars{'qrcode_generator_layout'}; $q++) {

if ($vars{'qrcode_generator_layout'} > 1) {
if ($q%2 == 0) {
$pos_y = $size_y/4;
} else {
$pos_y = $size_y/4*3;
}
if ($vars{'qrcode_generator_layout'} > 2) {

$pos_x = $size_x/4;
if ($q == 1 || $q == 2) {
$pos_x = $size_x/4*3;
}
}
if ($vars{'qrcode_generator_layout'} == 8) {
if ($q == 5 || $q == 6) {
$pos_x = $size_x/4*3;
}
$pos_y = $size_y/8;
if ($q == 2 || $q == 3) {
$pos_y = $size_y/8*3;
}
if ($q == 4 || $q == 5) {
$pos_y = $size_y/8*5;
}
if ($q == 6 || $q == 7) {
$pos_y = $size_y/8*7;
}
}
}

my $X = ($pos_x*$mul_x)-($img_size/2);
my $Y = ($pos_y*$mul_y)-($img_size/2)+$off_x;

ONO::Lib::PDF::Draw->image($canvas,$X,$Y,$img_size,$img_size,"images/qr/tmp/$FILE.jpg");

ONO::Lib::PDF::Draw->font('HB',12);

my $TITLE = $vars{'qrcode_generator_title'};
my ($code_up,$title_down);
if ($vars{'qrcode_generator_layout'} < 3) {
if ($vars{'qrcode_generator_layout'} == 1) {
$code_up = 12;
}
if ($vars{'qrcode_generator_layout'} == 2) {
$title_down = 12;
}
ONO::Lib::PDF::Draw->font('HB',36+(4-(length $vars{'qrcode_generator_code'})));
}
if ($vars{'qrcode_generator_layout'} == 8) {
$TITLE = "$vars{'qrcode_generator_code'} - $vars{'qrcode_generator_title'}";
if (!$vars{'qrcode_generator_code'}) {
$TITLE = $vars{'qrcode_generator_title'};
}
if (!$vars{'qrcode_generator_title'}) {
$TITLE = $vars{'qrcode_generator_code'};
}
} else {
ONO::Lib::PDF::Draw->text($canvas,$X+$img_size/2,$Y-$img_size*0.6-10-$code_up,$vars{'qrcode_generator_code'},"c");
}

if ($vars{'qrcode_generator_layout'} < 3) {
ONO::Lib::PDF::Draw->font('HB',24+(32-(length $TITLE)));
}

ONO::Lib::PDF::Draw->text($canvas,$X+$img_size/2,$Y-$img_size*0.6+$title_down,$TITLE,"c");
ONO::Lib::PDF::Draw->font('H',12);

my $print_line;
my $font_size = 12;
my $max_x = $size_x - 40;
if ($vars{'qrcode_generator_layout'} > 1) {
$max_x = $size_x/2 - 10;
}
my $app_pdf_y = $Y-$img_size*0.4;

foreach my $word (split(/ /,$vars{'qrcode_generator_text'})) {

if (ONO::Lib::PDF::Draw->string_width("$print_line $word","",$font_size) > $max_x) {

$print_line =~ s~^ ~~;
ONO::Lib::PDF::Draw->text($canvas,$X+$img_size/2,$app_pdf_y,$print_line,"c");
$print_line = $word;
$app_pdf_y = $app_pdf_y + $font_size/2.5;

} else{

$print_line .= " $word";

}

}

my $url_length = length $vars{'qrcode_generator_url'};

if ($url_length > 24) {
my $url_font = 12-$url_length/12;
ONO::Lib::PDF::Draw->font('H',$url_font);
}

ONO::Lib::PDF::Draw->text($canvas,$X+$img_size/2,$Y+$img_size+3,$vars{'qrcode_generator_url'},"c");
ONO::Lib::PDF::Draw->font('H',6);
ONO::Lib::PDF::Draw->text($canvas,$X+$img_size/2,$Y+$img_size+6,"QR Code generated with $ENV{'SERVER_NAME'}","c");
ONO::Lib::PDF::Draw->font('H',12);
}


}

ONO::Lib::PDF::Gen->close();

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

}

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

if ($PRINT) {

$WEB = $PRINT;

} else {

$WEB .= qq~<div class="abs" style="top:2px;width:100%;max-width:920px">
<$form>
$VARS
<div class="box_fabric" style="padding:5px 10px 5px 10px">
$CONF_BOX_TITLE
<div class="box_paper">
$RES
</div>
<div class="p2"></div>
</div>
</form>
</div>
~;

}

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

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

} else {

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

if ($vars{'app_request_uri'} =~ m~qrcode/(.*)/~) {
my $FILE = $1;
if (ONO::IO->exists("images/qr/$FILE.jpg") && ONO::IO->exists("images/qr/$FILE.txt")) {
$vars{'qrcode_generator_url'} = ONO::IO->load("images/qr/$FILE.txt");
$vars{'qrcode_generator_url'} =~ s~^(http|https)://~~g;
# $vars{'app_input_output_format'} = "pdf"
}
}

my ($TRANS,%sel,$DIS,$INFO,$CANCEL,$LAYOUT);

if ($vars{'app_input_output_format'} eq "pdf") {
$DIS = " disabled";
$CANCEL = qq~<a href="$action_url" class="button_yellow mt10">$BLK{'cancel'}</a>~;
foreach my $opt (1,2,4,8) {
my $BG = "white";
my $LAY = qq~<tr><td>1</td></tr>~;
if ($opt == 2) {
$LAY = qq~<tr class="bb"><td>1</td></tr><tr><td>2</td></tr>~;
}
if ($opt == 4) {
$BG = "green";
$LAY = qq~<tr class="bb"><td class="br">1</td><td>2</td></tr><tr><td class="br">3</td><td>4</td></tr>~;
}
if ($opt == 8) {
my @num;
for (my $i = 1; $i < 9; $i++) {
$num[$i] = qq~<div class="small lh125">$i</div>~;
}
$LAY = qq~<tr class="bb"><td class="p0 br">$num[1]</td><td class="p0">$num[2]</td></tr><tr class="bb"><td class="p0 br">$num[3]</td><td class="p0">$num[4]</td></tr>
<tr class="bb"><td class="p0 br">$num[5]</td><td class="p0">$num[6]</td></tr><tr><td class="p0 br">$num[7]</td><td class="p0">$num[8]</td></tr>
~;
}
$LAYOUT .= qq~<div id="qrcode_generator_layout_display_$opt" class="block64 bg_$BG bo fl mr10 center cursorlink" style="height:80px" onclick="qrcode_generator_layout_sel('$opt');">
<table class="wide_table" style="height:80px">$LAY</table>
</div>
~;
}

my $PAGES;
for (my $p = 1; $p < 11; $p++) {
$PAGES .= qq~<option value="$p">$p</option>~;
}

$LAYOUT = qq~<tr class="vtop">
<td class="p5 tar">$BLK{'layout'}:</td>
<td class="p10">
$LAYOUT
<input type="hidden" id="qrcode_generator_layout_id" name="qrcode_generator_layout" value="4">
<script>
function qrcode_generator_layout_sel(layout) {
for (var i = 1; i < 9; i++) {onojs_class('qrcode_generator_layout_display_'+i,'block64 bg_white bo fl mr10 center cursorlink')}
onojs_class('qrcode_generator_layout_display_'+layout,'block64 bg_green bo fl mr10 center cursorlink');
onojs_setvalue('qrcode_generator_layout_id',layout);
}
</script>
</td>
</tr>
<tr class="vtop">
<td class="pad5_2 tar">$BLK{'pages'}:</td>
<td class="pad5_2"><div class="select"><select name="qrcode_generator_pages">$PAGES</select></div></td>
</tr>
~;
} else {
$TRANS = "trans30";
$INFO = qq~<table class="wide_table mt10">
<tr class="vtop">
<td><img class="block48" src="/ono/osr/images/icons/crystal/64x64/apps/ktip.png" alt=""></td>
<td class="large col6">$txt[1] $txt[2] $txt[3] $txt[4]</td>
</tr>
</table>
~;
}

$sel{"app_input_output_format_$vars{'app_input_output_format'}"} = " selected";

my $VARS = ONO::FW::Apps::Core->input_vars(\%vars);
my $PRINT = qq~<div class="lightred mt10">$txt[8]</div>~;
if ($vars{'username'}) {
$PRINT = qq~<input type="submit" name="qrcode_generator_submit" value="$BLK{'print'}" class="button_green mt10">~;
}

$WEB .= qq~<div class="abs" style="top:2px;width:100%;max-width:920px">
<$form>
$VARS
<div class="box_fabric" style="padding:5px 10px 5px 10px">
$CONF_BOX_TITLE
<div class="box_paper">
<div id="app_input_output_opts" class="$TRANS">
<table class="wide_table mb10">
<tr>
<td class="pad5_2">$BLK{'Title'}:</td>
<td class="pad5_2 w80"><input type="text" name="qrcode_generator_title" value="$vars{'qrcode_generator_title'}" class="w95" maxlength="32"></td>
<td class="pad5_2">$BLK{'Code'}:</td>
<td class="pad5_2 w20"><input type="text" name="qrcode_generator_code" value="$vars{'qrcode_generator_code'}" class="w95" maxlength="4"></td>
</tr>
<tr>
<td class="pad5_2">$BLK{'Text'}:</td>
<td class="pad5_2" colspan="3"><input type="text" name="qrcode_generator_text" value="$vars{'qrcode_generator_text'}" class="w98" maxlength="128"></td>
</tr>
</table>
</div>
<div class="p10 mb10">
<div class="box_highlight">
<table class="wide_table">
<tr>
<td class="pad5_2 large nowrap">Website / URL:</td>
<td class="pad5_2">
<div class="select"><select name="qrcode_generator_protocol">
<option value="https">https://</option>
<option value="http">http://</option>
</select></div>
</td>
<td class="pad5_2 w100"><input type="text" name="qrcode_generator_url" value="$vars{'qrcode_generator_url'}" class="w98" maxlength="255"></td>
</tr>
</table>
</div>
</div>
<table class="default_table">
<tr>
<td class="pad5_2 tar">$BLK{'generate'}:</td>
<td class="pad5_2">
<div class="select"><select id="app_input_output_format_id" name="app_input_output_format" onchange="select_output();"$DIS>
<option value="jpg"$sel{"app_input_output_format_jpg"}>JPG (1 $BLK{'image'}, $BLK{'large'})</option>
<option value="png"$sel{"app_input_output_format_png"}>PNG (1 $BLK{'image'}, $BLK{'small'})</option>
<option value="pdf"$sel{"app_input_output_format_pdf"}>PDF (multiple pages/cards, with title, code, etc,...)</option>
</select></div>
</td>
</tr>
$LAYOUT
<tr>
<td></td>
<td class="pad5_2">$PRINT$CANCEL</td>
</tr>
</table>
</div>
<div class="p2"></div>
</div>
</form>
$INFO
</div>
<script>
function select_output() {
var output_format = onojs_getvalue('app_input_output_format_id');
if (output_format == 'pdf') {
onojs_class('app_input_output_opts','');
} else {
onojs_class('app_input_output_opts','trans30');
}
}
</script>
~;

$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);

return $WEB;

}

sub app_list {

my (
$self,
$app_opts_ref,
$app_opts_names_ref,
) = @_;

my @app_opts = @$app_opts_ref;
my @app_opts_names = @$app_opts_names_ref;
my $num = @app_opts;

my $HTML;

for (my $a = 0; $a < $num; $a++) {

my $SWITCH = ONO::Lib::UI::Check->switch("app_input_$app_opts[$a]",1,"r");

my $SEL;
for (my $s = 1; $s < 4; $s++) {
$SEL .= qq~<option value="$s">$s</option>~;
}

$HTML .= qq~<table class="default_table"><tr><td>$SWITCH</td><td><div class="select"><select name="app_input_$app_opts[$a]_num">$SEL</select></div></td><td class="pad5_2">$app_opts_names[$a]</td></tr></table>~;
if ($a == int($num/2)) {
$HTML .= qq~</td><td class="w50 p0">~;
}
}

return qq~<table class="wide_table"><tr class="vtop"><td class="w50 p0">$HTML</td></tr></table>~;

}

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

1;

__END__