#/usr/local/bin
#Use: permet de dire au programme d'utiliser les bibliothèques spécifiées
#----------------------------------------------------------
use Tk;
use locale;
use LWP::Simple; #Utilisée pour faire la récupération des URLs
use Encode;
use HTML::Entities;
use Tk::NoteBook; #Permet de gérer les onglets
use Tk::SMListbox;
use Win32::Process;
#----------------------------------------------------------
# definition interface jusqu'au MainLoop ligne 123
#----------------------------------------------------------
# creation de la fenetre principale
$mw= MainWindow->new;
$mw->title("SuperExtractor");
#---------------------------------------------------------
#On crée un cadre -frame- que l'on met en haut
my $cadreMenu = $mw->Frame->pack(-side => 'top',
			  -expand=>0,
			  -fill => 'both');
			  
#On crée un objet capable de gérer des listes de menu -menubutton-
my $b_menu=$cadreMenu->Menubutton(-text => "Fichier", -foreground=>'black',
				  -tearoff => 0,
				  -relief => 'ridge',
				  -menuitems => [ #Option qui permet de définir la liste des options visibles associées à des actions dans le menu créé
						 ['command' => "Charger fichier",
						 -command => \&lire_file],
						 ['command' => "Charger URL", 
						 -command => \&lire_url],
						  ['command' => "URL vers .txt", 
						 -command => \&url2txt],
						  ['command' => "Sauvegarder l'éditeur", 
						 -command => \&sauve_editor],

						 ['command' => "Rapport sur le fichier ou URL", 
						 -command => \&rapport],
						 ['command' => "Sortir", -
						 command =>  sub {exit;}]])->pack(-side => 'left');
						 
my $b_menu=$cadreMenu->Menubutton(-text => "Syntaxe", -foreground=>'black',
				  -tearoff => 0,
				  -relief => 'ridge',
				  -menuitems => [ #Option qui permet de définir la liste des options visibles associées à des actions dans le menu créé
						['command' => "Treetagger",
						 -command => \&loadtreetagger],
						['command' => "Extraction de patron (Nom-Adj)",
						 -command => \&extract_pattern],
						['command' => "Extraction de patron (Nom-Prep-Nom)",
						 -command => \&extract_pattern_npn],
						 ])->pack(-side => 'left');

my $b_menu=$cadreMenu->Menubutton(-text => "?", -foreground=>'black',
				  -tearoff => 0,
				  -relief => 'ridge',
				  -menuitems => [ #Option qui permet de définir la liste des options visibles associées à des actions dans le menu créé
						['command' => "Mode d'emploi du SuperExtractor",
						 -command => \&mode_emploi],
						 ])->pack(-side => 'left');

#---------------------------------------------------------
#On crée un nouveau cadre que l'on met en haut qui va contenir l'ensemble des onglets
my $cadre = $mw->Frame->pack(-side => 'top',
			  -expand=>1,
			  -fill => 'both');

#On crée un widget qui permet de créer des onglets -Notebook-
my $onglet=$cadre->NoteBook(
				-foreground=>'black', 
	
				)->pack(-side=>'top',
					-expand=>1,
					-fill=>'both');

#Je crée quatre pages dans mon objet de type onglet
my $page1=$onglet->add("page1",-anchor=>'w',label=>'Edition-URL',-underline=>0);
my $page2=$onglet->add("page2",-anchor=>'w',label=>'Dictionnaire',-underline=>0);
my $page3=$onglet->add("page3",-anchor=>'w',label=>'Concordance',-underline=>0);
my $page4=$onglet->add("page4",-anchor=>'w',label=>'Rapport sur fichier ou URL',-underline=>0);
my $page5=$onglet->add("page5",-anchor=>'w',label=>'Treetagger',-underline=>0);
my $page6=$onglet->add("page6",-anchor=>'w',label=>'Extraction de Patron',-underline=>0);
my $page7=$onglet->add("page7",-anchor=>'w',label=>'Mode d\'emploi',-underline=>0);

#------------------------------------------------------------
# interface de la page 1 : edition d' URL...
#------------------------------------------------------------

#Je crée un cadre dans la page 1
my $cadreP1=$page1->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'top', -fill => 'both',-expand=>'0');
$cadreP1->configure;


my $cadreP2=$page1->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'top', -fill => 'both',-expand=>'1');
$cadreP2->configure;

my $cadreP2b=$page1->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'top', -fill => 'both',-expand=>'0');
$cadreP2b->configure;

my $cadreP3=$page1->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'top', -fill => 'both',-expand=>'0');
$cadreP3->configure;

$cadreP1->Label(-text => "URL : ",
    	      -relief => 'raised')->pack(-side => 'left',
						  -anchor => 'w');
						  
#Je définis une zone de saisie via mécanisme interne à la zone de récupérer ce qui est dans la zone et l'associe à variable $url
$cadreP1->Entry(-textvariable => \$url)->pack(-side => 'left',
						-anchor => 'w',
						-fill => 'x',
						-expand => 1);
$cadreP1->Button(-text => "Charger l'URL", -background=> '#C0C0C0', -foreground=>'black',
	       -command => sub {&lire_url})->pack(-side => 'left',
						   -anchor => 'e');
$cadreP1->Button(-text => "URL vers texte", -background=> '#C0C0C0', -foreground=>'black',
	       -command => sub {&url2txt})->pack(-side => 'left',
						   -anchor => 'e');
#--------- Editeur fenetre principale ---------------
#Dans le cadreP2 je crée un objet text dans lequel je prévoie d'insérer le contenu de l'URL que je vais charger
#Scrolled permet de définir directement des ascenseurs




#------------------------------------------------------------------------------





$editortexte = $cadreP2->Scrolled("Text")->pack(-side => 'bottom',
				      -fill => 'both',
					  -expand => 1);
$editortexte->Text(-setgrid => 'true');
$search_string = '';
$w_string = $cadreP2b->Frame()->pack(-side => 'top', -fill => 'x');
$w_string_label = $w_string->Label(-text => 'Chercher mot:', -width => 13, -anchor => 'w');
$w_string_entry = $w_string->Entry(-textvariable => \$search_string);
$w_string_button = $w_string->Button(-text => 'Surligner',-background=> '#C0C0C0', -foreground=>'black',);
$w_string_label->pack(-side => 'left');
$w_string_entry->pack(-side => 'left');
$w_string_button->pack(-side => 'left', -pady => 5, -padx => 10);
$w_string->pack(-side => 'top', -fill => 'x');
$w_string_button->configure(-command => [sub {&text_search($editortexte, $search_string, 'search')}, $editortexte]);
$w_string_entry->bind('<Return>' => [sub {shift; &text_search($editortexte, $search_string, 'search')}, $editortexte]);
$w_string->pack(-side => 'top', -fill => 'x');
if ($mw->depth > 1) {
	text_toggle($editortexte, ['configure', 'search', -background => 'SeaGreen4', -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      } else {
	text_toggle($editortexte, ['configure', 'search', -background => 'black',     -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      }
#-----------------------------------------------------
sub sauve_editor {
#--------------------------------------------------------------------------------

$edit=$editortexte->get("1.0",'end');   #<< On récupère le texte et on le stocke dans une variable

open (FILEOUT,">sauvegarde.txt");
print FILEOUT $edit;
print $edit;
close (FILEOUT);
}




#---------------------------------------------------------------
# il faudra créer les contenus des autres pages...
#page 2
my $cadreGG=$page2->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'right', -fill => 'both',-expand=>'1');
$cadreGG->configure;

#expand = extension du cadre

my $cadreG=$page2->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'0');
$cadreG->configure;


my $framedico=$cadreG->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$framedico->configure;
my $labelDico=$framedico->Label(-text => "Dictionnaire", -foreground=>'black', -height=>2, -width=>15)->pack( -side => 'top', -padx => 5, -pady =>5);
$framedico->Button(-text => 'Concordance', -foreground=>'black', -command => sub {&concordance}) ->pack(-side => 'top', -padx => 5, -pady =>5);


my $cadreD=$cadreGG->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$cadreD->configure;


$editortextetmp = $cadreD->Scrolled('SMListbox',

                -scrollbars => 'se',
                -height => 24,
				-width => 306,
                -relief => 'sunken',
                -sortable => 1,
                -selectmode => 'extended',
                -showallsortcolumns => 1,
                -takefocus => 1,
                -borderwidth => 0,
                -columns => [
						
						#comparecommand= paramètre de tri de la colonne
						#cmp=compare les éléments de la liste en tant que chaîne de caractères
						#<=> = compare les valeurs numériques
                        [-text => 'Forme', -textwidth => 40, -fg => 'black',-bg => 'white', -comparecommand => sub { $_[1] cmp $_[0]}],
                        [-text => 'Fréquence', -textwidth => 13, -fg => 'black', -bg => 'white',-comparecommand => sub { $_[1] <=> $_[0]}],

                        
                ]

                )->pack(-side =>'top',
						-expand => 1,
						-padx => 0,
						-pady => 0,
                        -fill => 'both',

                );

#.......
#création de la page 3, page de la concordance
my $listeconcordance=$page3->Scrolled('SMListbox',

                -scrollbars => 'se',
                -height => 24,
				-width => 300,
                -relief => 'sunken',
				-sortable => 1,
                -selectmode => 'extended',
                -showallsortcolumns => 1,
                -takefocus => 1,
                -borderwidth => 1,
                -columns => [
						
						#comparecommand= paramètre de tri de la colonne
						#cmp=compare les éléments de la liste en tant que chaîne de caractères
						#<=> = compare les valeurs numériques
                        [-text => 'Contexte gauche', -textwidth => 30, -fg => 'black', -bg => 'white', -comparecommand => sub { $_[1] cmp $_[0]}],
                        [-text => 'Pôle', -textwidth => 15, -fg => 'black', -bg => 'white', -comparecommand => sub { $_[1] <=> $_[0]}],
						[-text => 'Contexte droit', -textwidth => 30, -fg => 'black', -bg => 'white', -comparecommand => sub { $_[1] cmp $_[0]}],

                        
                ]

                )->pack(-side =>'top',
						-fill=> 'both',
						-expand => 'yes',
						-padx => 0,
						-pady => 0,
                       
                );



#---------------------------------------------------------------

#---------------------------------------------------------------

#PAGE 5

my $cadrep5=$page5->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$cadrep5->configure(-background => 'black');

$editortexteP5 = $cadrep5->Scrolled("Text")->pack(-side => 'bottom',
				      -fill => 'both',
					  -expand => 1);
$editortexteP5->Text(-setgrid => 'true');

#---------------------------------------------------------------
#Page 6
my $cadrep6=$page6->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$cadrep6->configure(-background => 'black');

$editortexteP6 = $cadrep6->Scrolled("Text")->pack(-side => 'bottom',
				      -fill => 'both',
					  -expand => 1);
$editortexteP6->Text(-setgrid => 'true');

#---------------------------------------------------------------
#Page 4
my $cadrep4=$page4->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$cadrep6->configure(-background => 'black');

$editortexteP4 = $cadrep4->Scrolled("Text")->pack(-side => 'bottom',
				      -fill => 'both',
					  -expand => 1);
$editortexteP4->Text(-setgrid => 'true');

#---------------------------------------------------------------
#Page 7

my $cadreP72=$page7->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'top', -fill => 'both',-expand=>'1');
$cadreP72->configure;


my $cadrep7=$cadreP72->Frame(-borderwidth => '0', -relief => 'groove')->pack(-side => 'left', -fill => 'both',-expand=>'1');
$cadreP72->configure(-background => 'black');

$editortexteP7 = $cadrep7->Scrolled("Text")->pack(-side => 'bottom',
				      -fill => 'both',
					  -expand => 1);
$editortexteP7->Text(-setgrid => 'true');

my $cadreP7b=$cadrep7->Frame(-borderwidth => '2', -relief => 'groove')->pack(-side => 'bottom', -fill => 'both',-expand=>'0');
$cadreP7b->configure;

$search_string = '';
$w_string = $cadreP7b->Frame()->pack(-side => 'top', -fill => 'x');
$w_string_label = $w_string->Label(-text => 'Chercher mot:', -width => 13, -anchor => 'w');
$w_string_entry = $w_string->Entry(-textvariable => \$search_string);
$w_string_button = $w_string->Button(-text => 'Surligner',-background=> '#C0C0C0', -foreground=>'black',);
$w_string_label->pack(-side => 'left');
$w_string_entry->pack(-side => 'left');
$w_string_button->pack(-side => 'left', -pady => 5, -padx => 10);
$w_string->pack(-side => 'top', -fill => 'x');
$w_string_button->configure(-command => [sub {&text_search($editortexteP7, $search_string, 'search')}, $editortexteP7]);
$w_string_entry->bind('<Return>' => [sub {shift; &text_search($editortexteP7, $search_string, 'search')}, $editortexteP7]);
$w_string->pack(-side => 'top', -fill => 'x');
if ($mw->depth > 1) {
	text_toggle($editortexteP7, ['configure', 'search', -background => 'SeaGreen4', -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      } else {
	text_toggle($editortexteP7, ['configure', 'search', -background => 'black',     -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      }








#---------------------------------------------------------------

#---------------------------------------------------------------
MainLoop;
#---------------------------------------------------------------



#---------------------Procédures------------------------------
sub mode_emploi {

$editortexteP7->delete("1.0","end");

	#J'ouvre le fichier
	open(MODE, "mode_emploi.txt");

	while (<MODE>) {

		$mode_emploi=$_;
		
			#J'insère le contenu du fichier dans l'éditeur de texte
			$editortexteP7->insert("end",$mode_emploi);
	}


	#J'insère le contenu du fichier dans l'éditeur de texte
	$editortexteP7->insert("end",$mode_emploi);

$onglet->raise('page7');	

}

#---------------------------------------------------------------
#LIRE file

sub lire_file {

	my $types=[
		['Text Files', ['.txt', '.dic', '.par']],
		['All files', ['*.*']]
		];
		
	my $tmp_nom_source=$mw->getOpenFile(-filetypes=>$types);
	print $tmp_nom_source, "\n";
	
	#On teste pour être sûr que l'utilisateur a sélectionné quelque chose
	#Si vide, return.
	if ($tmp_nom_source=~/^$/) {
		return;
	}
	
	#Je crée une variable qui va stocker le contenu du fichier
	my $texte="";
	$url=$tmp_nom_source;
	
	#J'ouvre le fichier
	open(TMP, $tmp_nom_source);
	
	#Je parcours le fichier
	while (<TMP>) {
	
		#Je concatène chacune des lignes du fichier
		$texte.=$_;
	}
	
	close (TMP);
	
	#Je vide le contenu de la page 1
	$editortexte->delete("1.0","end");
	
	#J'insère le contenu du fichier dans l'éditeur de texte
	$editortexte->insert("end",$texte);
	
	#On lance la génération du dictionnaire
	&makedico($texte);
}






#---------------------------------------------------------------

#fonction lire url

sub lire_url {
    $info="Chargement $url...";
	
	#editortexte est un objet graphique de type éditeur qui dispose de fonctionnalités
	#delete est une fonction qui permet de vider le contenu de l'éditeur de la position 1.0 à la dernière position
    $editortexte->delete("1.0","end");

	#fonction get est une fonction prédéfinie dans biblio LWP Simple
	#cette fonction prend une URL comme argument et récupère le contenu de l'URL
    my $page = get( $url );

	#Si ce qu'on récupère n'est pas défini, on affiche un message d'erreur
    if ( not defined( $page ) ){
	print "Problème lors du téléchargement !\n";
    }

	#Quand ça fonctionne, on revient sur l'éditeur et on utilise la fonction insert 
	#qui permet d'insérer une chaîne de caractères dans un objet éditeur
    $editortexte->insert("end",$page);

	
    $info = "$url loaded.";
	

}
#----------------------------------------------------------------

#fonction url2txt

sub url2txt {
    $editortexte->delete("1.0","end");
    my $page = get( $url );
    if ( not defined($page) ){
	die "Problème lors du téléchargement !\n";
    }
	
	#-------------------------------------------------------------
	#Procédure makedico
	
	sub makedico {
		
		#On crée une variable locale qui correspond à l'argument contenu dans le tableau des arguments
		#
		
		my ($texteasegmenter)=@_; #@_ est une variable qui correspond aux arguments de la procédure
		
		#On segmente le texte en mots
		my @listemots=split(/\W+/,$texteasegmenter);
		
		
		#On va créer une table de hachage avec comme clef le mot et sa valeur sera sa fréquence
		my %dico=();
		foreach my $mot (@listemots){
			if (exists($dico{$mot})) {
				$dico{$mot}++;
				
			}
			else {
				$dico{$mot}=1;
			}
			
		}
		foreach my $mot (sort keys %dico) {
		
		#On insère une ligne dans un objet smlistbox
			$editortextetmp->insert("end",[$mot, $dico{$mot}]);
		}
	
	}
	
	
	
	
	#-------------------------------------------------------------
	#On normalise en ISO-Latin le contenu de la page
	#Opérations de décodage de la page
    my $codage_page = "latin1";
    if ($page =~ /\bcharset\s*=\s*([\w-]+)/i) {
	$codage_page = $1;
	eval { decode ($codage_page, "test") };
	if ( defined ($@) ) {
	    $codage_page = "latin1";
	}
    }
    my $page_unicode = decode( $codage_page, $page );
    my $texte_unicode = supprime_html( $page_unicode );
    my $texte = normalise_latin1( $texte_unicode );
    $editortexte->insert("end",$texte);
	
	#On déclenche création dico
	
	&makedico($texte);
	
	
	
	#---------------------------------------------------------------


	
    #-------------------------------------------------------------
	#Suppression des balises
    sub supprime_html { 
	my @balises_a_ignorer =
	    ("applet","code","embed","head","object","script","server");
	
	my $html = shift @_; 
	$html =~ s/\n+/ /g;
	$html =~ s/\r+/ /g;
	decode_entities($html);
	foreach my $balise (@balises_a_ignorer) {
	    $html=~s/<$balise.*?<\/$balise>//ig;
	}
	$html =~ s/<!--.*?-->//g;     #commentaires
	$html =~ s/<\/?p\/?>/\n/ig;   #paragraphes
	$html =~ s/<br\/?>/\n/ig;     #retours à la ligne
	$html =~ s/<\/tr>/\n/ig;      #lignes de tableau
	$html =~ s/<\/?h[1-6]>/\n/ig; #titres
	$html =~ s/<\/?div.*?>/\n/ig; #sections
	$html =~ s/<.*?>//g;          #autres balises
	$html =~ s/\s*\n\s*/\n/g;     #espaces en début/fin de ligne
	$html =~ s/ +/ /g;            #séquences de plusieurs espaces  
	return $html;
    }
    sub normalise_latin1 {
	my $chaine = shift @_;
	$chaine =~ s/[\x{2019}\x{2018}]/\'/g;
	$chaine =~ s/[\x{201C}\x{201D}]/\"/g;
	$chaine =~ s/[\x{2013}\x{2014}]/-/g;
	$chaine =~ s/\x{2026}/.../g;
	$chaine =~ s/\x{0152}/OE/g;
	$chaine =~ s/\x{0153}/oe/g;
	$chaine =~ s/[^\x{0000}-\x{00FF}]//g;
	return $chaine;
    }
}
#-------------------------------------------------------------------------------
sub rapport {
#-------------------------------------------------------------------------------
open(FILETTT,"sauvegarde.txt");
@FILEIN=<FILETTT>;
close(FILETTT);


$editortexteP4->delete("1.0","end");

#On crée un compteur pour compter les lignes, les mots et les mots différents
$i=0;
$j=0;
$k=0;

#On crée un dictionnaire
%dico=();

#Tant qu'il y a des lignes à lire...

foreach $lines (@FILEIN) {

	#On crée un tableau avec un mot par ligne
    my @TAB=split(/[\W]/,$lines);
	
	#On incrémente le compteur
	$i++;
	
	#Pour chaque mot du tableau...
    foreach my $mot (@TAB) {
		
		#On incrémente le compteur:
		$j++;
		
		#Afin de ne pas compter les blancs on ajoute une condition
		if ($mot ne "") {
		
			#Si le contenu de la variable $mot existe dans le dico alors:
			if (exists($dico{$mot})) {
				#On calcule la fréquence...
				$dico{$mot}++;
			}
			
			#Si le contenu de la variable $mot n'existe pas dans le dico alors:
			else {
				#On affecte la valeur 1 à la valeur de la clé $mot du tableau $dicomots
				$dico{$mot}=1;
				#On incrémente le compteur $compteurmotsdifferents
				$k++;
			}
		}
	}
}



open (FILEOUTRAPPORT,">rapport.txt");

#Puis on affiche un petit "résumé":
print FILEOUTRAPPORT "\nResultat de l'analyse du fichier:\n";
print FILEOUTRAPPORT "\nFichier analysé: $url\n\n";

#Si la variable $i contient 0 alors:
if ($i==0) {
	#On affiche "Le fichier ne contient aucune ligne."
	print FILEOUTRAPPORT "Le fichier ne contient aucune ligne.\n";
}

#Si $i contient une ligne alors:
elsif ($i==1) {
	#On affiche "Le fichier contient $i ligne." avec retour à la ligne.
	print FILEOUTRAPPORT "Le fichier contient $i ligne.\n";
}
#Si $i ne contient ni 0 ni 1 alors:
else {
	#On affiche "Le fichier contient $i lignes.\n" puis retour à la ligne:
	print FILEOUTRAPPORT "Le fichier contient $i lignes.\n";
}

#Si la variable $j contient 0 alors:
if ($j==0) {
	#On affiche "Le fichier ne contient aucun mot."
	print FILEOUTRAPPORT "Le fichier ne contient aucun mot.\n";
}

#Si $i contient un mot alors:
elsif ($j==1) {
	#On affiche "Le fichier contient $i mot." avec retour à la ligne.
	print FILEOUTRAPPORT "Le fichier contient $j mot.\n";
}
#Si $i ne contient ni 0 ni 1 alors:
else {
	#On affiche "Le fichier contient $i mots.\n" puis retour à la ligne:
	print FILEOUTRAPPORT "Le fichier contient $j mots.\n";
}



close FILEOUTRAPPORT;

open(FF,"rapport.txt");
@RAPPORT=<FF>;
close(FF);



$editortexteP4->insert("end","@RAPPORT\n");
close FF;

$onglet->raise('page4');

}





#---------------------------------------------------------------
sub search_in_fic {
    
    $info="Recherche dans le fichier...";
    &text_search($editortexte, $search_string, 'search');
    if ($mw->depth > 1) {
	text_toggle($editortexte, ['configure', 'search', -background => 'SeaGreen4', -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      } else {
	text_toggle($editortexte, ['configure', 'search', -background => 'black',     -foreground => 'white'], 800,
		          ['configure', 'search', -background => undef,       -foreground => undef],   200);
      }

    $info= "Recherche dans Fichier terminée.";
}
#---------------------------------------------------------------
sub text_search {

    # The utility procedure below searches for all instances of a given string in a text widget and applies a given tag
    # to each instance found.
    # Arguments:
    #
# w -	The window in which to search.  Must be a text widget.
    # string -	The string to search for. (regexp and so on...)
    # tag -	Tag to apply to each instance of a matching string.

    my($w, $string, $tag) = @_;

    $w->tag('remove',  $tag, '0.0', 'end');
    (my $num_lines) = $w->index('end') =~ /(\d*)\.\d*/;
    for($i = 1; $i <=$num_lines; $i++) {
	my $line = $w->get("${i}.0", "${i}.1000");
	next if not defined $line or $line !~ /($string)/;
        my $l = length $1;
	$stringRegexp=$1;
	my $offset = 0;
	while (1) {
	    my $tmpoffset=0;
	    my $index = index $line, $stringRegexp, $tmpoffset;
	    last if $index == -1;
	    $offset += $index;
	    $w->tag('add', $tag, sprintf("%d.%d", $i, $offset), sprintf("%d.%d", $i, $offset+$l));
	    $offset += $l;
	    $line = substr $line, $index+$l;
	    if ($line=~/($string)/) { $stringRegexp=$1;
				      $l = length $1;}
	} # whilend
    } # forend

} # end text_search
#---------------------------------------------------------------
sub text_toggle {
    # The procedure below is invoked repeatedly to invoke two commands at periodic intervals.  It normally reschedules itself
    # after each execution but if an error occurs (e.g. because the window was deleted) then it doesn't reschedule itself.
    # Arguments:
    #
    # w -       Text widget reference.
    # cmd1 -	Reference to a list of tag options.
    # sleep1 -	Ms to sleep after executing cmd1 before executing cmd2.
    # cmd2 -	Reference to a list of tag options.
    # sleep2 -	Ms to sleep after executing cmd2 before executing cmd1 again.
    my($w, $cmd1, $sleep1, $cmd2, $sleep2) = @_;
# return if not Exists $w;
    $w->tag(@{$cmd1});
    $w->after($sleep1, [sub {text_toggle(@_)}, $w, $cmd2, $sleep2, $cmd1, $sleep1]);
} # end text_toggle



#---------------------------------------------------------------
#Concordance


sub concordance {


	#recherche des motifs sélectionnés dans le dico
	#On récupère ce que l'utilisateur a sélectionné avec sa souris dans la sm listbox dico
	my @selection = $editortextetmp->curselection();
	
	#Je vérifie si la sélection n'est pas vide
	if ($#selection eq -1) {
		
		return;
		
	}
	
	#Je crée une liste vide dans laquelle j'aurais les motif sur lesquels lancés la concordance
	my @listeItem=();
	
	
	#J'ai mémorisé dans sélection les positions des mots
	#Je crée un compteur qui va lire les lignes correspondant aux indices sélectionnés dans la liste
	for (my $sel=0;$sel <= $#selection; $sel++) {
	
		#Je récupère les lignes correspondantes
		#getRow renvoie à une liste correspondant aux différents éléments de la ligne
		#dans @formes j'ai la liste des colonnes
		my @formes=$editortextetmp->getRow($selection[$sel]);
		#ce qui m'intéresse c'est le premier élément
		my $forme=$formes[0];
		print $forme, "\n";
		#Je mets ces mots dans la liste des items
		push (@listeItem,$forme);
		}
	
	#Je récupère le contenu total de l'objet texte du texte qui m'intéresse
	my $texte=$editortexte->get("1.0",'end');
	
	#Nombre de msots qu'on veut dans le contexte
	my $nbre_mots_a_garder_ds_contexte=5;
	
	#On parcourt...
	foreach my $motif (@listeItem) {
		
		#on lance la concordance du $motif sur $texte
		
		
		
		while($texte=~/\b$motif\b/gi) { 
			my $gauche=$`;
			my $pole=$&;
			my $droite=$';
			$droite=~s/^ //;
	
			#Je découpe la chaîne de caractères sur la base de l'expression régulière
			#"tout ce qui n'est pas caractère alphanumérique".
			my @GAUCHE=split(/\W+/,$gauche);


			#Je découpe la chaîne de caractères sur la base de l'expression régulière
			#"tout ce qui n'est pas caractère alphanumérique".
			my @DROITE=split(/\W+/,$droite);

			#On recrée le contexte droit
			#Liste temporaire vide
			my $tmpdroit="";
			#on part de la position 1 pour enlever le blanc qui se trouve avant
			for ($i=1;$i<=$nbre_mots_a_garder_ds_contexte;$i++) {
				$tmpdroit.=$DROITE[$i]." ";
			}


			#On recrée le contexte gauche
			#Il faut renverser le tableau

			#Liste temporaire vide
			my $tmpgauche="";

			@GAUCHE=reverse(@GAUCHE);
			#print "@GAUCHE \n";
			#boucle
			for ($i=0;$i<=$nbre_mots_a_garder_ds_contexte-1;$i++) {
				$tmpgauche=$GAUCHE[$i]." ".$tmpgauche;
			}
			
	
			$listeconcordance->insert('end',[$tmpgauche,$pole,$tmpdroit]);
	
			
		}
	}
	$onglet->raise('page3');
}


#--------------------------------------------------------------------------------
sub extract_pattern {
#--------------------------------------------------------------------------------
$editortexteP6->delete("1.0","end");


$tt=$editortexteP5->get("1.0",'end');   #<< On récupère le texte et on le stocke dans une variable

open (FILEOUT,">tt.txt");
print FILEOUT $tt;
close (FILEOUT);


open(FILE,"tt.txt");
@lineslist=<FILE>;
close(FILE);

#On va parcourir la liste et supprimer chaque élément une fois lu
#Afin que la liste diminue et que donc la boucle s'arrête à la fin
#Tant qu'il y a des éléments dans ma liste...
while (@lineslist) {

	#Je prends le premier élément de la liste et l'enlève
	my $line=shift(@lineslist);
	
	#Je crée une variable vide dans laquelle je vais stocker le nom suivi de l'adj
	my $name="";
	#On donne l'expression régulière
 	if ($line=~/<element><data type="type">NOM<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#Je mémorise ce que j'ai récupéré
		$name=$1;
	
		
		if ($lineslist[0]=~/<element><data type="type">ADJ<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#On concatène et on met un blanc pour séparer le nom de l'adj
		$name.=" ".$1;
		print "$name\n\n";
		$editortexteP6->insert("end","$name\n");
			
		}
	}
	
}
$onglet->raise('page6');

}


#--------------------------------------------------------------------------------
sub extract_pattern_npn {
#--------------------------------------------------------------------------------
$editortexteP6->delete("1.0","end");

$tt=$editortexteP5->get("1.0",'end');   #<< On récupère le texte et on le stocke dans une variable

open (FILEOUT,">tt.txt");
print FILEOUT $tt;
close (FILEOUT);


open(FILE,"tt.txt");


@lineslist=<FILE>;
close(FILE);

#On va parcourir la liste et supprimer chaque élément une fois lu
#Afin que la liste diminue et que donc la boucle s'arrête à la fin
#Tant qu'il y a des éléments dans ma liste...
while (@lineslist) {

	#Je prends le premier élément de la liste et l'enlève
	my $line=shift(@lineslist);
	
	#Je crée une variable vide dans laquelle je vais stocker le nom suivi de l'adj
	my $name="";
	#On donne l'expression régulière
 	if ($line=~/<element><data type="type">NOM<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#Je mémorise ce que j'ai récupéré
		$name=$1;
	
		
		if ($lineslist[0]=~/<element><data type="type">PRP.*<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#On concatène et on met un blanc pour séparer le nom de l'adj
		$name.=" ".$1;
		
		
		#Soit on supprime à nouveau la ligne et on met un indice 0 SOLUTION 1
		my $line=shift(@lineslist);
		if ($lineslist[0]=~/<element><data type="type">NOM<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#Soit on met l'indice 1 pour aller à la ligne du dessous SOLUTION 2:
		#if ($lineslist[0]=~/<element><data type="type">NOM<\/data><data type="lemma">[^<]+<\/data><data type="string">([^<]+)<\/data>/){
		
		#On concatène et on met un blanc pour séparer le nom de l'adj
		$name.=" ".$1;
		
		
		print "$name\n";
		$editortexteP6->insert("end","$name\n");
		}
		
		}
	}
	
}

$onglet->raise('page6');


}
#--------------------------------------------------------------------------------
sub loadtreetagger {
#--------------------------------------------------------------------------------

	#Tokenisation
	$txt=$editortexte->get("1.0",'end');   #<< On récupère le texte et on le stocke dans une variable

	open (FILEOUT,">toto.txt");
	print FILEOUT $txt;
	close (FILEOUT);


	system ("perl tokenise-fr.pl toto.txt > toto2.txt");


#------------------------Lancement treetagger-----------------------------
	
	my $treetagger="toto2.txt";
	my $treetaggerout="resultat.txt";
	my $liblangue="french.par";
	my $progname="tree-tagger.exe";
	my $commandetreetagger="$progname $liblangue -lemma -token -sgml -no-unknown \"$treetagger\" \"$treetaggerout\"";
	
	
	Win32::Process::Create($Win32::Process::Create::ProcessObj,
			"tree-tagger.exe",
			$commandetreetagger,
			0,
			NORMAL_PRIORITY_CLASS,
			"."
			)
	or
	die Win32::FormatMessage(Win32::GetLastError()), "\n";
	$Win32::Process::Create::ProcessObj->Wait(INFINITE);

system("ls resultat.txt");
#------------------------On met au format xml-----------------------------
system ("perl treetagger2xml.pl resultat.txt");
#--------------------------------------------------------------------------------
#Il faut lire les résultats

my $texte="";
open(TMP, "resultat.txt.xml");
while(<TMP>) {
	$texte.=$_;
}
close TMP;
$editortexteP5->delete("1.0","end");
$editortexteP5->insert("end", $texte);
$onglet->raise('page5');

}
#--------------------------------------------------------------------------------