#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script pour analyser la fréquence des mots dans un fichier livre.org
et générer un nuage de mots coloré en tons pastels.

Ce script:
1. Lit le fichier livre.org
2. Extrait le texte en ignorant les métadonnées et les commentaires
3. Compte la fréquence des mots
4. Sauvegarde les 500 mots les plus fréquents dans un fichier CSV
5. Génère un nuage de mots en SVG et PNG avec des couleurs pastel aléatoires
"""

import re
import os
import csv
import random
import argparse
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
from wordcloud import WordCloud
import matplotlib.colors as mcolors

# Définir les arguments en ligne de commande
parser = argparse.ArgumentParser(description='Analyser la fréquence des mots dans un fichier Org-mode.')
parser.add_argument('dossier', nargs='?', help='Le chemin du dossier contenant le fichier livre.org. Si aucun dossier n\'est spécifié, le dossier courant sera utilisé.', default=os.getcwd())
args = parser.parse_args()

# Chemin vers le fichier livre.org
fichier_livre = f"{args.dossier}/livre.org"

# Liste des mots vides (stopwords) en français
stopwords = set([
    "le", "la", "les", "un", "une", "des", "du", "de", "d'", "l'", "et", "ou", "où", 
    "à", "au", "aux", "ce", "ces", "cette", "cet", "il", "ils", "elle", "elles", 
    "nous", "vous", "je", "tu", "on", "son", "sa", "ses", "leur", "leurs", "mon", 
    "ma", "mes", "ton", "ta", "tes", "que", "qui", "quoi", "dont", "pour", "par", 
    "dans", "sur", "sous", "avec", "sans", "en", "y", "est", "sont", "était", 
    "étaient", "sera", "seront", "a", "ont", "avait", "avaient", "aura", "auront", 
    "plus", "moins", "très", "peu", "beaucoup", "trop", "pas", "ne", "n'", "si", 
    "comme", "mais", "ou", "et", "donc", "car", "quand", "lorsque", "puis", "ensuite", 
    "alors", "ainsi", "aussi", "même", "tout", "tous", "toute", "toutes", "autre", 
    "autres", "certain", "certains", "certaine", "certaines", "tel", "tels", "telle", 
    "telles", "ceci", "cela", "ça", "c'", "s'", "d'", "l'", "qu'", "n'", "m'", "t'",
    "se", "me", "te", "lui", "leur", "y", "en", "là", "ici", "voici", "voilà", "ci",
    "là", "cet", "cette", "ces", "celui", "celle", "ceux", "celles", "celui-ci",
    "celle-ci", "ceux-ci", "celles-ci", "celui-là", "celle-là", "ceux-là", "celles-là"
])

def generate_pastel_color():
    """Génère une couleur pastel aléatoire en format RGB."""
    # NOTE: PIL's ImageDraw requires integer RGB values (0-255), not floats.
    # La version précédente retournait des valeurs flottantes entre 0.6 et 0.9,
    # ce qui causait une erreur: 'float' object cannot be interpreted as an integer
    
    # Générer des valeurs RGB entre 153 et 229 (0.6*255 et 0.9*255) pour obtenir des tons pastels
    # tout en convertissant en entiers pour la compatibilité avec PIL
    r = int(random.uniform(0.6, 0.9) * 255)
    g = int(random.uniform(0.6, 0.9) * 255)
    b = int(random.uniform(0.6, 0.9) * 255)
    return (r, g, b)

def extract_text_from_org(file_path):
    """
    Extrait le texte d'un fichier org-mode en ignorant les métadonnées et les commentaires.
    """
    with open(file_path, 'r', encoding='utf-8') as file:
        content = file.read()
    
    # Supprimer les blocs de commentaires
    content = re.sub(r'#\+begin_comment.*?#\+end_comment', '', content, flags=re.DOTALL | re.IGNORECASE)
    
    # Supprimer les lignes de métadonnées (commençant par #+)
    content = re.sub(r'^\s*#\+.*$', '', content, flags=re.MULTILINE)
    
    # Supprimer les lignes de propriétés
    content = re.sub(r'^\s*:.*:.*$', '', content, flags=re.MULTILINE)
    
    # Supprimer les titres de chapitres (lignes commençant par * ou **)
    content = re.sub(r'^\s*\*+.*$', '', content, flags=re.MULTILINE)
    
    # Supprimer les liens org-mode [[...][...]] et [[...]]
    content = re.sub(r'\[\[.*?\]\](?:\[.*?\])?', '', content)
    
    # Supprimer les caractères spéciaux et la ponctuation
    content = re.sub(r'[^\w\s]', ' ', content)
    
    # Convertir en minuscules
    content = content.lower()
    
    return content

def count_word_frequencies(text):
    """
    Compte la fréquence des mots dans un texte.
    Ignore les mots vides (stopwords) et les mots de moins de 3 caractères.
    """
    # Diviser le texte en mots
    words = re.findall(r'\b\w+\b', text)
    
    # Filtrer les mots courts et les stopwords
    filtered_words = [word for word in words if len(word) >= 3 and word not in stopwords]
    
    # Compter les fréquences
    word_counts = Counter(filtered_words)
    
    return word_counts

def save_to_csv(word_counts, output_path, limit=500):
    """
    Sauvegarde les mots les plus fréquents dans un fichier CSV.
    """
    # Obtenir les mots les plus fréquents
    most_common = word_counts.most_common(limit)
    
    # Écrire dans le fichier CSV
    with open(output_path, 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['Mot', 'Fréquence'])
        for word, count in most_common:
            writer.writerow([word, count])
    
    print(f"Les {limit} mots les plus fréquents ont été sauvegardés dans {output_path}")

def generate_wordcloud(word_counts, output_svg, output_png):
    """
    Génère un nuage de mots en SVG et PNG avec des couleurs pastel aléatoires.
    """
    # Fonction pour attribuer des couleurs pastel aléatoires aux mots
    def color_func(word, font_size, position, orientation, random_state=None, **kwargs):
        return generate_pastel_color()
    
    # Créer le nuage de mots
    wordcloud = WordCloud(
        width=1200, 
        height=800, 
        background_color='white',
        max_words=500,
        color_func=color_func,
        prefer_horizontal=0.9,
        relative_scaling=0.5
    ).generate_from_frequencies(word_counts)
    
    # Sauvegarder en SVG
    plt.figure(figsize=(12, 8), dpi=300)
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis('off')
    plt.tight_layout(pad=0)
    plt.savefig(output_svg, format='svg', bbox_inches='tight')
    
    # Sauvegarder en PNG
    plt.savefig(output_png, format='png', bbox_inches='tight')
    
    plt.close()
    
    print(f"Nuage de mots sauvegardé en SVG: {output_svg}")
    print(f"Nuage de mots sauvegardé en PNG: {output_png}")

def main():
    # Extraire le texte du fichier livre.org
    print(f"Analyse du fichier: {fichier_livre}")
    text = extract_text_from_org(fichier_livre)
    
    # Compter les fréquences des mots
    word_counts = count_word_frequencies(text)
    
    # Définir les chemins de sortie
    csv_output = f"{args.dossier}/frequence_mots_top500.csv"
    svg_output = f"{args.dossier}/nuage_mots.svg"
    png_output = f"{args.dossier}/nuage_mots.png"
    
    # Sauvegarder les résultats
    save_to_csv(word_counts, csv_output)
    generate_wordcloud(word_counts, svg_output, png_output)
    
    print("Analyse de fréquence des mots terminée avec succès!")

if __name__ == "__main__":
    main()