#! /usr/bin/perl

=head1 NAME

linbo_images - manage LINBO image files

=head1 SYNOPSIS

 https://server/schulkonsole/linbo_images

=head1 DESCRIPTION

C<linbo_images> lets the user copy, delete, and rename image files and edit
their description.
The HTML template is linbo_images.tt.

=head2 Template variables

Additionally to the variables of Schulkonsole::Session C<linbo_images>
provides the following variables:

=over

=cut

use strict;
use utf8;
use lib '/usr/share/schulkonsole';
use open ':utf8';
use Schulkonsole::Encode;
use Schulkonsole::Linbo;
use Schulkonsole::Session;


my $this_file = 'linbo_images';



my $sk_session = new Schulkonsole::Session($this_file);
if (not $sk_session->get_password()) {
	my $q = new CGI;
	my $url = $q->url( -full => 1 );

	# we send cookies over secure connections only
	if ($url =~ s/^http:/https:/g) {
		$sk_session->redirect($url);
	} else {
		$sk_session->exit_with_login_page($this_file);
	}
}

my $q = $sk_session->query();


my $images = Schulkonsole::Linbo::images();

my $is_action;

eval {

SWITCHCOMMAND: {
$q->param('delete') and do {
	my $image = $q->param('image');

	if ($image !~ /^[^\\]+.(?:cloop|rsync)$/) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s ist kein Image'), $image), 1);
		last SWITCHCOMMAND;
	}

	if (not $$images{$image}) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s existiert nicht'), $image), 1);
		last SWITCHCOMMAND;
	}


	Schulkonsole::Linbo::delete_image(
		$sk_session->userdata('id'),
		$sk_session->get_password(),
		$image);

	$images = Schulkonsole::Linbo::images();
	if (not $$images{$image}) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s gelöscht'), $image), 0);
	} else {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s konnte nicht gelöscht werden'), $image), 0);
	}
	
	last SWITCHCOMMAND;
};

(   $q->param('move')
 or $q->param('copy')) and do {
	my $is_move = $q->param('move');

	my $image = $q->param('src');
	my $new_image = $q->param('dst');
	$new_image =~ s/(?:\.cloop|\.rsync)$//;

	if ($image !~ /^[^\\]+.(?:cloop|rsync)$/) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s ist kein Image'), $image), 1);
		last SWITCHCOMMAND;
	}

	if (not $$images{$image}) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s existiert nicht'), $image), 1);
		last SWITCHCOMMAND;
	}


	if (not $new_image) {
		$sk_session->set_status($sk_session->d()->get(
			'Geben Sie einen Namen für das neue Image an'),
			1);
		$sk_session->mark_input_error("${image}_newimage");
		last SWITCHCOMMAND;
	}


	my ($suffix) = $image =~ /(cloop|rsync)$/;
	my $new_image_filename = "$new_image.$suffix";

	if ($is_move) {
		Schulkonsole::Linbo::move_image(
			$sk_session->userdata('id'),
			$sk_session->get_password(),
			$image,
			$new_image);
	} else {
		Schulkonsole::Linbo::copy_image(
			$sk_session->userdata('id'),
			$sk_session->get_password(),
			$image,
			$new_image);
	}

	$images = Schulkonsole::Linbo::images();
	if (exists $$images{$new_image_filename}) {
		$sk_session->set_status(sprintf(
			($is_move ?
			  $sk_session->d()->get('%s nach %s umbenannt')
			: $sk_session->d()->get('%s nach %s kopiert')),
			$image, $new_image_filename), 0);
		$q->delete("${image}_newimage");
	} else {
		$sk_session->set_status(sprintf(
			($is_move ?
			  $sk_session->d()->get('%s konnte nicht in %s umbenannt werden')
			: $sk_session->d()->get('%s konnte nicht nach %s kopiert werden')),
			$image, $new_image_filename), 0);
	}

	last SWITCHCOMMAND;
};

$q->param('edit') and do {
	my $filename = $q->param('filename');

	if ($filename !~ /^[^\\]+\.(?:cloop|rsync)\.desc$/) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s ist keine Beschreibungsdatei'), $filename), 1);
		last SWITCHCOMMAND;
	}

	my ($image) = $filename =~ /^(.*)\.desc$/;
	if (not $$images{$image}) {
		$sk_session->set_status(sprintf($sk_session->d()->get(
			'%s existiert nicht'), $image), 1);
		last SWITCHCOMMAND;
	}


	my $lines = $q->param('imagedesc');

	Schulkonsole::Linbo::write_file(
		$sk_session->userdata('id'),
		$sk_session->get_password(),
		$filename,
		$lines);

	
	$sk_session->set_status(sprintf($sk_session->d()->get(
		'%s geschrieben'), $filename), 0);

	last SWITCHCOMMAND;
};


=head3 Parameters depending on selected submit button

The following values are set only if a submit button
C<< <image>_<action> >> has been selected. <image> is the name of the image
and <action> identifies what to do.

=cut

foreach my $param ($q->param) {
	if (my ($image, $action)
	    	= $param =~ /^(.+)_(editdesc|info|move|copy|delete)$/) {
		if (not $$images{$image}) {
			$sk_session->set_status(sprintf($sk_session->d()->get(
				'%s existiert nicht'), $image), 1);

			last SWITCHCOMMAND;
		}

		$sk_session->set_var('image', $image);

		{	# switch action
		$action =~ /^e/ and do {	# editdesc
			my $image_desc = "$image.desc";
			my $image_desc_full_path
				= "$Schulkonsole::Config::_linbo_dir/$image_desc";

			if (-e $image_desc_full_path) {
				if (open DESC, '<',
				         Schulkonsole::Encode::to_fs(
				         	"$Schulkonsole::Config::_linbo_dir/$image_desc")) {
					flock DESC, 1;
					seek DESC, 0, 0;

					{
					local $/ = undef;
					my $lines = <DESC>;
					$q->param('imagedesc', $lines);
					}
				} else {
					$sk_session->set_status(sprintf($sk_session->d()->get(
					 	'Kann Datei %s nicht öffnen'), $image_desc),
						1);

					last SWITCHCOMMAND;
				}
			}

=item C<editfilename>

Name of the <image>.desc file, if the action C<editdesc> has been selected.
The query parameter C<imagedesc> contains the contents of the file.

=cut

			$sk_session->set_var('editfilename', "$image_desc");
			$is_action = 1;

			last SWITCHCOMMAND;
		};
		$action =~ /^i/ and do {	# info
			my $image_info = "$image.info";
			my $image_info_full_path
				= "$Schulkonsole::Config::_linbo_dir/$image_info";

			if (open INFO, '<',
			         Schulkonsole::Encode::to_fs($image_info_full_path)) {
				flock INFO, 1;

				my $lines;
				{
				local $/ = undef;
				$lines = <INFO>;
				}

				if ($lines) {

=item C<imageinfo>

Contents of the <image>.info file, if the action C<info> has been selected.

=cut

					$sk_session->set_var('imageinfo', $lines);
				} else {
					$sk_session->set_status(sprintf($sk_session->d()->get(
						'Datei %s ist leer'), $image_info),
						1);
					last SWITCHCOMMAND;
				}
			} else {
				$sk_session->set_status(sprintf($sk_session->d()->get(
				 	'Kann Datei %s nicht öffnen'), $image_info),
					1);

				last SWITCHCOMMAND;
			}

			$is_action = 1;

			last SWITCHCOMMAND;
		};
		(   $action =~ /^m/	# move
		 or $action =~ /^c/) and do {	# copy
			my $new_image = $q->param("${image}_newimage");
			$new_image =~ s/(?:\.cloop|\.rsync)$//;

			my $is_move = $action =~ /^m/;

			if (not $new_image) {
				$sk_session->set_status($sk_session->d()->get(
					'Geben Sie einen Namen für das neue Image an'),
					1);
				$sk_session->mark_input_error("${image}_newimage");
				last SWITCHCOMMAND;
			}


			my ($suffix) = $image =~ /(cloop|rsync)$/;
			my $new_image_filename = "$new_image.$suffix";
			if (exists $$images{$new_image_filename}) {
				$sk_session->set_status(sprintf($sk_session->d()->get(
					'%s existiert bereits'), $new_image_filename),
					1);

=item C<moveimage>

Name of image to overwrite, if the submit button C<move> has been selected.

=item C<copyimage>

Name of image to overwrite, if the submit button C<copy> has been selected.

=cut

					$sk_session->set_var(($is_move ? 'moveimage' : 'copyimage'),
					                     $new_image_filename);
					$sk_session->set_var('src', $image);
					$is_action = 1;

				last SWITCHCOMMAND;
			}


			if ($is_move) {	# move
				Schulkonsole::Linbo::move_image(
					$sk_session->userdata('id'),
					$sk_session->get_password(),
					$image,
					$new_image);
			} else {	# copy
				Schulkonsole::Linbo::copy_image(
					$sk_session->userdata('id'),
					$sk_session->get_password(),
					$image,
					$new_image);
			}


			$images = Schulkonsole::Linbo::images();
			if (exists $$images{$new_image_filename}) {
				$sk_session->set_status(sprintf(
					($is_move ?
					  $sk_session->d()->get('%s nach %s umbenannt')
					: $sk_session->d()->get('%s nach %s kopiert')),
					$image, $new_image_filename), 0);
				$q->delete("${image}_newimage");
			} else {
				$sk_session->set_status(sprintf(
					($is_move ?
					  $sk_session->d()->get('%s konnte nicht in %s umbenannt werden')
					: $sk_session->d()->get('%s konnte nicht nach %s kopiert werden')),
					$image, $new_image_filename), 0);
			}

			last SWITCHCOMMAND;
		};
		$action =~ /^d/ and do {	# delete

=item C<deleteimage>

Name of image to delete, if the submit button C<delete> has been selected.

=cut

			$sk_session->set_var('deleteimage', $image);
			$is_action = 1;

			$sk_session->set_status('Bitte bestätigen', 0);
			last SWITCHCOMMAND;
		};

		}
	}
}

}
};
if ($@) {
	$sk_session->standard_error_handling($this_file, $@);
}



if (not $is_action) {
	my @array_images_base;
	my @array_images_diff;
	
	foreach my $image (sort keys %$images) {
		if ($image =~ /p$/) {	# *.cloop
			push @array_images_base, $image;
		} else {	# *.rsync
			push @array_images_diff, $image;
		}
	}

=item C<images_base>

A list of all base images

=cut

	$sk_session->set_var('images_base', \@array_images_base);

=item C<images_diff>

A list of all diff images

=cut

	$sk_session->set_var('images_diff', \@array_images_diff);
}






$sk_session->print_page("$this_file.tt", $this_file);







=back

=head2 Form fields

=over

=item C<image>

Filename of an image

=item C<delete>

Deletes image from C<image> if selected

=item C<src>

Name of source file for verification (see C<move> and C<copy>)

=item C<dst>

Name of (existing) destination file for verification (see C<move> and C<copy>)

=item C<move>

Renames image C<src> to C<dst>, even if C<dst> exists if selected

=item C<copy>

Copies image C<src> to C<dst>, even if C<dst> exists if selected

=item C<imagedesc>

Contents of an <image>.desc file

=item C<filename>

Filename of an <image>.desc file

=back

The following parameters refer to an image name from the arrays in the
session variables C<images_base> and C<images_diff>.

=over

=item C<${image}_editdesc>

Submit button to edit <image>.desc

=item C<${image}_info>

Submit button to display <image>.info

=item C<${image}_newimage>

Argument for the following submit buttons

=item C<${image}_move>

Submit button to move image and associated files to
C<${image}_newimage>*

=item C<${image}_copy>

Submit button to copy image and associated files to
C<${image}_newimage>*

=item C<${image}_delete>

Submit button to delete image and associated files

=back

