#!/bin/perl

#
# Compone le immagini in fogli
# by Andrea 
# 29/1/2009 - rimosso stroke=>'none' in my $montage = $images->Montage(...)
#

# Appunti
#     Ping() is a convenience method that returns information about an image without having to read the image into memory.
#            It returns the width, height, file size in bytes, and the file format of the image.
#            You can specify more than one filename but only one filehandle:
#
#  ($width, $height, $size, $format) = $image->Ping('logo.png');



use strict;
use warnings;
use Image::Magick;
use Win32::GUI();
use Win32::GUI::DropFiles();
use File::Basename;


# 
# assegna le variabili
#
my $versione = 'v.1.0.1';

# --- dichiara Main Windows e la status bar per la gui
my $mw;
my $sb;

# --- flag display  1=visualizza i fogli creati
#     flag rotate   1=rotazione casuale polaroid
my $flgdisplay=0;
my $flgrotate=1;
my $flgpolaroid=1;
my $flgsinglefoto=0;

# nasconde la finestra dos
my ($DOS) = Win32::GUI::GetPerlWindow();
Win32::GUI::Hide($DOS);

#
# determina il direttorio di default per OUT
#
my $outdefault = 'e:\\tmp\\';
if  (!-e $outdefault) {
	$outdefault = $ENV{'HOMEDRIVE'} . $ENV{'HOMEPATH'} . '/Desktop/';
	$outdefault =~ s/\\/\//g;
	if (!-e $outdefault) {
		my $tmpdir = $ENV{'TEMP'};
		$tmpdir =~ s/\\/\//g;		
	}
}


# visualizza GUI
visualizzaGUI();

exit 0;


# **************************************************************
#
# legge l'immagine e crea il polaroid a dimensione stabilita
#
# **************************************************************
sub leggiimmagine
{
	my $fullpathfile = $_[0];
	my $x = $_[1];
	my $y = $_[2];
	my $geometryfoto = $_[3];

	my $nomefile;
	my $path;
	my $suffix;
	my $randomangle = 0;
	my $img;
	my $background = $mw->BACKGROUND->GetLBText($mw->BACKGROUND->SelectedItem());
	
	# genera un angolo casuale
	srand;
	$randomangle = (rand(10) -5) * $flgrotate ;

	# estrae il nome del file dal percorso completo
	( $nomefile, $path, $suffix ) = fileparse($fullpathfile);

	if ($flgpolaroid == 1) {
		$img = Image::Magick->new;
		$img->Read($nomefile);
		$img->Resize(x=>$x,y=>$y);
		$img->Polaroid(caption=>$nomefile, pointsize=>70, angle=>$randomangle, background=>$background, curl=>0, geometry=>$geometryfoto);
	
		#convert -pointsize 25 -caption !ETICHETTA! !SRC! -gravity center -bordercolor white -background black -resize !SIZE! +polaroid !ETICHETTA!.PNG
	} else {
		$img = Image::Magick->new;
		$img->Read($nomefile);
		$img->Resize(x=>$x,y=>$y);   #, geometry=>$geometryfoto
		$img->Border(width=>"60", height=>"120", fill=>"grey87");
		$img->Annotate(text=>$nomefile, pointsize=>80, gravity =>'South');
		#$img->Annotate(font=>'kai.ttf', pointsize=>70, fill=>'green', text=>$nomefile);
	}
	return $img;
}	

# **************************************************************
#
# Gui function
#
# **************************************************************
sub visualizzaGUI {
	$mw = Win32::GUI::Window->new(
		-title => "Composizione foto $versione  (c) Andrea Guido Sommaruga 2009",
		-pos   => [100,100],
		-size  => [600,500],
		-onResize => \&mwResize,
	);

	$sb = $mw->AddStatusBar(-text => 'in attesa');
		
	$mw->AddTextfield(
	    -name => 'OUTX',
	    -text => 1650,
	    -prompt => [ "Out X:", 35 ],
	    -pos => [10,10],
	    -size => [45,20],
	    -align => 'right',
	    -number => 1,
	    -tabstop => 1,
	);

	$mw->AddTextfield(
	    -name => 'OUTY',
	    -text => 1050,
	    -prompt => [ "Out Y:", 35 ],
	    -pos => [100,10],
	    -size => [45,20],
	    -align => 'right',
	    -number => 1,
	    -tabstop => 2,
	);

	$mw->AddTextfield(
	    -name => 'RIGHE',
	    -text => 2,
	    -prompt => [ "Righe:", 45 ],
	    -pos => [210, 10],
	    -size => [35,20],
	    -align => 'right',
	    -number => 1,
	    -tabstop => 3,
	);

	$mw->AddTextfield(
	    -name => 'COLONNE',
	    -text => 3,
	    -prompt => [ "Colonne", 45 ],
	    -pos => [300, 10],
	    -size => [35,20],
	    -align => 'right',
	    -number => 1,
	    -tabstop => 4,
	);

	$mw->AddTextfield(
	    -name => 'COMPRESSION',
	    -text => 90,
	    -prompt => [ "Qualità:", 45 ],
	    -pos => [410,10],
	    -size => [35,20],
	    -align => 'right',
	    -number => 1,
    	    -tabstop => 5,
	);

	$mw->AddCheckbox(
		-name    => "FLGROTATE",
		-text    => "Rotazione casuale",
		-pos => [10,40],
		-size => [145,20],
		-tabstop => 1,
		-cheched => 1,
		-tabstop => 6,
	);
	$mw->FLGROTATE->SetCheck(1);

	$mw->AddCheckbox(
		-name    => "FLGDISPLAY",
		-text    => "Visualizza out",
		-pos => [10,60],
		-size => [145,20],
		-tabstop => 7,
	);
	$mw->FLGDISPLAY->SetCheck(0);

	$mw->AddCheckbox(
		-name    => "FLGPOLAROID",
		-text    => "Polaroid",
		-pos => [200,60],
		-size => [145,20],
		-tabstop => 8,
	);
	$mw->FLGPOLAROID->SetCheck(1);
	
	$mw->AddCombobox(
	    -name => 'BACKGROUND',
	    -text => 'Colore di sfondo',
	    -dropdownlist => 1,
	    -pos => [200,40],
	    -size => [200,20],
	    -width => 60,
	    -height => 100,
	    -tabstop => 9,
	);
	$mw->BACKGROUND->Add('black', 'white', 'grey42','yellow','DeepSkyBlue', 'DarkOliveGreen3');
	$mw->BACKGROUND->Select(0);
	
	$mw->AddTextfield(
	    -name => 'OUTDIR',
	    -text => $outdefault,
	    -prompt => [ "OutDIR:", 45 ],
	    -pos => [10,90],
	    -size => [400,20],
	    -align => 'left',
	    -number => 0,
	    -tabstop => 10,
	);
	
	$mw->AddButton(
	    -name => "AGGIUNGIJPG",
	    -text => "Aggiungi jpg",
	    -left => 500,
	    -top  => 10,
	    -size => [80,20],
	    -onClick => \&aggiungi_jpg,
	    -tabstop => 11,
	);
	
	$mw->AddButton(
	    -name => "CREAFOGLI",
	    -text => "Crea Fogli",
	    -left => 500,
	    -top  => 40,
	    -size => [80,20],
	    -onClick => \&crea_fogli,
	    -tabstop => 12,
	);

	$mw->AddButton(
	    -name => "EXIT",
	    -text => "Exit",
	    -left => 500,
	    -top  => 90,
	    -size => [80,20],
	    -onClick => \&esci,
	    -tabstop => 13,
	);

	
	$mw->AddLabel(
		-pos  => [10,115],
		-text => "Aggiungi i file con il bottone a sinistra",
	);
	
	$mw->AddListbox(
		-name => 'LB',
		-pos => [10,130],
		-size => [$mw->Width()-200, $mw->Height()-300],
		-vscroll => 1,
		-acceptfiles => 1,
		-onDropFiles => \&gotDrop,
	);

	$mw->Show();
	
	Win32::GUI::Dialog();
	$mw->Hide();
	exit(0);

}

sub gotDrop {
	my ($self, $dropObj) = @_;

	$self->Add($dropObj->GetDroppedFiles());

	return 0;
}

sub mwResize {
	my $self = shift;

	$self->LB->Resize(
		$self->ScaleWidth()-20,
		$self->ScaleHeight()-150,
	);
        $sb->Move(0, $mw->ScaleHeight - $sb->Height);
        $sb->Resize($mw->ScaleWidth, $sb->Height);

	return 1;
}


sub aggiungi_jpg {
	
	#GetOpenFileName - opzione BrowseForFolder(%OPTIONS)

	# selezione multipla di file solo jpg
	my ( @file, $file );
	my ( $lastfile );
	my ( @parms );
	push @parms,
	  -multisel => 1, # use 40000 byte buffer
	  -filter =>
	    [ 'JPG - Joint Photographics experts Group', '*.jpg',
	    ],
	  -directory => "c:\\programmi",
	  -title => 'Seleziona immagini da aggiungere';
	push @parms, -file => $lastfile  if $lastfile;
	@file = Win32::GUI::GetOpenFileName ( @parms );
	
	my $percorso = '';
	my $nrfile = scalar(@file);
	foreach $file(@file) {
		
		# test se definito $file ... in tre forme equivalenti ...
		#  $file = '' unless defined $file;
		#  $file ¦¦= '';
		#  if (!defined($file) {do stuff}
		if (defined($file)) {
			if ($percorso eq '' && $nrfile > 1) {
				# se selezionati più di un file...il primo in elenco è il path completo
				$percorso = $file . '\\';
			} else {
				if (length($file) > 4) {
					# minima lunghezza per il nome dovendo esserci .jpg
					print $file . "\n";
					$sb->Text($percorso . $file);
					$mw->LB->InsertItem($percorso . $file);
				}
			}
		}
	}
}

sub crea_fogli {
	my $i;
	my $maxi = $mw->LB->GetCount();
	
	my @dir;
	my $dir;

	# -----------------------------------------------------------
	#
	#  Assegna le variabili
	#
	#  ----------------------------------------------------------
	
	# --- dimensione foglio da generare
	my $resxbg = $mw->OUTX->Text();
	my $resybg= $mw->OUTY->Text();
	my $geometrybg = $resxbg . 'x' . $resybg;
	
	my $righe = $mw->RIGHE->Text();
	my $colonne = $mw->COLONNE->Text();
	my $maxperpag = $righe * $colonne;
	my $tilebg = $colonne . 'x' . $righe;
	
	my $nomefile;	

	# --- determina se elaborazione di foto singola o montaggi
	my $resxfoto;
	my $resyfoto;
	my $geometryfoto;
	
	if (($righe == 1) && ($colonne == 1)) {
		# --- elaborazione foto singole
		$flgsinglefoto = 1;
		
		# --- dimensioni fotocolor per generare polaroid foto singole
		$resxfoto = $resxbg;
		$resyfoto = $resybg;
		$geometryfoto = $resxfoto . 'x' . $resyfoto;  # . '+20+20';

	} else {
		# --- elaborazione montaggio
		$flgsinglefoto = 0;

		# --- dimensioni fotocolor per generare polaroid nei montaggi
		$resxfoto = ( $resxbg -50 ) / $colonne;
		$resyfoto = ( $resybg -50 ) / $righe;
		$geometryfoto = $resxfoto . 'x' . $resyfoto;  # . '+20+20';
	}
	my @images;
	my $images;
	my $maxdir;
	
	my $basedir = './';
	my $srcdir = $basedir;
	my $outdir = $mw->OUTDIR->Text();
	$outdir =~ s/\//\\\\/g;

	# --- flag display  1=visualizza i fogli creati
	#     flag rotate   1=rotazione casuale polaroid
	$flgdisplay = $mw->FLGDISPLAY->GetCheck();
	$flgrotate = $mw->FLGROTATE->GetCheck();
	$flgpolaroid = $mw->FLGPOLAROID->GetCheck();
	
        my $background = $mw->BACKGROUND->GetLBText($mw->BACKGROUND->SelectedItem());
	
	#
	# --- crea array dei fileda elaborare
	#
	for ($i = 0; $i < $maxi; $i++) {
		my $selectfile = $mw->LB->GetString($i);
		$selectfile =~ s/\//\\\\/g;	
		if (length($selectfile) > 3) {
			# tre è la lunghezza minima per il nome di un file
			push(@dir, $selectfile);
		}
	}	
		    
	# --- scalar(@dir) ritorna il numero di elementi
	#     $#dir rende indice ultimo elemento quindi 1 in meno perchè iniziano da 0	    
	$maxdir = scalar(@dir);		
	print "Letto $maxdir immagini\n...attendere...\n";
	$sb->Text('attendere...');
	
	my $contatot = 0;
	my $contapag = 0;
	my $nrpag = 0;
	
	my $geometry; 		# usata localmente
	
	foreach $dir(@dir) {
		
		if ($contapag == 0) {
			# --- inizializza array
			$images = Image::Magick->new();		
		}
		
		if ($contapag < $maxperpag ) {
			# --- il contatore totale deve sempre essere incrementato
			$contatot++;			
			if ($dir !~ m/foglio-/) {
				# --- se deve...aggiunge immagini
				#     salta i file foglio-###
				push (@$images, leggiimmagine($dir, $resxfoto, $resyfoto, $geometryfoto));
				$contapag++;
				print "Elabora: $dir\n";
				$sb->Text("Elabora: $dir");
			}
		}
		
		# --- test se deve generare una pagina composta...se fatti x per pagina o se alla fine
		if (($contapag == $maxperpag) || ($contatot == $maxdir)) {
			# --- incrementa contatore pagina ed azzera contatore elaborate per pagina
			$nrpag++;
			$contapag=0;	
			#
			# compone le immagini
			#
			if ($flgpolaroid == 0) {
				$geometry = $geometrybg . '+30+30>';
			} else {
				$geometry = $geometrybg . '+15+15>';
			}
			
			# test se montaggio di più fotocolor o foto singola
			if ($flgsinglefoto == 1) {
				#
				# --- foto singola
				#
				$nomefile = $outdir . 'foglio-' . $nrpag . '.jpg';
				$images->Write($nomefile);
				#
				# --- se richiesto anteprima immagine
				#
				if ($flgdisplay == 1) {
					$images->Write('win:');
				}
				#
				# --- rilascia la memoria
				#
				undef $images;
			} else {
				#
				# --- montaggio di piu fito
				#
				my $montage = $images->Montage(
					geometry=>$geometry,
					gravity=>'Center',
					tile=>$tilebg,
					compose=>'over',
					background=>$background,
					font=>'Generic.ttf',
					pointsize=>25,
					fill=>'#600',);
					# 
					# rimosso
					# stroke=>'none'
				
				# --- matte definisce la trasparenza
				#$montage->Set(matte=>'True');
				#$montage->Set(mattecolor=>'black');
				#$montage->Set(format => "png");
				#$montage->Resize(geometry=>$geometrybg);
				#$montage->Set(matte=>'false');
				
				$montage->Set(quality=>90);
				$montage->Set(format => "jpg");
				$montage->Resize(geometry=>$geometrybg);
				$nomefile = $outdir . 'foglio-' . $nrpag . '.jpg';
				$montage->Write($nomefile);
				#
				# --- se richiesto anteprima immagine
				#
				if ($flgdisplay == 1) {
					$montage->Write('win:');
				}
				#
				# --- rilascia la memoria
				#
				undef $montage;
				undef $images;
			}

			print "componi pagina: $nrpag  $nomefile\n";
			$sb->Text("componi pagina: $nrpag  $nomefile");
		}
	}
	$sb->Text('OK: elaborazione terminata');
}

sub esci {
	return -1;
}
