from PIL import Image, ImageDraw, ImageFont
from random import randint

def get_text_dimensions(text_string, font):
    # https://stackoverflow.com/a/46220683/9263761
    ascent, descent = font.getmetrics()

    text_width = font.getmask(text_string).getbbox()[2]
    text_height = font.getmask(text_string).getbbox()[3] + descent

    return (text_width, text_height)

def create_dic(texte, exclusion):
    D = {}
    P = [ "'" , "." , ";" , "," , ":" , "!" , "?" , "(" , ")" , "&" , "%"]
    for i in P:
        texte = texte.replace(i," ")
        
    T = [ i.lower() for i in texte.split() if len(i) >= 2 and i not in exclusion ]
        
    for i in T:
        if i not in D:
            D[i] = T.count(i)
    
    return D
                

def nuage( fichier , size , MAX_COUNTER = 50):
    Fichier = open(fichier, 'r' , encoding='utf-8')
    texte = Fichier.read()
    Fichier.close()
    
    counter = 0
    
    exclusion = [ 'data', 'science' , 'données', 'du', 'de', 'la', 'des', 'le', 'et', 'est', 'elle', 'une', 'en', 'que', 'aux', 'qui', 'ces', 'les', 'dans', 'sur', 'un', 'pour', 'par', 'il', 'ou', 'ce', 'sont', 'cas', 'plus', 'leur', 'se', 'vous', 'au', 'aussi', 'toutes', 'autre', 'comme']
    
    mots = create_dic(texte , exclusion)

    max_size = min(size[0],size[1])//3 # taille maximale d'un mot
    w,h = size[0], size[1]

    cloud = Image.new("RGB", (w, h), 'white')
    d = ImageDraw.Draw(cloud)

    m = max( [ value for key, value in mots.items() ] )

    for key, value in sorted( mots.items() , key = lambda x:x[1] , reverse=True):
        if key not in exclusion and counter <= MAX_COUNTER:
            fontsize = int(max_size*value/m)
            font = ImageFont.truetype("arial.ttf", fontsize)
            x_max = w - get_text_dimensions(key,font)[0] - 20
            y_max = h - get_text_dimensions(key,font)[1] - 20
        
            x, y = randint(20,x_max) , randint(20,y_max)
        
            d.text((x, y), key ,font=font, fill=(randint(1,255), randint(1,255), randint(1,255)))
            counter += 1

    cloud.show()

if __name__ == "__main__":
        nuage( 'texte.txt' , (500,500) )
        
""" Méthode avec wordcloud *********
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from random import randint

def couleur(*args, **kwargs):
    return "rgb(110, {}, 100)".format(randint(100, 255))

Fichier = open('texte.txt', 'r' , encoding='utf-8')
texte = Fichier.read()
Fichier.close()

mask = np.array(Image.open("coeur.png"))
mask[mask == 1] = 255

mots_exclus = ['d', 'du', 'de', 'la', 'des', 'le', 'et', 'est', 'elle', 'une', 'en', 'que', 'aux', 'qui', 'ces', 'les', 'dans', 'sur', 'l', 'un', 'pour', 'par', 'il', 'ou', 'à', 'ce', 'a', 'sont', 'cas', 'plus', 'leur', 'se', 's', 'vous', 'au', 'c', 'aussi', 'toutes', 'autre', 'comme']
wordcloud = WordCloud(background_color = 'white', stopwords = mots_exclus, max_words = 50, mask = mask).generate(texte)

plt.imshow(wordcloud.recolor(color_func = couleur))
plt.axis("off")
plt.show()
"""