ONO::FW::Edu::Apps::Modules::SketchArt

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

use ONO::Render;

use ONO::ToolBox::Auth;
use ONO::Lib::Lang::LangKitEdu;

use ONO::Lib::DateTime::ToolBox;
use ONO::Lib::Image::Drawing;

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

use ONO::FW::Edu::Apps::ToolBox;
use ONO::FW::User::Init;

use ONO::FW::Edu::Apps::Modules::Drawing;

use ONO::IO;
use ONO::DB;
use ONO::Lib::Basic;

sub play {

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 ($HEAD,$WEB);

my (
$vpath,
$lang,$domain,$community,
$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$timestamp,
$script_url,$action_url,$form
) = ONO::FW::User::Init->getvar(\%vars);

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

my $action_url = qq~$ENV{'SCRIPT_NAME'}?app_lang=$vars{'app_lang'}&~;

###################################################################
# DRAW
###################################################################

my $CSSJS = ONO::Render->cssjs($BASE);
$CSSJS .= ONO::Lib::Image::Drawing->cssjs($BASE);

my ($X,$Y) = (900,420);

if ($vars{'username'} && $vars{'ono_lib_image_drawing_target_folder'} && $vars{'ono_lib_image_drawing_data'} =~ s~^data:image/png;base64,~~) {

my $FILE;

if ($vars{'ono_lib_image_drawing_target_folder'} eq "user_documents_images") {
$FILE = "media/​users/".ONO::IO->deepdir($vars{'username'})."/​$vars{'username'}/​documents/images";
}
if ($vars{'ono_lib_image_drawing_target_folder'} =~ m~^virclass_(.*?)_class$~) {
my $virclass = $1;
$virclass =~ s~[^0-9]~~gi;
foreach my $line (ONO::DB->select($db,"${community}_school_virclass_relationships","username = '$vars{'username'}' AND virclass = '$virclass'")) {
my @col = ONO::DB->readcols($line);
$FILE = "media/virclass/$virclass/class/$vars{'username'}/documents/images";
}
}
if ($FILE) {
$vars{'ono_lib_image_drawing_save_success'} = ONO::Lib::Image::Drawing->save("$FILE/$vars{'ono_lib_image_drawing_filename'}.png​",$vars{'ono_lib_image_drawing_data'});
}
}

my @txts = ONO::Lib::Image::Drawing->txts($lang);

my $SUCCESS;
if ($vars{'ono_lib_image_drawing_save_success'}) {
$SUCCESS = ONO::Lib::Image::Drawing->success($BLK{'Done'},$txts[3],$BLK{'ok'});
}

my $DIRS = ONO::FW::Edu::Apps::Modules::Drawing->get_dirs($db,$community,$vars{'username'});
my $SAVE = ONO::Lib::Image::Drawing->savebox(\@txts,$BLK_ref,$vars_ref,"",$DIRS,"sketch");
my $SAVE2;

my $SAVEBUTTON = ONO::Lib::Image::Drawing->savebutton("$BLK{'save'} / $BLK{'download'}");
my $SAVEBOXES = ONO::Lib::Image::Drawing->saveboxes($SAVE,$SAVE2,$lang,$BLK_ref,$BASE);
my $SAVESCRIPT = ONO::Lib::Image::Drawing->savescript_generic();

my $CLEARBUTTON = ONO::Lib::Image::Drawing->clearbutton($BLK{'clear'});
my $CLEARBOX = ONO::Lib::Image::Drawing->clearbox($action_url,$BLK_ref);

my $SKETCH = qq~

<div class="p2 bb bg_paper rel">
<table class="default_table auto">
<tr>
<td class="p0">
<div class="bo_dark radius16" onmouseout="ono_draw_context.strokeStyle=onojs_getvalue('color_picker_value');">
<table class="default_table">
<tr>
<td class="p0"><img class="block20 ml2" src="$BASE/ono/osr/images/icons/crystal/32x32/ono/colors.png" alt=""></td>
<td class="p0">
<input type="color" id="color_picker_value" name="color" value="#000000" onchange="ono_draw_context.strokeStyle=onojs_getvalue('color_picker_value');">
</td>
<td></td>
</tr>
</table>
</div>
</td>
<td class="pad10_2"></td>
<td class="p0"><a id="button_line" href="javascript:void(0);" onclick="button_line();" class="button button_small button_left">line</a></td>
<td class="p0"><a id="button_geometry" href="javascript:void(0);" onclick="button_geometry()" class="button_dark button_small button_right">geometry</a></td>
<td class="pad10_2"></td>
<td>•</td>
<td class="p0"><a id="button_width_0" href="javascript:void(0);" onclick="button_width('0');" class="button button_small button_left">0.5</a></td>
<td class="p0"><a id="button_width_1" href="javascript:void(0);" onclick="button_width('1');" class="button_dark button_small button_middle">1</a></td>
<td class="p0"><a id="button_width_2" href="javascript:void(0);" onclick="button_width('2');" class="button button_small button_right">2</a></td>
<td class="pad10_2"></td>
<td class="p0"><a id="button_inter_0" href="javascript:void(0);" onclick="button_inter('0');" class="button_dark button_small button_left">-</a></td>
<td class="p0"><a id="button_inter_3" href="javascript:void(0);" onclick="button_inter('3');" class="button button_small button_middle">•••</a></td>
<td class="p0"><a id="button_inter_5" href="javascript:void(0);" onclick="button_inter('5');" class="button button_small button_right">• • •</a></td>
<td class="pad10_2"></td>
<td class="p0">$CLEARBUTTON</td>
<td class="p0">$SAVEBUTTON</td>
<div>
</tr>
</table>
$CLEARBOX
$SAVEBOXES
<input type="hidden" name="ono_lib_image_drawing_data" id="ono_lib_image_drawing_data_id" class="w95">
$SUCCESS
</div>

<div class="inline auto"><canvas id="ono-drawing-canvas"></canvas></div>

$SAVESCRIPT


<script type="text/javascript">

// here comes the ONO draw app

var canvas = onojs_draw_canvas('ono-drawing-canvas',$X,$Y);
var ono_draw_context = onojs_draw_context(canvas,'#ffffff');
onojs_draw_mouse_logic(canvas);
ono_draw_execute_alt = true;

// the UI code

function button_line() {
onojs_class('button_line', 'button_dark button_small button_left');
onojs_class('button_geometry','button button_small button_right');
ono_draw_execute_alt = false;
}
function button_geometry() {
onojs_class('button_line', 'button button_small button_left');
onojs_class('button_geometry','button_dark button_small button_right');
ono_draw_execute_alt = true;
}
function button_width(width) {
onojs_class('button_width_0','button button_small button_left');
onojs_class('button_width_1','button button_small button_middle');
onojs_class('button_width_2','button button_small button_right');
if (width < 1) {
width = 0.5;
onojs_class('button_width_0','button_dark button_small button_left');
}
if (width == 1) {
onojs_class('button_width_1','button_dark button_small button_middle');
}
if (width == 2) {
onojs_class('button_width_2','button_dark button_small button_right');
}
ono_draw_context.lineWidth = width;
ono_draw_context.strokeStyle = 'rgba(0,0,0,'+width+')';
}
function button_inter(inter) {
onojs_class('button_inter_0','button button_small button_left');
onojs_class('button_inter_3','button button_small button_middle');
onojs_class('button_inter_5','button button_small button_right');
if (inter == 0) {
ono_draw_mouse_interval_enable = false;
onojs_class('button_inter_0','button_dark button_small button_left');
}
if (inter == 3) {
ono_draw_mouse_interval_enable = true;
ono_draw_mouse_interval_max = 3;
onojs_class('button_inter_3','button_dark button_small button_middle');
}
if (inter == 5) {
ono_draw_mouse_interval_enable = true;
ono_draw_mouse_interval_max = 5;
onojs_class('button_inter_5','button_dark button_small button_right');
}
}

// and here's the custom code, will be used if ono_draw_execute_alt is true

var density = 1;
var density_threshold_total = 500;
var density_threshold_single = 100;

var coord_array = new Array();
var coord_counter = 0;

// add a new coordinate, then draw lines (see sub below)

function onojs_draw_execute_alt(event) {
coord_array.push(new get_coord_xy(event));
coord_array[coord_counter].draw_lines(event,coord_array);
coord_counter++;
}

// get the x and y mouse coordinates

function get_coord_xy(event){
this.x = onojs_draw_mouse_pos_x(event);
this.y = onojs_draw_mouse_pos_y(event);
}

// draw all geometric lines

get_coord_xy.prototype.draw_lines = function(event,coord_array) {

// calculate all distances between the last coordinate and all previous coordinates

for(i = 0; i < coord_counter; i++) {
coord_array[i].distance = onojs_draw_distance(coord_array[i].x,coord_array[i].y,this.x,this.y);
}

// sort the coordinates, starting with those that are close to the last coordinate added

coord_array.sort(function(a,b){return a.distance-b.distance});

// draw lines as long as we're below all density thresholds

var total_distance = 0;
for (i = 0; i < coord_counter; i++) {
total_distance += coord_array[i].distance;
if (total_distance < density*density_threshold_total && coord_array[i].distance < density*density_threshold_single){
onojs_draw_line(ono_draw_context,onojs_draw_mouse_pos_x(event),onojs_draw_mouse_pos_y(event),coord_array[i].x,coord_array[i].y);
}
}
}
</script>
~;

print qq~Content-Type: text/html; charset=UTF-8\n\n
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="Generator" content="ONO App Engine">
$CSSJS
</head>
<body style="margin:0px;padding:0px;background-color:#cccccc">
<form id="ono_lib_image_drawing_form" method="post">
<input type="hidden" name="app_lang" value="$vars{'app_lang'}">
$SKETCH
</form>
</body>
</html>
~;

}

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

1;

__END__