#!/bin/perl

# programma di acquisizione documenti da scanner con salvataggio in jpg o pdf
#
# Appunti:
#   per la gestione dei PDF si può usare anche CAM-PDF-1.07
#   per la gestione dello scanner sotto linux c'e' SANE
#
# 	Win32::MsgBox(messaggio, tasti, titolo);
#
# v.1.0 - 24-05-2008 
# v.1.1 - 25-05-2008 - Aggiunto slider per qualità



use strict;
use warnings;
use Win32::GUI();
use Win32::GUI::DIBitmap;
use Win32::OLE;
use Win32::Clipboard;
use Win32::GUI::BitmapInline ();
use Config::IniFiles;


use Win32::Scanner::EZTWAIN;
use Image::Magick;

	my $versione = "1.0" ;
	#
	# default dir per i file temporanei
	#
	my $tmpdir = $ENV{'TEMP'};
	$tmpdir =~ s/\\/\//g;
	my $outfile = $ENV{'HOMEDRIVE'} . $ENV{'HOMEPATH'} . '/Desktop/scanner.pdf';
	$outfile =~ s/\\/\//g;


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

	#
	# apre finestra dell'applicazione
	#
	my $WIN = new Win32::GUI::Window(
		-name => "WINScanner",
		-text => "scanner versione: $versione - andrea guido sommaruga",
		-width => 1040,
		-height => 620,
		-left => 100,
		-top => 100,
		-resize => 0,
	);
	#
	# aggiunge la statusbar
	#
	my $WINsb = $WIN->AddStatusBar();

	my $FontNormal = new Win32::GUI::Font(
		-name => "Courier New", 
		-height => 10,
		-bold => 0,
	);


	#
	# definisce i controlli
	#
	my $col1 = 5; 
	my $col2 = 100;
	my $col3 = 900;
	my $height = 25;
	my $TLwidth = 90;
	my $TFDwidth = 780;
	my $BTwidth = 120;
	my $vtab = 35;
	my $riga = 1;
	
	# riga 1: tipoimmagine
	$riga = 1;
	
	$WIN->AddLabel(
		-name   => "TLdotxx",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"dot xx",
	);

	$WIN->AddTextfield(
		-name   => "TFLDdotxx",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => 100,
		-height => $height,
		-text=>"1240",
	);

	$WIN->AddLabel(
		-name   => "TLdotyy",
		-left   => 300,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"dot yy",
	);

	$WIN->AddTextfield(
		-name   => "TFLDdotyy",
		-left   => 400,
		-top    => $vtab * $riga,
		-width  => 100,
		-height => $height,
		-text=>"1755",
	);
 
	my $BTscansione = $WIN->AddButton(
		-name => "BTscansione",
		-text => "scansione",
		-left   => $col3,
		-top    => $vtab * $riga,
		-width  => $BTwidth,
		-height => $height,
        );

	# riga 2: qualita
	$riga = 2;
	
	$WIN->AddLabel(
		-name   => "TLqualita",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"qualità jpg",
	);

	$WIN->AddSlider(
		-name   => "SLIqualita",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => 100,
		-height => $height,
		-text=>"80",
		-selrange => 1,
	);
	#-vertical=> 1,
	$WIN->SLIqualita->SetBuddy(1, $WIN->AddLabel(-text => 'Min'));
	$WIN->SLIqualita->SetBuddy(0, $WIN->AddLabel(-text => 'Max'));
	$WIN->SLIqualita->Min(10);
	$WIN->SLIqualita->Max(100);
	$WIN->SLIqualita->Pos(80);
 
	my $BTcreapdf = $WIN->AddButton(
		-name => "BTcreapdf",
		-text => "Crea PDF",
		-left   => $col3,
		-top    => $vtab * $riga,
		-width  => $BTwidth,
		-height => $height,
	);
	$BTcreapdf->Disable(); 

	# riga 3: sovrastampa
	$riga = 3;
	
	$WIN->AddLabel(
		-name   => "TLsovrastampa",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"sovrastampa",
	);

	$WIN->AddTextfield(
		-name   => "TFLDsovrastampa",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => $TFDwidth,
		-height => $height,
		-text=>"http://sommaruga.stnet.net",
	);

	my $BTfine = $WIN->AddButton(
		-name => "BTfine",
		-text => "fine",
		-left   => $col3,
		-top    => $vtab * $riga,
		-width  => $BTwidth,
		-height => $height,
	);


	# riga 4: contatri
	$riga = 4;
	
	$WIN->AddLabel(
		-name   => "TLcontatore",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"contapagine",
	);

	$WIN->AddTextfield(
		-name   => "TFLDcontatore",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => 100,
		-height => $height,
		-text=>"0",
	);

	# riga 5: tmpdir
	$riga = 5;
	
	$WIN->AddLabel(
		-name   => "TLtmpdir",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"tmp dir",
	);

	$WIN->AddTextfield(
		-name   => "TFLDtmpdir",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => $TFDwidth,
		-height => $height,
		-text=>"$tmpdir",
	);

	# riga 6: outfile
	$riga = 6;
	
	$WIN->AddLabel(
		-name   => "TLoutfile",
		-left   => $col1,
		-top    => $vtab * $riga,
		-width  => $TLwidth,
		-height => $height,
		-text=>"PDF creato",
	);

	$WIN->AddTextfield(
		-name   => "TFLDpdf",
		-left   => $col2,
		-top    => $vtab * $riga,
		-width  => $TFDwidth,
		-height => $height,
		-text=>"$outfile",
	);

	$WIN->AddButton(
		-name   => "BTvisualizzapdf",
		-left   => $col3,
		-top    => $vtab * $riga,
		-width  => $BTwidth,
		-height => $height,
		-text=>'Visualizza PDF',
	);

	# riga 7: listbox
	$riga = 7;
	
	$WIN->AddListbox(
		-name => "LBimmagini",
		-left => $col2,
		-top    => $vtab * $riga,
		-width  => 400,
		-height => 300,
		-selectmode => 'browse',
	);

	#$WIN->AddGraphic(
	#	-name => "GRimmagine",
	#	-left => 620,
	#	-top    => $vtab * $riga,
	#	-width  => 250,
	#	-height => 300,
	#	-background => '#282828',
	#);
	
	my $dib = newFromFile Win32::GUI::DIBitmap ('image.jpg');
	$dib = $dib->Rescale (200, 200,0);
	my $bitmap = $dib->ConvertToBitmap();
	undef $dib;
	my $BTimmagine = $WIN->AddButton (
		-name    => "BTimmagine",
		-pos     => [620, $vtab * $riga],
		-size    => [250, 300],
		-visible => 1,
		-bitmap  => $bitmap,
	);
	#$WIN->BTimmagine->SetImage($bitmap);

	#
	#	blocco test INI file
	#
	# $ARGV[0] -> valore primo elemento passato
	# $#ARGV   -> indice ultimo elemento
	# @ARGV    -> array
	my $inifile = "scanner.ini";
	#print "$#ARGV\n";
	if ($#ARGV == 0)
	{
		# controllo se passato inifile per parametro
		$inifile = $ARGV[0];
		#print  "passato $inifile\n";
	}
	if (-e $inifile)
	{
		# se inifile esiste...
		my $cfg = new Config::IniFiles( -file => $inifile , -nocase => 1 );
		my $inisection = "scanner";
		
		$WIN->SLIqualita->Pos($cfg->val( $inisection, 'qualita' ));
		$WIN->TFLDdotxx->Text($cfg->val( $inisection, 'dotxx' ));
		$WIN->TFLDdotyy->Text($cfg->val( $inisection, 'dotyy' ));
		$WIN->TFLDsovrastampa->Text($cfg->val( $inisection, 'sovrastampa' ));
		#$WIN->TFLDtmpdir->Text($cfg->val( $inisection, 'tmpdir' ));
		#$WIN->TFLDoutfile->Text($cfg->val( $inisection, 'outfile' ));
		if ($cfg->val( $inisection, 'showdos' )==1) 
		{
			# se richiesta finestra DOS di debug
			Win32::GUI::Show($DOS);
		}
		# correzione backslash in slash
		#{
		#my $tmp = $WIN->TFLDtmpdir->Text();
		#$tmp =~ s/\\/\//g;
		#$WIN->TFLDtmpdir->Text($tmp);
		#$tmp = $WIN->TFLDoutfile->Text();
		#$tmp =~ s/\\/\//g;
		#$WIN->TFLDoutfile->Text($tmp);
		#}
	} else {
		#print  "non trovo $inifile\n";
	}

	#
	#	attiva l'interfaccia verso lo scanner
	#
	my $scanner = new Win32::Scanner::EZTWAIN("./",  $WIN);
	$WINsb->Text("Selezione scanner");
	$scanner->select_image_source();

	# commento:
	# new Win32::API("${path_to_dll}eztw32.dll", "TWAIN_IsAvailable", undef, 'N')

	#
	# All'avvio...cancella eventuali file rimasti da precedenti run
	#
	# il sub indica la dichiarazione di un prototipo....
	sub CancellaTmpScanner();

	#
	# loop eventi
	#
	$WIN->Show();
	Win32::GUI::Dialog();
  
#
# termina programma
#
sub WINScanner_Terminate {
	CancellaTmpScanner();
	return -1;
}
#
# resize
#
sub WINScanner_Resize {
        $WINsb->Move(0, $WIN->ScaleHeight - $WINsb->Height);
        $WINsb->Resize($WIN->ScaleWidth, $WINsb->Height);
    }


#######################
#
# gestori eventi
#
#######################

sub BTscansione_Click  { ScansionePagina(), $BTcreapdf->Enable(); }
sub BTcreapdf_Click  { CreaPdf(), AprePdf() }
sub BTfine_Click  { -1 }
sub LBimmagini_Click {
	my $LBSelection = $WIN->LBimmagini->GetCurSel();
	my $selectfile = $WIN->LBimmagini->GetString($LBSelection);
	#Win32::MsgBox($selectfile);
	$selectfile =~ s/\//\\\\/g;
 
  # chiedo conferma per cancellazione...rende 6=yes 7=no
  if (Win32::MsgBox("Confermi cancellazione di $selectfile", 32+4) == 6) {
    # confermata cancellazione
  	unlink $selectfile;
    $WIN->LBimmagini->DeleteString($LBSelection);
  }
	VisualizzaImmagine($selectfile);
}
sub BTvisualizzapdf_Click  { VisualizzaPdf() }

#######################
#
# click su finestra file inseriti per consentire cancellazione
#
#######################
sub ClickForDelete() {
  my $LBSelection = $WIN->LBimmagini->GetCurSel();
  my $selectfile = $WIN->LBimmagini->GetString($LBSelection);
  #Win32::MsgBox($selectfile);
  $selectfile =~ s/\//\\\\/g;

  # chiedo conferma per cancellazione...rende 6=yes 7=no
  if (Win32::MsgBox("Confermi cancellazione di $selectfile", 32+4) == 6) {
  # confermata cancellazione
    unlink $selectfile;
    $WIN->LBimmagini->DeleteString($LBSelection);
  }
  VisualizzaImmagine($selectfile);
}


#######################
#
# altro codice chiamato dai gestori eventi
#
#######################
sub ScansionePagina() {
	my $tmpfile = "$tmpdir/scanner.bmp";
	my $nuovofile;
	my $nrpagina = $WIN->TFLDcontatore->Text();
	my $sovrastampa = $WIN->TFLDsovrastampa->Text();
	my $qualita = $WIN->SLIqualita->Pos();
	my $dotxx = $WIN->TFLDdotxx->Text();
	my $dotyy = $WIN->TFLDdotyy->Text();

	#
	# in base al numero di pagine acquisito...determina il nome del file immagine per il salvataggio
	# incremento di 100 per evitare il problema dell strzero(npagina)
	#
	$nrpagina = $nrpagina + 1;
	$WIN->TFLDcontatore->Text($nrpagina);
	$nrpagina = $nrpagina + 100;
	$nuovofile = "$tmpdir/scanner_$nrpagina.jpg";
	
	#
	# blocco scansione
	#
	$WINsb->Text("Acquisizione $tmpfile...");
	$scanner->acquire_to_file("$tmpfile");
	
	my $image = new Image::Magick;
	$WINsb->Text("Lettura $tmpfile...");
	$image->Read("$tmpfile");
	$image->Resize(width=>$dotxx, height=>$dotyy, filter=>"Cubic");
	if ( $sovrastampa ne '' ) {
		$image->Annotate(text=>'http://sommaruga.stnet.net',
			font=>"Verdana",
			pointsize=>12,
			fill=>"#000000",
			antialias=>"true",
			x=>17,
			y=>20);
		$image->Annotate(text=>'http://sommaruga.stnet.net',
			font=>"Verdana",
			pointsize=>12,
			fill=>"#ffffff",
			antialias=>"true",
			x=>15,
			y=>18);
	}
	
	$image->Set(quality=>$qualita);
	$WINsb->Text("Conversione $tmpfile in $nuovofile");
	$image->Write(filename=>"$nuovofile", compression=>'jpeg');
	$WINsb->Text("in attesa");
	undef $image;

	#
	# aggiorna la listbox e la miniatura
	#
	#$WIN->LBimmagini->AddFile($nuovofile);
	$WIN->LBimmagini->AddString($nuovofile);
	
	#my $dib = newFromFile Win32::GUI::DIBitmap ($nuovofile);
	#my $hbitmap = $dib->ConvertToBitmap();
	#undef $dib;
	#undef $hbitmap;
	
	#
	# Visualizza immagine
	#
	VisualizzaImmagine($nuovofile);

}


##########################################
#
#
# visualizza immagine dal file
#
#
##########################################
sub VisualizzaImmagine {
	my $nomedelfile = $_[0];
	
	# debug
	#Win32::MsgBox($nomedelfile);
	if (-e $nomedelfile) {
		my $dib2 = newFromFile Win32::GUI::DIBitmap ($nomedelfile);
		$dib2 = $dib2->Rescale (200, 200,0);
		my $bitmap2 = $dib2->ConvertToBitmap();
		$BTimmagine->SetImage($bitmap2);
		undef $dib2;
	} else {
		Win32::MsgBox("non esiste $nomedelfile");
	}
}


#############################################################
#
#
#	blocco creazione pdf
#
#
#############################################################

#use warnings;
#use strict;
sub CreaPdf() {
my $pdf;
my @files;
my $file;
my $rc;

	chdir( $tmpdir ) or die "Non riesco a posizionarmi in $tmpdir $!";
	while( <scanner_*.jpg> ) 
	{
		push @files, $_;
		$WINsb->Text("Aggiunta di $_");;
	}

	$pdf = Image::Magick->new();

	foreach $file ( sort @files ) 
	{
		my $img = Image::Magick->new();
		$rc = $img->Read( $file );
		warn $rc if $rc;
		push @$pdf, $img;
	}

	$pdf->[0]->Coalesce();
	$pdf->Write( $outfile );
	
	#
	# dopo la scansione cancella i file temporanei della scansione
	#
	CancellaTmpScanner();
	#
	# cancella anche la lista a video
	#
	$WIN->LBimmagini->ResetContent();
	$BTcreapdf->Disable(); 
}

sub VisualizzaPdf() {
	#my $app = Win32::OLE->new('AcroExch.App');
	my $app = Win32::OLE->new('Acroexec.App');
	$app->Show();
	#my $avdoc = Win32::OLE->new('AcroExch.AVDoc');
	my $avdoc = Win32::OLE->new('Acroexec.AVDoc');
	$avdoc->Open($outfile,$outfile);
	$avdoc->BringToFront();
}

sub CancellaTmpScanner() {
	#
	# dopo la scansione cancella i file temporanei della scansione
	#
	my $scandir = $tmpdir;
	$scandir =~ s/ /?/g;
	my @filelist = glob ($scandir . "/scanner_*.jpg");
	unlink @filelist;
}
