ONO::FW::Edu::Apps::Modules::Vocabulary

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

use ONO::Lib::Encoding::HTML;

use ONO::IO;
use ONO::DB;

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

use ONO::FW::Apps::Core;
use ONO::FW::Apps::Core::Graphics;
use ONO::FW::Apps::Core::Lang;

use ONO::FW::Apps::PDF;

use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::Lib::PDF::Elements::EduLine;

use ONO::Lib::Parser;

use ONO::Lib::SQL::TableCreate;
use ONO::Lib::Basic;

use ONO::Lib::Lang::ToolBox;

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

my $WEB;

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

$vars{'app_input_print_options_title_default'} = ucfirst $BLK{$app};

# Known bug: "lang - img - mix - web_single" should allow to type vocs manually, but it offers multiple choice instead
# Not a major issue, but could be fixed in future...


# total_pix is the upper limit of /images/pix IDs
# this may need to be updated if new pix are being added to the DB

my $total_pix = ONO::FW::Apps::Core::Lang->total_pix();

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

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 .= ONO::FW::Apps::Core->output_paper_save($pdfkey,$BLK_ref,\%vars,$HTTP,$BASE,"$year$mon$mday");

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

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

if ($vars{'output_worksheet_maker'}) {

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

}

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

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

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

if ($vars{'output_web_mc_continue'}) {
$vars{'output_web_question_number'}++;
}
if ($vars{'output_web_mistakes_add'}) {
$vars{'output_web_mistakes'} = $vars{'output_web_mistakes'} + $vars{'output_web_mistakes_add'};
}
if (!$vars{'app_input_images_status'}) {
$vars{'app_input_images_status'} = 16;
}

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

if ($vars{'output_web_hide_flags'}) {
$hide_flags++;
}
if ($vars{'output_web_images_forced'}) {
$use_images_forced++;
}

if ($vars{'app_input_number_of_questions'} > $words_found) {
$vars{'app_input_number_of_questions'} = $words_found;
}

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

my $questions_per_page = 1;
my $print_list_multiplexer = 1;

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

$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 = 20;
if ($vars{'app_input_multiple_choice'}) {
$questions_per_page = 16;
}
if ($use_images) {
$questions_per_page = 12;
if ($vars{'app_input_images_status'} > 12) {
$questions_per_page = $vars{'app_input_images_status'};
}
if ($use_language2 eq "img") {
$questions_per_page = 8;
}
}

}

if ($vars{'output_web'}) {
if ($vars{'app_input_multiple_questions_per_page'}) {
$questions_per_page = 20;
if ($use_images) {
$questions_per_page = 12;
}
}
}

if ($vars{'output_print_vocs'}) {
$print_list_multiplexer = int($words_found/20)+1;
$vars{'app_input_multiple_choice'} = 0;
}

my @img_dims = (23,30);
my $img_dots = "......................................................";

if ($vars{'app_input_images_status'} > 12) {
@img_dims = (17,22);
if ($vars{'app_input_images_status'} == 20) {
@img_dims = (12,17.25);
}
for (my $d = 0; $d < $vars{'app_input_images_status'}/1.5; $d++) {
$img_dots .= ".";
}
}

my $item_numbers = 4;

if ($vars{'app_input_images_status'} == 12) {
$item_numbers = 3;
}
if ($vars{'app_input_images_status'} == 20) {
$item_numbers = 5;
}

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

my (@que,@res,@ans);

my ($pdf_x,$pdf_y) = (5,8);
my @corr_cache;

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

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,$item_numbers,"HV",$vars_ref);

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

if ($copy > 1 && !$vars{'output_print_vocs'}) {
@WORDLIST = ONO::Lib::Basic->randomize_array(@WORDLIST);
}

}

if ($vars{'output_web'}) {

$WEB .= qq~<$form>
<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">
~;

if ($vars{'app_input_multiple_questions_per_page'}) {

($stats_switches,$questions_per_page,$page,$pages) = ONO::FW::Apps::Core->multi_page_logic($page,\%vars,$questions_per_page,"pP");

if (!$vars{'output_web_finish'}) {

if ($pages > 1) {
$stats_switches .= "p";
}
if ($vars{'app_input_allow_hints'} && !$vars{'app_input_multiple_choice'} && $use_language2 ne "img") {
$stats_switches .= "H";
}
if ($vars{'app_input_langs_mix'}) {
$stats_switches .= "H";
}

$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"ctm$stats_switches");

}

my $custom_width;

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

} else {

if ($vars{'app_input_allow_hints'} && !$vars{'app_input_multiple_choice'} && $use_language2 ne "img") {
$stats_switches .= "H";
}

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

$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"ctmW$stats_switches");

}

}

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 {

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

if ($vars{'output_web'}) {
if ($use_images && $vars{'app_input_multiple_questions_per_page'}) {
$questions_per_page = 10;
}
}

if ($words_found < $questions_per_page) {
$questions_per_page = $words_found;
}

my $lang_img_single_mix_mode;

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

my $current_question = $i;

if ($vars{'output_print_vocs'}) {
$current_question = ($copy-1)*20 + $i;
}
if (!$vars{'app_input_multiple_questions_per_page'}) {
$current_question = $question_number,
}

# $WEB .= ONO::IO->devprint("current_question: $current_question, $question_number");

my @wp = split(/\^/,$WORDLIST[$current_question]);

# the following is required to make lang mixing work in single question mode

if (!$vars{'app_input_multiple_questions_per_page'} && ($vars{'output_web_continue_key'} || $vars{'output_web_mc_continue'})) {
$vars{"output_web_cache_langs_mix_$i"} = 0;
}

# randomly mix languages 1 and 2

if ($vars{'app_input_langs_mix'}) {

if ($use_language1 eq "img" || $use_language2 eq "img") {

if (!$vars{"output_web_cache_langs_mix_$i"} || $vars{'output_web_mc_continue'}) {
$vars{"output_web_cache_langs_mix_$i"} = 1;
if (int(rand(100)) > 50) {
$vars{"output_web_cache_langs_mix_$i"} = 2;
}
}
if ($vars{"output_web_cache_langs_mix_$i"} == 2) {
$lang_img_single_mix_mode = 1;
}
}


if ($vars{"output_web_cache_langs_mix_$i"}) {
if ($vars{"output_web_cache_langs_mix_$i"} == 2 && !$use_images_reverse) {
@wp = ONO::Lib::Basic->array_flip(@wp);
}
} else {
if (int(rand(100)) > 50) {
$vars{"output_web_cache_langs_mix_$i"} = 2;
if (!$use_images_reverse) {
@wp = ONO::Lib::Basic->array_flip(@wp);
}
} else {
$vars{"output_web_cache_langs_mix_$i"} = 1;
}
}
$WEB .= qq~<input type="hidden" name="output_web_cache_langs_mix_$i" value="$vars{"output_web_cache_langs_mix_$i"}">~;
}

$wp[1] =~ s~\((.*?)\)~~g;

($wp[0],$wp[1]) = &clean_words("",$wp[0],$wp[1]);

$vars{'cache_wp0'} = $wp[0];
$vars{'cache_wp1'} = $wp[1];

# fix a problem in mix mode...

if ($use_language1 eq "img" && $vars{'app_input_langs_mix'} && $vars{'output_web_cache_langs_mix_0'} == 2) {
if ($vars{'cache_wp1'} !~ /[A-Za-z]/ && $vars{'cache_wp1'} =~ /[0-9]/) {
($vars{'cache_wp0'},$vars{'cache_wp1'}) = ONO::Lib::Basic->array_flip($vars{'cache_wp0'},$vars{'cache_wp1'});
}
}

if ($vars{'output_web'}) {

# if ($stat_todo < $words_found) {
$stat_todo++;
# }

if ($vars{'app_input_multiple_questions_per_page'}) {

# no code required here in this app

} else {

if ($vars{"output_web_answer"} =~ /[A-Za-z0-9]/) {

my $check = $wp[1];
if ($wp[1] !~ /[A-Za-z]/ && $wp[1] =~ /[0-9]/) {
$check = $wp[0];
}

$WEB .= ONO::IO->devprint(qq~Checking "$vars{"output_web_answer"}" vs "$check"...~);

if ($vars{"output_web_answer"} ne $check) {

# $WEB .= ONO::IO->devprint(qq~ [BAD ANSWER]~);

$vars{'output_web_answer_status'} = 2;
$res[$i] = $vars{"output_web_cache_res_$i"};
if ($vars{"output_web_answer"} ne "") {
$vars{'output_web_mistakes'}++;
}

} else {

# $WEB .= ONO::IO->devprint(qq~ [OK]~);

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

}

}

}

}

# output paper

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

if ($wp[0] && $wp[1]) {

if ($vars{'app_input_multiple_choice'}) {

# multiple choice

my $off_x = 95;
if ($use_images) {
$off_x = 36 + $pdf_x;
} else {
if ($i > 7) {
$pdf_x = 92;
}
}

my $use_pos = int(rand(3));
my @alt;

if (($use_language2 eq "img" && $vars{"output_web_cache_langs_mix_$i"} != 2) || ($use_language1 eq "img" && $vars{"output_web_cache_langs_mix_$i"} == 2)) {

$vars{"correct_img_pos_$i"} = int(rand(3));
my @answers = &multi_choice_bad_answer_img("",$wp[0],3,1,$total_pix);
$answers[$vars{"correct_img_pos_$i"}] = $wp[0];

my $word = $wp[1];
if ($word !~ /[A-Za-z]/ && $word =~ /[0-9]/) {
$answers[$vars{"correct_img_pos_$i"}] = $wp[1];
$word = $wp[0];
}

ONO::Lib::PDF::Draw->text($canvas,$off_x-36,$pdf_y, $word);

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

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($answers[$a],$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x+2+$a*$img_dims[0]*1.6, $pdf_y+5, $img_dims[0]*1.3+1,$img_dims[0]*1.3+1,$IMG_URL,1,2);

ONO::Lib::PDF::Draw->checkbox($canvas,$pdf_x+$a*$img_dims[0]*1.6, $pdf_y+3, 4);

}

} else {

my $dont_flip;
if ($use_language2 eq "img" && $vars{"output_web_cache_langs_mix_$i"}) {
$dont_flip = 1;
}

my ($use_answer_short,@bad_answer) = &multi_choice_gen("",$wp[1],\@WORDLIST,$vars{"output_web_cache_langs_mix_$i"},$dont_flip);

for (my $i = 1; $i < 3; $i++) {

my ($false,$MARK) = &multi_choice_bad_answer("",$wp[1],$use_answer_short,$bad_answer[$i]);
@alt[$i] = "$false$MARK";

}

my $line_mul = 6;
my $line_ins = 0;
my $line_ans = 0;
my $last_column = $i-8;

if (!$use_images && $i < 8) {
$line_ans = 50;
}

if (!$use_images && $i > 7) {
$line_ans = -37;
}

my $correct = $wp[1];
# $correct =~ s~^(the|der|die|das|le|la|les) ~~;
# $correct =~ s~^l'~~;

my $maxlength = 50;

if ($use_images) {

$line_mul = int($img_dims[0]/3);
$line_ins = 26-$img_dims[0];

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($wp[0],$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x, $pdf_y-5, $img_dims[0]+2,$img_dims[0]+2,$IMG_URL,1,2);

if (length $wp[1] > 20) {
ONO::Lib::PDF::Draw->font('',10);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins+3, $pdf_y+($use_pos*$line_mul), $correct);
ONO::Lib::PDF::Draw->font('',12);
} else {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins+3, $pdf_y+($use_pos*$line_mul), $correct);
}

} else {

$maxlength = 37;

ONO::Lib::PDF::Draw->text($canvas,$pdf_x-$line_ins, $pdf_y, $wp[0], "","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+($use_pos*6), $correct,"","","m",$maxlength);
}

if ($use_pos == 0) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul, $alt[1], "","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul*2, $alt[2], "","","m",$maxlength);
}
if ($use_pos == 1) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y, $alt[1], "","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul*2, $alt[2], "","","m",$maxlength);
}
if ($use_pos == 2) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y, $alt[1], "","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul, $alt[2], "","","m",$maxlength);
}
for (my $b = 0; $b < 3; $b++) {
ONO::Lib::PDF::Draw->checkbox($canvas,$off_x-$line_ins-$line_ans-3, $pdf_y-3+($b*$line_mul), 3);
}

$vars{"print_line_ans_$i"} = $line_ans;

$vars{"print_colums_offset_$i"} = $line_ins+$line_ans;

}

if (!$use_images && $i < 9 && $i%2 == 0) {
ONO::Lib::PDF::Draw->line($canvas,-2,$pdf_y+14,174,$pdf_y+14,0.75,"0:188:188:188");
ONO::Lib::PDF::Draw->line($canvas,87.5,$pdf_y-7,87.5,$pdf_y+37.5,0.75,"0:188:188:188");
}

$corr_cache[$i] = "$use_pos\^$alt[1]\^$alt[2]\^";

if ($use_images) {

$pdf_y = $pdf_y + $img_dims[1];
if ($use_language2 eq "img") {
$pdf_y = $pdf_y + 25.5;
} else {
if ($i%2 != 0) {
$pdf_y = $pdf_y + 3.5;
}
}
if ($pdf_y > 180) {
$pdf_x = 95-13+$img_dims[0]/2;
$pdf_y = 8;
}

} else {

$pdf_y = $pdf_y + 20;
if ($i%2 != 0) {
$pdf_y = $pdf_y + 7.5;
}
if ($pdf_y > 180) {
$pdf_y = 8;
}

}

} else {

# standard (not multiple choice)

if ($use_images) {

my ($do_switch_mix,$no_img_but_text);
if ($vars{'app_input_langs_mix'} && !$vars{'output_print_vocs'} && int(rand(100)) > 49) {
$do_switch_mix++;
if ($use_language1 eq "img") {
$no_img_but_text = 1;
}
}

if ($use_language1 eq "img" || !$use_language2 eq "img" || $do_switch_mix || $vars{'output_print_vocs'}) {

# dirty fix here...

my $img = $wp[0];
if ($wp[0] =~ /[A-Za-z]/) {
$img = $wp[1];
}

if (!$no_img_but_text) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($img,$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x, $pdf_y-5,$img_dims[0]+2,$img_dims[0]+2,$IMG_URL,1,2);

}

} else {

ONO::Lib::PDF::Draw->square($canvas,$pdf_x, $pdf_y-5, $img_dims[0]+2,1,"","",2);

}

# dirty fix here...

my $show = $wp[0];
if ($wp[1] =~ /[A-Za-z]/) {
$show = $wp[1];
}

if ($no_img_but_text) {

ONO::Lib::PDF::Draw->text($canvas,$pdf_x+$img_dims[1], $pdf_y, $show);

} else {

if ($use_language1 ne "img" && ($vars{'output_print_vocs'} || $use_language2 eq "img") && !$do_switch_mix) {

ONO::Lib::PDF::Draw->text($canvas,$pdf_x+$img_dims[1], $pdf_y, $show);

} else {

if (($use_language1 ne "img" && !$do_switch_mix) || $vars{'output_print_vocs'}) {

ONO::Lib::PDF::Draw->text($canvas,$pdf_x+$img_dims[1], $pdf_y, $show);

} else {

if ($vars{'app_input_lines_type'} eq "edulines") {

ONO::Lib::PDF::Elements::EduLine->eduline($canvas,$pdf_x+$img_dims[1],$pdf_y,$pdf_x+$img_dims[1]+58,$vars{'app_input_lines_height'});

} else {

ONO::Lib::PDF::Draw->font('',9);
for (my $l = 1; $l < 3; $l++) {
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+$img_dims[1], $pdf_y-4+$l*(($img_dims[0]/2)), $img_dots);
}
ONO::Lib::PDF::Draw->font('',12);

}

}

}

}

$pdf_y = $pdf_y + $img_dims[1];

if ($i%2 != 0) {
$pdf_y = $pdf_y + 3.5;
}

if ($pdf_y > 180) {
$pdf_x = 95-13+$img_dims[0]/2;
$pdf_y = 8;
}

} else {

my $DOTS = ".........................";
my $whilecounter;
while (ONO::Lib::PDF::Draw->string_width("$wp[0] $DOTS") < 85 && $whilecounter < 1024) {
$whilecounter++;
$DOTS .= ".";
}

my $flag_ins = 0;

if ($vars{'app_input_langs_mix'}) {
my $flag = $use_language2;
if ($vars{"output_web_cache_langs_mix_$i"} == 2) {
$flag = $use_language1;
}
$flag_ins = 6.5;
my $flag_y = 4;
if ($vars{'output_print_vocs'}) {
$flag_y = 3;
}
ONO::Lib::PDF::Draw->image($canvas,$pdf_x+77, $pdf_y-$flag_y,5,3,"ono/osr/images/flags/countries_large_tld/$flag.jpg",0.1);
}

ONO::Lib::PDF::Draw->text($canvas,$pdf_x, $pdf_y, $wp[0]);
if ($vars{'output_print_vocs'}) {
ONO::Lib::PDF::Draw->text($canvas,82.5+$flag_ins, $pdf_y, $wp[1]);
}

ONO::Lib::PDF::Draw->font('',9);
if (!$vars{'output_print_vocs'}) {
ONO::Lib::PDF::Draw->text($canvas,170, $pdf_y, "....................................................................................................","r");
}
ONO::Lib::PDF::Draw->color(0.7,0.7,0.7);
ONO::Lib::PDF::Draw->text($canvas,80, $pdf_y, $DOTS,"r");
ONO::Lib::PDF::Draw->font('',12);
ONO::Lib::PDF::Draw->color(0,0,0);

$pdf_y = $pdf_y + 8;
if (($i+1)%5 == 0) {
$pdf_y = $pdf_y + 7.5;
}
}
}
}
}

if ($vars{'output_web'}) {

$WEB .= qq~<input type="hidden" name="output_web_cache_res_$i" value="$res[$i]">~;

if ($vars{'app_input_multiple_questions_per_page'}) {

my ($BG,$is_correct);

# data = question, correct answer, given answer

my @data = &get_data("",$wp[0],$wp[1],$vars{"output_web_answer_$i"});

my $PLA = "?";
if (ONO::IO->devstation) {
$PLA = $data[1];
}

my $HINT;
if ($vars{'app_input_allow_hints'}) {
$HINT = qq~<a href="javascript:void(0);" onclick="hint('$i');" class="col3">
<div class="rel" style="top:4px">
<div class="block20 bg_dark radius20 abs" style="top:0px;left:0px">
<img class="block16 abs" src="/ono/osr/images/icons/crystal/16x16/apps/ktip.png" style="top:2px;left:2px" alt="">
</div>
<div id="output_web_hints_counter_$i" class="small mr5 abs" style="top:-6px;left:21px">$vars{"output_web_hints_$i"}</div>
</div>
</a>
<input type="hidden" id="output_web_hints_$i" name="output_web_hints_$i" value="$vars{"output_web_hints_$i"}">
<input type="hidden" id="output_web_correct_${i}" name="output_web_correct_${i}" value="$data[1]">
~;
}

my $FIELD = qq~<input type="text" id="output_web_answer_${i}_id" name="output_web_answer_$i" value="$data[2]" class="w95" placeholder="$PLA">~;

if ($use_language1 eq "img") {
$FIELD = qq~<div class="rel">
<div class="abs" style="top:-5px;left:0px"><img class="flag" src="/ono/osr/images/flags/languages/$use_language2.png" alt=""></div>
<input type="text" id="output_web_answer_${i}_id" name="output_web_answer_$i" value="$data[2]" class="w90 center" placeholder="$PLA">
</div>
~;
}

if ($data[2] =~ /[A-Za-z0-9]/) {
$BG = " bg_red";
$stat_todo--;
if ($data[2] eq $data[1]) {
$BG = " bg_green";
$FIELD = qq~<div class="bold green">$data[1]</div><input type="hidden" name="output_web_answer_$i" value="$data[2]">~;
$stat_correct++;
$is_correct++;
} else {
$stat_wrong++;
$vars{'output_web_mistakes'}++;
}
}

if (!$is_correct && !$focus_on) {
$FIELD .= qq~<script>document.getElementById('output_web_answer_${i}_id').focus();</script>~;
$focus_on++;
}

if ($data[0] && $data[1]) {

if ($use_images) {

if ((!$use_images_reverse && $vars{"output_web_cache_langs_mix_$i"} == 2) || ($use_images_reverse && $vars{"output_web_cache_langs_mix_$i"} != 2)) {

if ($use_images_reverse) {
($data[0],$data[1]) = ($data[1],$data[0]);
}

my @img_dis = split(/;/,$vars{"output_web_cache_langs_multiimg_$i"});

if ($vars{'output_web_continue'}) {
@img_dis = ();
$vars{"output_web_multiimg_status_$i"} = 0;
}

if (!$img_dis[0]) {
my $img_num = @IMGS;
my @img_alt = ($data[1]);
my $whilecounter;
for (my $a = 1; $a < 3; $a++) {
while (!$img_alt[$a] && $whilecounter < 1024) {
$whilecounter++;
my $test = $IMGS[int(rand($img_num))];
my @tp = split(/;/,$test);
if ($tp[0] && $tp[1] && $img_alt[0] ne $tp[0] && $img_alt[1] ne $tp[0] && $data[0] ne $tp[1] && $data[1] ne $tp[1]) {
$img_alt[$a] = $tp[0];
}
}
while ((!$img_alt[$a] || !ONO::IO->exists("images/pix/preview/rgb/$img_alt[$a].jpg")) && $whilecounter < 4096) {
$whilecounter++;
$img_alt[$a] = ONO::Lib::Basic->add_leading_zeroes(int(rand($total_pix)),4);
}
}

@img_dis = (@img_alt,0);
my $rand = int(rand(100));
if ($rand > 33) {
@img_dis = ($img_alt[1],$img_alt[0],$img_alt[2],1);
if ($rand > 66) {
@img_dis = ($img_alt[1],$img_alt[2],$img_alt[0],2);
}
}
}

my (@IMG,$multiimg_status);

for (my $x = 0; $x < 3; $x++) {
my $color = "red";
my $trans = 50;
my $trans_done = 30;
my $JS = "onojs_hide('img_multi_${i}_${x}');onojs_block('img_multi_${i}_${x}_res');";
if ($x == $img_dis[3]) {
$color = "green";
$trans = 90;
$trans_done = 100;
my @not = (1,2);
if ($x == 1) {
@not = (0,2);
}
if ($x == 2) {
@not = (0,1);
}
$JS .= "onojs_class('img_multi_${i}_$not[0]_all','trans20');onojs_class('img_multi_${i}_$not[1]_all','trans20');";
$JS .= "onojs_setvalue('output_web_multiimg_status_${i}_id','1');";
} else {
$JS .= "output_web_mistakes_inc();";
}

if ($vars{"output_web_multiimg_status_$i"}) {

if ($x == 0) {
$BG = "bg_green";
$multiimg_status++;
$stat_correct++;
}

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($img_dis[$x],$vars{'username'},$community);

$IMG[$x] = qq~<div id="img_multi_${i}_${x}_res" class="box_$color trans$trans_done p2 block72 auto">
<img class="block radius5 trans$trans" src="/$IMG_URL" style="width:100%;height:auto" alt="">
</div>
~;

} else {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($img_dis[$x],$vars{'username'},$community);

$IMG[$x] = qq~<div id="img_multi_${i}_${x}_all">
<div id="img_multi_${i}_${x}" class="box_paper p2 block72 auto cursorlink"
onmouseover = "onojs_class('img_multi_${i}_${x}','box_yellow p2 block72 auto cursorlink');"
onmouseout = "onojs_class('img_multi_${i}_${x}','box_paper p2 block72 auto cursorlink');"
onclick = "$JS">
<img class="block radius5" src="/$IMG_URL" style="width:100%;height:auto" alt="">
</div>
<div id="img_multi_${i}_${x}_res" class="box_$color p2 block72 auto hide">
<img class="block radius5 trans$trans" src="/$IMG_URL" style="width:100%;height:auto" alt="">
</div>
</div>
~;

}
}

if ($i == 0) {
$WEB .= qq~<input id="output_web_mistakes_add_id" type="hidden" name="output_web_mistakes_add" value="0">~;
}

$WEB .= qq~<tr class="$BG">
<td>
<table class="wide_table">
<tr>
<td class="p0">
<table class="default_table auto">
<tr>
<td><div class="rel" style="left:-5px;top:5px">$IMG[0]</div></td>
<td><div class="rel" style="left:-5px">$IMG[1]</div></td>
</tr>
</table>
<div class="rel" style="top:-10px">$IMG[2]</div>
</td>
</tr>
<tr>
<td class="p0 center">
<div class="rel" style="height:20px;top:-6px">
<div class="inline auto"><div class="box_highlight pad10_0">$data[0]</div></div>
</div>
</td>
</tr>
</table>
<input type="hidden" name="output_web_cache_langs_multiimg_$i" value="$img_dis[0];$img_dis[1];$img_dis[2];$img_dis[3]">
<input type="hidden" id="output_web_multiimg_status_${i}_id" name="output_web_multiimg_status_$i" value="$multiimg_status">
</td>
</tr>
~;

} else {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($data[0],$vars{'username'},$community);

$WEB .= qq~<tr class="$BG">
<td>
<table class="wide_table">
<tr>
<td>
<div class="box_paper block128 p5 auto rel">
<img class="block radius5" src="/$IMG_URL" style="width:100%;height:auto" alt="">
<div class="abs" style="top:108px;right:14px">$HINT</div>
</div>
</td>
</tr>
<tr>
<td class="center"><div style="height:32px">$FIELD</div></td>
</tr>
</table>
</td>
</tr>
~;
}

} else {

my $FLAG;
if (!$hide_flags) {

my $flag = $use_language2;
if ($vars{"output_web_cache_langs_mix_$i"} == 2) {
$flag = $use_language1;
}
$FLAG = qq~<img class="flag" src="/ono/osr/images/flags/languages/$flag.png" alt="">~;

}

if ($use_images_forced) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($data[0],$vars{'username'},$community);

$data[0] = qq~<a href="javascript:void(0);" onclick="onojs_block('output_web_image_preview_box');
onojs_setsrc('output_web_image_preview','$BASE/$IMG_URL');">
<img class="block32 radius5 fr" src="/$IMG_URL" alt="">
</a>
~;

}

$WEB .= qq~<tr class="bt bb$BG">
<td class="w50 pad5_2 tar"><div class="lh125">$data[0]</div></td>
<td>$FLAG</td>
<td class="w50 pad5_2">$FIELD</td>
<td><div class="block32">$HINT</div></td>
</tr>
~;

}

}

}

if ($use_images) {
if ($i%2 != 0) {
$WEB .= ONO::FW::Apps::Core->multi_frame_split($multi_frame_custom_width);
}
} else {
if ($i == 9) {
$WEB .= ONO::FW::Apps::Core->multi_frame_split;
}
}

}

}

if ($vars{'output_web'}) {

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

if ($questions_per_page == 1) {

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

my $flag1 = $use_language1;
my $flag2 = $use_language2;
if ($vars{"output_web_cache_langs_mix_0"} == 2) {
$flag1 = $use_language2;
$flag2 = $use_language1;
}

my @data = &get_data("",$vars{'cache_wp0'},$vars{'cache_wp1'},$vars{"output_web_answer_$question_number"});

my $img_lang_multi_mix_mode_alt;
if ($use_language1 eq "img" && $vars{'app_input_langs_mix'} && $vars{"output_web_cache_langs_mix_0"} == 2) {
$img_lang_multi_mix_mode_alt = 1;
}

if ((($vars{'app_input_multiple_choice'} && $use_language2 ne "img") || $lang_img_single_mix_mode) && !$img_lang_multi_mix_mode_alt) {

my $use_answer = $data[1];

my ($use_answer_short,@bad_answer) = &multi_choice_gen("",$use_answer,\@WORDLIST,$vars{"output_web_cache_langs_mix_0"},$lang_img_single_mix_mode);

my $RIGHT = qq~<td id="td_answer_correct" class="p5">
<div class="inline auto">
<div id="button_answer_correct_1" class="button button_big"
onclick="onojs_hide('button_answer_correct_1');
onojs_block('button_answer_correct_2');
onojs_class('td_answer_false_1','p5 trans30');
onojs_class('td_answer_false_2','p5 trans30');
onojs_class('td_answer_false_3','p5 trans30');
onojs_hide('question_flag');
onojs_block('done_spinwheel_div');
onojs_setsrc('done_spinwheel','$BASE/ono/osr/images/loading/wheel_32.gif');
timer_correct('2');
;">$use_answer</div>
<div id="button_answer_correct_2" class="button_green button_big hide">
<img class="inline" src="/ono/osr/images/icons/crystal/32x32/ono/ok.png" alt="">
$use_answer
</div>
</div>
<input id="timer_correct_id" type="hidden" name="timer_correct_name" value="2">
<input type="hidden" name="output_web_mc_continue" value="1">
<input id="output_web_mistakes_add_id" type="hidden" name="output_web_mistakes_add" value="0">
</td>
~;

my @FALSE;
for (my $i = 1; $i < 4; $i++) {

my ($false,$MARK,$false_help) = &multi_choice_bad_answer("",$use_answer,$use_answer_short,$bad_answer[$i]);

$FALSE[$i] = qq~<td id="td_answer_false_$i" class="p5">
<div class="inline auto">
<div id="button_answer_false_$i\_1" class="button button_big"
onclick="onojs_hide('button_answer_false_$i\_1');onojs_block('button_answer_false_$i\_2');output_web_mistakes_inc();">$false$MARK</div>
<div id="button_answer_false_$i\_2" class="button_red button_big hide">
<img class="inline" src="/ono/osr/images/icons/crystal/32x32/ono/delete.png" alt="">
$bad_answer[$i]$false_help
</div>
</div>
</td>
~;
}

my ($img_mode,$TR);
if ($data[0] =~ /[0-9]/ && $data[0] !~ /[A-Za-z]/) {
$img_mode++;
} else {
$TR = "</tr><tr>";
}

my $rand = int(rand(100));
my $QUESTIONS = qq~<tr>$RIGHT$TR$FALSE[1]</tr><tr>$FALSE[2]$TR$FALSE[3]</tr>~;
if ($rand > 24) {
$QUESTIONS = qq~<tr>$FALSE[1]$TR$RIGHT</tr><tr>$FALSE[2]$TR$FALSE[3]</tr>~;
}
if ($rand > 49) {
$QUESTIONS = qq~<tr>$FALSE[1]$TR$FALSE[2]</tr><tr>$RIGHT$TR$FALSE[3]</tr>~;
}
if ($rand > 74) {
$QUESTIONS = qq~<tr>$FALSE[1]$TR$FALSE[2]</tr><tr>$FALSE[3]$TR$RIGHT</tr>~;
}

my $QUEST = qq~<div class="mt40 mb40">
<div class="box_highlight inline auto" style="min-width:320px">
<div class="pad10_2">
<table class="default_table auto">
<tr>
<td>
<div id="question_flag" class="p2"><img class="flag_large mr10" src="/ono/osr/images/flags/languages/$flag1.png" alt=""></div>
<div id="done_spinwheel_div" class="hide">
<img id="done_spinwheel" class="block20 mr10" src="/ono/osr/images/spacer/trans.gif" alt="">
</div>
</td>
<td>
<div class="xlarge center">$data[0]</div>
</td>
</tr>
</table>
</div>
</div>
</div>
~;

if ($img_mode) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($data[0],$vars{'username'},$community);

$QUEST = qq~<div class="mt20 mb20">
<div class="box_highlight inline auto" style="min-width:320px">
<div class="pad10_2">
<table class="default_table auto">
<tr>
<td>
<div class="rel">
<div class="abs" style="top:0px;left:-30px">
<div id="question_flag"></div>
<div id="done_spinwheel_div" class="hide">
<img id="done_spinwheel" class="block20 mr10" src="/ono/osr/images/spacer/trans.gif" alt="">
</div>
</div>
<div class="bo radius10 auto"><img class="block150 radius10" src="/$IMG_URL" alt=""></div>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
~;
}

$WEB .= qq~$QUEST
<table class="default_table auto">
$QUESTIONS
</table>
~;

} else {

my $HINT;
if ($vars{'app_input_allow_hints'}) {
$HINT = qq~<td>
<a href="javascript:void(0);" onclick="hint('0');" class="col3">
<div class="rel small" style="width:24px;top:-8px;left:4px">
<div class="block20 bg_dark radius20 abs" style="top:0px;left:0px">
<img class="block16 abs" src="/ono/osr/images/icons/crystal/16x16/apps/ktip.png" style="top:2px;left:2px" alt="">
</div>
<div id="output_web_hints_counter_0" class="small mr5 abs" style="top:-18px;left:18px">$vars{"output_web_hints_0"}</div>
</div>
</a>
<input type="hidden" id="output_web_hints_0" name="output_web_hints_0_special_transmit" value="$vars{"output_web_hints_0"}">
<input type="hidden" id="output_web_correct_0" name="output_web_correct_0_dont_transmit" value="$data[1]">
</td>
~;
$WEB .= ONO::FW::Apps::Core->hint_script_v2("length/2","(length/3*2)+1",$vars{'output_web_hints'},"output_web_answer_id");
}

if ($use_language1 eq "img" && !$img_lang_multi_mix_mode_alt) {

my $IMG = $data[0];
if ($data[0] =~ /[A-Za-z]/ && $data[1] !~ /[A-Za-z]/ && $data[1] =~ /[0-9]/) {
$IMG = $data[1];
}

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($IMG,$vars{'username'},$community);

$WEB .= ONO::IO->devprint("/$IMG_URL");

$WEB .= qq~<div class="mt20 mb20">
<div class="box_highlight inline auto" style="min-width:320px">
<div class="pad10_2">
<div class="bo radius10 inline auto"><img class="block200 auto radius10" src="/$IMG_URL" alt=""></div>
</div>
</div>
</div>
~;

} else {

my $QUESTION = $data[0];

if ($QUESTION !~ /[A-Za-z]/ && $QUESTION =~ /[0-9]/) {
$QUESTION = $data[1];
}

$WEB .= qq~<div class="mt40 mb40">
<div class="box_highlight inline auto" style="min-width:320px">
<div class="pad10_2">
<table class="default_table auto">
<tr>
<td>
<div id="question_flag"><img class="flag_large mr10" src="/ono/osr/images/flags/languages/$flag1.png" alt=""></div>
<div id="done_spinwheel_div" class="hide"><img id="done_spinwheel" class="block20 mr10" src="/ono/osr/images/spacer/trans.gif" alt=""></div>
</td>
<td><div class="xlarge center">$QUESTION</div></td>
</tr>
</table>
</div>
</div>
</div>
~;

}

if ($use_language2 eq "img" || $img_lang_multi_mix_mode_alt) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($data[0],$vars{'username'},$community);

my $correct_answer = qq~<a href="javascript:void(0);" onclick="onojs_class('correct_answer','p10 radius10 bg_green');
onojs_class('bad_answer_0','p10 radius10 trans30');
onojs_class('bad_answer_1','p10 radius10 trans30');
onojs_class('bad_answer_2','p10 radius10 trans30');
onojs_hide('question_flag');
onojs_block('done_spinwheel_div');
onojs_setsrc('done_spinwheel','$BASE/ono/osr/images/loading/wheel_32.gif');
timer_correct('2');">
<div class="p5 fl">
<div id="correct_answer" class="p10 radius10"><div class="bo radius10"><img class="block128 radius10" src="/$IMG_URL" alt=""></div></div>
</div>
</a>
~;

my @bad_answer = &multi_choice_bad_answer_img("",$data[0],3,0,$total_pix);

my @alts = ($correct_answer,$bad_answer[0],$bad_answer[1],$bad_answer[2]);

my $rand = int(rand(100));
if ($rand > 24) {
@alts = ($bad_answer[0],$correct_answer,$bad_answer[1],$bad_answer[2]);
if ($rand > 49) {
@alts = ($bad_answer[0],$bad_answer[1],$correct_answer,$bad_answer[2]);
if ($rand > 74) {
@alts = ($bad_answer[0],$bad_answer[1],$bad_answer[2],$correct_answer);
}
}
}

$WEB .= qq~<div class="inline w100 auto" style="max-width:640px">~;

for (my $a = 0; $a < 4; $a++) {
$WEB .= qq~<div class="fl">$alts[$a]</div>~;
}

$WEB .= qq~</div>
<input id="timer_correct_id" type="hidden" name="timer_correct_name" value="2">
<input type="hidden" name="output_web_mc_continue" value="1">
<input id="output_web_mistakes_add_id" type="hidden" name="output_web_mistakes_add" value="0">
~;


} else {

if ($vars{'output_web_answer_status'} == 1) {
$HINT = qq~<td class="green">$vars{'cache_wp1'}</td>~;
}

$WEB .= ONO::IO->devprint($vars{'cache_wp1'});

if ($flag2 eq "img") {
$flag2 = $flag1;
}

$WEB .= ONO::FW::Apps::Core->check_single(
qq~<td><img class="flag_large" src="/ono/osr/images/flags/languages/$flag2.png" alt=""></td>~,
$HINT,
320,
int((length $vars{'cache_wp1'})*1.5),
$BLK_ref,
\%vars,
"CfM",
);

}

}

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

} else {

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

my $remaining = $stat_todo;
if ($use_images) {
$remaining = ($page*$questions_per_page)-$stat_correct;
$remaining = $questions_per_page-$stat_correct;
}

# $WEB.=qq~$remaining = ($page*$questions_per_page)-$stat_correct~;

$WEB .= ONO::FW::Apps::Core->check_multi($BLK_ref,$remaining+$stat_wrong,$page,$pages,"",\%vars);

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

if ($vars{'app_input_allow_hints'}) {
$WEB .= ONO::FW::Apps::Core->hint_script_v2("length/2","(length/3*2)+1",$vars{'output_web_hints'});
}

}

$WEB .= qq~ <input type="hidden" name="output_web_hide_flags" value="$hide_flags">
<input type="hidden" name="output_web_images_forced" value="$use_images_forced">
</form>
~;

}

}

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,$item_numbers,"CHV",$vars_ref);

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

my ($pdf_x,$pdf_y) = (5,8);

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

my @wp = split(/\^/,$WORDLIST[$c]);

if ($wp[0] && $wp[1]) {

if ($vars{'app_input_multiple_choice'}) {

my $off_x = 95;
if ($use_images) {
$off_x = 36 + $pdf_x;
}

my @cp = split(/\^/,$corr_cache[$c]);

if (($use_language2 eq "img" && $vars{"output_web_cache_langs_mix_$c"} != 2) || ($use_language1 eq "img" && $vars{"output_web_cache_langs_mix_$c"} == 2)) {

ONO::Lib::PDF::Draw->text($canvas,$off_x-36,$pdf_y,$wp[1]);

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

if ($a == $vars{"correct_img_pos_$c"}) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($wp[0],$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x+2+$a*$img_dims[0]*1.6, $pdf_y+5, $img_dims[0]*1.3+1,$img_dims[0]*1.3+1,$IMG_URL,1,2);
ONO::Lib::PDF::Draw->checkbox($canvas,$pdf_x+$a*$img_dims[0]*1.6, $pdf_y+3, 4,"",1);

} else {

ONO::Lib::PDF::Draw->square($canvas,$pdf_x+2+$a*$img_dims[0]*1.6, $pdf_y+5, $img_dims[0]*1.3+2,1,"","",2);
ONO::Lib::PDF::Draw->checkbox($canvas,$pdf_x+$a*$img_dims[0]*1.6, $pdf_y+3, 4);

}


}

} else {

my $line_mul = 6;
my $line_ins = 0;
my $line_ans = $vars{"print_line_ans_$c"};

if (!$use_images && $c > 7) {
$pdf_x = 92;
}

my $maxlength = 50;

if ($use_images) {

$line_mul = int($img_dims[0]/3);
$line_ins = 26-$img_dims[0];

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($wp[0],$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x, $pdf_y-5, $img_dims[0]+2,$img_dims[0]+2,$IMG_URL,1,2);

} else {

$maxlength = 37;

ONO::Lib::PDF::Draw->text($canvas,$pdf_x, $pdf_y, $wp[0]);
}

for (my $b = 0; $b < 3; $b++) {
my $chk;
if ($cp[0] == $b) {
$chk = 1;
}
ONO::Lib::PDF::Draw->checkbox($canvas,$off_x-6-$line_ins-$line_ans+3, $pdf_y-3+($b*$line_mul), 3,0,$chk);
}

ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+($cp[0]*$line_mul), $wp[1],"","","m",$maxlength);

ONO::Lib::PDF::Draw->color(0.7,0.7,0.7);

if ($cp[0] == 0) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul, $cp[1],"","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul*2, $cp[2],"","","m",$maxlength);
}
if ($cp[0] == 1) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y, $cp[1],"","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul*2, $cp[2],"","","m",$maxlength);
}
if ($cp[0] == 2) {
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y, $cp[1],"","","m",$maxlength);
ONO::Lib::PDF::Draw->text($canvas,$off_x-$line_ins-$line_ans+3, $pdf_y+$line_mul, $cp[2],"","","m",$maxlength);
}

ONO::Lib::PDF::Draw->color(0,0,0);

if (!$use_images && $c < 9 && $c%2 == 0) {
ONO::Lib::PDF::Draw->line($canvas,-2,$pdf_y+14,174,$pdf_y+14,0.75,"0:188:188:188");
ONO::Lib::PDF::Draw->line($canvas,87.5,$pdf_y-7,87.5,$pdf_y+37.5,0.75,"0:188:188:188");
}

}

if ($use_images) {

$pdf_y = $pdf_y + $img_dims[1];

if ($use_language2 eq "img") {
$pdf_y = $pdf_y + 25.5;
} else {
if ($c%2 != 0) {
$pdf_y = $pdf_y + 3.5;
}
}

if ($pdf_y > 180) {
$pdf_x = 95-13+$img_dims[0]/2;
$pdf_y = 8;
}

} else {

$pdf_y = $pdf_y + 20;
if ($c%2 != 0) {
$pdf_y = $pdf_y + 7.5;
}
if ($pdf_y > 180) {
$pdf_y = 8;
}

}

} else {

if ($use_images) {

my $IMG_URL = ONO::FW::Apps::Core::Lang->lang_image_url_generator($wp[0],$vars{'username'},$community);

ONO::Lib::PDF::Draw->image($canvas,$pdf_x, $pdf_y-5, $img_dims[0]+2,$img_dims[0]+2,$IMG_URL,1,2);

ONO::Lib::PDF::Draw->font('',9);
ONO::Lib::PDF::Draw->text($canvas,$pdf_x+$img_dims[1], $pdf_y-4+($img_dims[0]/2)-1, $wp[1]);
ONO::Lib::PDF::Draw->font('',12);

$pdf_y = $pdf_y + $img_dims[1];
if ($c%2 != 0) {
$pdf_y = $pdf_y + 3.5;
}
if ($pdf_y > 180) {
$pdf_x = 95-13+$img_dims[0]/2;
$pdf_y = 8;
}

} else {

my $DOTS = ".........................";
my $whilecounter;
while (ONO::Lib::PDF::Draw->string_width("$wp[0] $DOTS") < 85 && $whilecounter < 1024) {
$whilecounter++;
$DOTS .= ".";
}

ONO::Lib::PDF::Draw->text($canvas,$pdf_x, $pdf_y, $wp[0]);

ONO::Lib::PDF::Draw->text($canvas,82, $pdf_y, $wp[1]);

ONO::Lib::PDF::Draw->font('',9);
ONO::Lib::PDF::Draw->color(0.7,0.7,0.7);
ONO::Lib::PDF::Draw->text($canvas,80, $pdf_y, $DOTS,"r");
ONO::Lib::PDF::Draw->font('',12);
ONO::Lib::PDF::Draw->color(0,0,0);


$pdf_y = $pdf_y + 8;
if (($c+1)%5 == 0) {
$pdf_y = $pdf_y + 7.5;
}
}
}
}
}
}
}

if ($vars{'output_web'} && !$vars{'output_web_finish'}) {

($stat_correct,$stat_todo_total) = ONO::FW::Apps::Core->stats_multi_pages($vars{'app_input_number_of_questions'},$stat_correct,$stat_wrong,$page,$pages,$questions_per_page);

if ($questions_per_page == 1) {

$WEB .= ONO::IO->devprint("XXX - $vars{'output_web_mistakes'} - $vars{'output_web_mistakes_add'}");

$stat_correct = $question_number-1;

my $mistakes = $vars{'output_web_mistakes'}-1;
if ($vars{'output_web_mistakes'} == 1 && !$vars{'app_input_multiple_questions_per_page'}) {
$mistakes = 1;
}
if ($vars{'output_web_mistakes'} == 1 && $vars{'output_web_mistakes_add'}) {
$mistakes = $vars{'output_web_mistakes'}+$vars{'output_web_mistakes_add'}-1;
}

$WEB = ONO::FW::Apps::Core->stats_replace(
$WEB,
$stat_correct,
$stat_wrong,
$stat_todo_total-$stat_correct,
$mistakes,
"",
"",
"",
$vars{'output_web_hints'},
);

} else {

$WEB = ONO::FW::Apps::Core->stats_replace(
$WEB,
$stat_correct,
$stat_wrong,
$stat_todo_total,
$vars{'output_web_mistakes'},
$page,
$pages,
$vars{'output_web_completed'},
$vars{'output_web_hints'},
);

}

}

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

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

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

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

}

}

$WEB .= qq~<a href="javascript:void(0);" onclick="onojs_hide('output_web_image_preview_box');">
<div id="output_web_image_preview_box" class="box_fabric abs hide" style="top:32px;left:32px">
<div class="abs" style="top:2px;right:2px"><img class="close" alt="close button"></div>
<div class="box_paper"><img id="output_web_image_preview" class="block256 radius10" src="/ono/osr/images/spacer/trans.gif" alt="">
</div>
</a>
<script>
function timer_correct(seconds) {
onojs_setvalue('timer_correct_id',seconds);
if (seconds > 0) {
seconds = seconds -1 ;
setTimeout(function() {timer_correct(seconds)},1000);
} else {
onojs_submit();
}
}
function output_web_mistakes_inc() {
var mistakes = onojs_getvalue('output_web_mistakes_add_id');
mistakes++;
onojs_setvalue('output_web_mistakes_add_id',mistakes);

var mistakes = onojs_gethtml('output_web_total_mistakes');
mistakes++;
onojs_sethtml('output_web_total_mistakes',mistakes);
}
</script>
~;

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

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

} else {

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

$WEB .= ONO::FW::Apps::Core->infopics(
"screen:320:50:40::vocabulary_screenshot_1.jpg",
"sheet:168:180:120:15:vocabulary_sheet_2.jpg",
"sheet:168:40:150:-10:vocabulary_sheet_1.jpg",
);

if (!$vars{'app_input_number_of_questions'}) {
$vars{'app_input_number_of_questions'} = 20;
if (ONO::IO->device eq "phone") {
$vars{'app_input_number_of_questions'} = 10;
}
}

my (
$default_ref,$default_lessons,$all_lessons,$custom_lessons,$LU,
) = ONO::FW::Apps::Core::Lang->lang_default_setup_config(\%vars,"i");
my @default = @$default_ref;

$vars{'software_base'} = $BASE;

my $CONF .= ONO::FW::Apps::ToolBox->conf_input("langs", $BLK_ref,\%vars,"mp","$default[0];en:de:fr$LU:img",">","$default[1];en:de:fr$LU:img");
$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");
$CONF .= ONO::FW::Apps::ToolBox->conf_input("difficulty", $BLK_ref,\%vars,"i",5,3);

if ($vars{'output_paper'} && ($vars{'app_input_langs_lang_1'} eq "img" || $vars{'app_input_langs_lang_2'} eq "img")) {
if (!$vars{'app_input_images_status'}) {
$vars{'app_input_images_status'} = 16;
}
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("tabs", $BLK_ref,\%vars,"j",$BLK{'images'},"images","12:dark:12;16:dark:16;20:dark:20");
}

if ($vars{'output_paper'} && $vars{'app_input_langs_lang_1'} eq "img") {
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("lines", $BLK_ref,\%vars);
}

my $BUTTONS = "op";
$vars{'output_paper_custom_text'} = "$BLK{'print'}: $BLK{'worksheet'} $BLK{'or'} $BLK{'list'}";
if ($vars{'output_paper'}) {
$vars{'output_paper_custom_text'} = $BLK{'print_worksheet'};
$vars{'output_paper_add_button'} = "output_print_vocs";
$vars{'output_paper_add_button_color'} = "lightgreen";
$vars{'output_paper_add_button_text'} = $BLK{'list'};
$vars{'output_paper_add_button_hint'} = "$BLK{'print_list'}: $BLK{'vocabulary'}";
}

$WEB .= ONO::FW::Apps::Core->conf_box(
$db,
$community,
$app,
$form,
"",
$action_url,
$CONF,
$lang,
$BLK_ref,
\%vars,
"${BUTTONS}-ncdi-CDI-lsu-mM-NO-h",
);

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'}),
);
}

$WEB .= ONO::FW::Apps::Core->vardump($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);
}

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

return $WEB;

}

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

sub get_data {

my @data = ($_[1],$_[2],$_[3]);

foreach my $opt (0,1,2) {
$data[$opt] =~ s~…~\.\.\.~g;
$data[$opt] =~ s~\.\.\.~ \.\.\. ~g;
$data[$opt] = ONO::Lib::Basic->remove_bad_spaces_sentence($data[$opt]);
}

$data[0] =~ s~\((.*?)\)~<span class="col6 small">\($1\)</span>~g;

return @data;

}

sub clean_words {

my @words = ($_[1],$_[2]);

for (my $i = 0; $i < 2; $i++) {
$words[$i] =~ s~(\n|\r|\t)~~g;
$words[$i] =~ s~^ ~~g;
$words[$i] =~ s~ $~~g;
}

return ($words[0],$words[1]);

}

sub remove_article {

my ($word,$article) = ONO::Lib::Lang::ToolBox->remove_article_alt($_[1]);

return ($word,$article);

}

sub multi_choice_gen {

my (
$self,
$use_answer,
$WORDLIST_ref,
$flip,
$flip_never,
) = @_;

my @WORDLIST = @$WORDLIST_ref;

my $num = @WORDLIST;
my ($use_answer_short,$article) = &remove_article("",$use_answer);
my $correct_length = length $use_answer;
my $correct_uplow = 0;
if ($use_answer =~ /[A-Z]/) {
$correct_uplow = 1;
}

my @bad_answer;

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

# first we'll try to find solutions with similar length, respecting upper/lower case

# !!! still missing: try to respect article !!!

my $whilecounter;
while ($whilecounter < 256 && (
(!$bad_answer[$a] || $bad_answer[$a] eq $use_answer || ($bad_answer[$a-1] && $bad_answer[$a] eq $bad_answer[$a-1])) ||
(length $bad_answer[$a] < $correct_length/2 || length $bad_answer[$a] > $correct_length*2) ||
($bad_answer[$a] =~ /[A-Z]/ && $correct_uplow == 0) || ($bad_answer[$a] !~ /[A-Z]/ && $correct_uplow == 1)
)
) {
$whilecounter++;
my @RAND = split(/\^/,$WORDLIST[int(rand($num))]);
if ($flip == 2 && !$flip_never) {
$bad_answer[$a] = $RAND[0];
} else {
$bad_answer[$a] = $RAND[1];
}
}

# if not enough results, then we'll use anything available...

my $whilecounter;
while ($whilecounter < 256 && (!$bad_answer[$a] || $bad_answer[$a] eq $use_answer || ($bad_answer[$a-1] && $bad_answer[$a] eq $bad_answer[$a-1]))) {
$whilecounter++;
my @RAND = split(/\^/,$WORDLIST[int(rand($num))]);
if ($flip == 2 && !$flip_never) {
$bad_answer[$a] = $RAND[0];
} else {
$bad_answer[$a] = $RAND[1];
}
}

}

return ($use_answer_short,@bad_answer);

}

sub multi_choice_bad_answer {

my (
$self,
$use_answer,
$use_answer_short,
$bad_answer,
) = @_;

my $MARK;

$bad_answer =~ s~:(.*)$~~g;
my $false_help = $1;

my ($false,$article) = &remove_article("",$bad_answer);

# restore the article, but make it lower case, this will undo the previous line of code:

$false = ONO::Lib::Lang::ToolBox->lc_article($bad_answer);
$false = $bad_answer;

$false =~ s~(\!|\?)~~g;

if ($use_answer =~ /(\!|\?|\.)/) {
$MARK = $1;
$false =~ s~\.\.\. $~~;
$false =~ s~\.\.\.$~~;
$false =~ s~\.$~~;
}
if ($use_answer =~ /(\.\.\.)$/) {
$MARK = $1;
} else {
$false =~ s~\.\.\.~~;
}
if ($use_answer_short =~ /^[A-Z]/) {
# $false = ucfirst $false;
}
if ($use_answer_short =~ /^[a-z]/) {
$false = lcfirst $false;
}

$false =~ s~ \.\.(\!|\?)$~~;
$false =~ s~ (\!|\?|\.)$~~;

$false =~ s~\.\.(\!|\?)$~~;
$false =~ s~(\!|\?|\.)$~~;

if ($false_help) {
$false_help = qq~ <span class="small">($false_help)</span>~;
}

return ($false,$MARK,$false_help);

}

sub multi_choice_bad_answer_img {

my (
$self,
$init,
$number,
$simple_ids,
$total_pix,
) = @_;

my (@bad_answer,%used,$whilecounter);
$used{$init}++;
for (my $b = 0; $b <$number; $b++) {
while (!$bad_answer[$b] && $whilecounter < 4096) {
$whilecounter++;
my $rand = ONO::Lib::Basic->add_leading_zeroes(int(rand($total_pix)),4);
if (!$used{$rand} && ONO::IO->exists("images/pix/preview/rgb/$rand.jpg")) {

if ($simple_ids) {

$bad_answer[$b] = $rand;

} else {

$bad_answer[$b] = qq~<a href="javascript:void(0);" onclick="onojs_class('bad_answer_$b','p10 radius10 bg_red');output_web_mistakes_inc();">
<div class="p5 fl">
<div id="bad_answer_$b" class="p10 radius10"><div class="bo radius10"><img class="block128 radius10" src="/images/pix/preview/rgb/$rand.jpg" alt=""></div></div>
</div>
</a>
~;

}
$used{$rand}++;
}
}
}

return @bad_answer;

}

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

1;

__END__