import tkinter as tk
from tkinter import messagebox, simpledialog
from PIL import Image, ImageDraw
import os


# ============================================================
# CORES
# ============================================================

CORES = {
    0: ("Vazio", "#FFFFFF"),
    1: ("Azul", "#0000FF"),
    2: ("Verde", "#00AA00"),
    3: ("Amarelo", "#FFFF00"),
    4: ("Vermelho", "#FF0000"),
    5: ("Rosa", "#FF69B4"),
    6: ("Roxo", "#8000FF"),
    7: ("Laranja", "#FF8C00"),
    8: ("Preto", "#000000"),
    9: ("Branco", "#FFFFFF"),
    10: ("Ciano", "#00FFFF")
}


# ============================================================
# JANELA DE TAMANHO
# ============================================================

def escolher_tamanho():

    janela = tk.Tk()

    janela.title("LeviOS - Desenho")
    janela.geometry("650x500")
    janela.resizable(False, False)

    tk.Label(
        janela,
        text="MODO DESENHO",
        font=("Arial", 24, "bold")
    ).pack(pady=20)

    tk.Label(
        janela,
        text="Escolha a largura e a altura:",
        font=("Arial", 12)
    ).pack()

    largura = tk.IntVar(value=5)
    altura = tk.IntVar(value=5)

    # --------------------------------------------------------
    # LARGURA
    # --------------------------------------------------------

    frame_largura = tk.Frame(janela)
    frame_largura.pack(pady=10)

    tk.Label(
        frame_largura,
        text="LARGURA:",
        font=("Arial", 12, "bold")
    ).pack()

    botoes_largura = tk.Frame(frame_largura)
    botoes_largura.pack()

    for numero in range(1, 21):

        tk.Button(
            botoes_largura,
            text=str(numero),
            width=3,
            command=lambda n=numero: largura.set(n)
        ).grid(
            row=(numero - 1) // 10,
            column=(numero - 1) % 10,
            padx=2,
            pady=2
        )

    # --------------------------------------------------------
    # ALTURA
    # --------------------------------------------------------

    frame_altura = tk.Frame(janela)
    frame_altura.pack(pady=10)

    tk.Label(
        frame_altura,
        text="ALTURA:",
        font=("Arial", 12, "bold")
    ).pack()

    botoes_altura = tk.Frame(frame_altura)
    botoes_altura.pack()

    for numero in range(1, 21):

        tk.Button(
            botoes_altura,
            text=str(numero),
            width=3,
            command=lambda n=numero: altura.set(n)
        ).grid(
            row=(numero - 1) // 10,
            column=(numero - 1) % 10,
            padx=2,
            pady=2
        )

    # --------------------------------------------------------
    # TAMANHO
    # --------------------------------------------------------

    texto_tamanho = tk.Label(
        janela,
        text="Tamanho: 5 x 5",
        font=("Arial", 14, "bold")
    )

    texto_tamanho.pack(pady=10)

    def atualizar(*args):

        texto_tamanho.config(
            text=f"Tamanho: {largura.get()} x {altura.get()}"
        )

    largura.trace_add("write", atualizar)
    altura.trace_add("write", atualizar)

    # --------------------------------------------------------
    # CRIAR
    # --------------------------------------------------------

    def criar():

        abrir_desenho(
            janela,
            largura.get(),
            altura.get()
        )

    tk.Button(
        janela,
        text="CRIAR MALHA",
        width=20,
        height=2,
        font=("Arial", 12, "bold"),
        command=criar
    ).pack(pady=10)

    janela.mainloop()


# ============================================================
# JANELA DO DESENHO
# ============================================================

def abrir_desenho(janela_anterior, largura, altura):

    janela_anterior.withdraw()

    janela = tk.Toplevel(janela_anterior)

    janela.title(
        f"LeviOS - Desenho {largura}x{altura}"
    )

    janela.resizable(False, False)

    # --------------------------------------------------------
    # TAMANHO DAS CÉLULAS
    # --------------------------------------------------------

    maior = max(largura, altura)

    if maior <= 10:
        tamanho = 45
    elif maior <= 15:
        tamanho = 38
    else:
        tamanho = 30

    largura_malha = largura * tamanho
    altura_malha = altura * tamanho

    # --------------------------------------------------------
    # MATRIZ
    # --------------------------------------------------------

    desenho = []

    botoes = []

    for linha in range(altura):

        linha_desenho = []
        linha_botoes = []

        for coluna in range(largura):

            linha_desenho.append(0)

            botao = tk.Button(
                janela,
                bg="#FFFFFF",
                activebackground="#DDDDDD",
                relief="solid",
                borderwidth=1
            )

            botao.place(
                x=coluna * tamanho,
                y=linha * tamanho,
                width=tamanho,
                height=tamanho
            )

            linha_botoes.append(botao)

        desenho.append(linha_desenho)
        botoes.append(linha_botoes)

    # --------------------------------------------------------
    # PAINEL
    # --------------------------------------------------------

    painel = tk.Frame(janela)

    painel.place(
        x=largura_malha + 15,
        y=10,
        width=220,
        height=max(altura_malha, 450)
    )

    tk.Label(
        painel,
        text=f"Malha {largura} x {altura}",
        font=("Arial", 14, "bold")
    ).pack(pady=5)

    # --------------------------------------------------------
    # COR ATUAL
    # --------------------------------------------------------

    cor_atual = tk.IntVar(value=1)

    tk.Label(
        painel,
        text="ESCOLHA A COR:",
        font=("Arial", 11, "bold")
    ).pack(pady=5)

    frame_cores = tk.Frame(painel)
    frame_cores.pack()

    for numero in range(1, 11):

        nome, codigo = CORES[numero]

        botao = tk.Button(
            frame_cores,
            text=str(numero),
            width=5,
            height=2,
            bg=codigo,
            command=lambda n=numero:
                cor_atual.set(n)
        )

        if numero in (3, 5, 9, 10):
            botao.config(fg="black")
        else:
            botao.config(fg="white")

        botao.grid(
            row=(numero - 1) // 2,
            column=(numero - 1) % 2,
            padx=3,
            pady=3
        )

    # --------------------------------------------------------
    # PINTAR
    # --------------------------------------------------------

    def pintar(linha, coluna):

        cor = cor_atual.get()

        desenho[linha][coluna] = cor

        nome, codigo = CORES[cor]

        botoes[linha][coluna].config(
            bg=codigo,
            activebackground=codigo
        )

    # --------------------------------------------------------
    # CLIQUES
    # --------------------------------------------------------

    for linha in range(altura):

        for coluna in range(largura):

            botoes[linha][coluna].config(
                command=lambda l=linha, c=coluna:
                    pintar(l, c)
            )

    # ========================================================
    # SALVAR JPG
    # ========================================================

    def salvar():

        pasta = os.path.expanduser(
            "~/Desenhos_LeviOS"
        )

        os.makedirs(
            pasta,
            exist_ok=True
        )

        nome = simpledialog.askstring(
            "Salvar desenho",
            "Digite o nome do desenho:"
        )

        if not nome:
            return

        # Remover extensão caso o usuário coloque
        if nome.lower().endswith(".jpg"):
            nome = nome[:-4]

        if not nome:
            messagebox.showerror(
                "Erro",
                "Nome inválido."
            )
            return

        caminho = os.path.join(
            pasta,
            nome + ".jpg"
        )

        # ----------------------------------------------------
        # TAMANHO DA IMAGEM
        # ----------------------------------------------------

        imagem = Image.new(
            "RGB",
            (
                largura * 100,
                altura * 100
            ),
            "white"
        )

        desenho_jpg = ImageDraw.Draw(imagem)

        # ----------------------------------------------------
        # DESENHAR CÉLULAS
        # ----------------------------------------------------

        for linha in range(altura):

            for coluna in range(largura):

                numero_cor = desenho[linha][coluna]

                _, codigo = CORES[numero_cor]

                x1 = coluna * 100
                y1 = linha * 100

                x2 = x1 + 100
                y2 = y1 + 100

                desenho_jpg.rectangle(
                    [x1, y1, x2, y2],
                    fill=codigo,
                    outline="#555555",
                    width=2
                )

        # ----------------------------------------------------
        # SALVAR
        # ----------------------------------------------------

        imagem.save(
            caminho,
            "JPEG",
            quality=95
        )

        messagebox.showinfo(
            "Desenho salvo!",
            f"O desenho foi salvo em:\n\n{caminho}"
        )

    # --------------------------------------------------------
    # COMANDO
    # --------------------------------------------------------

    tk.Label(
        painel,
        text="Comando:",
        font=("Arial", 11, "bold")
    ).pack(pady=(15, 3))

    frame_comando = tk.Frame(painel)
    frame_comando.pack()

    tk.Label(
        frame_comando,
        text=">>>",
        font=("Courier New", 12, "bold")
    ).pack(side="left")

    entrada = tk.Entry(
        frame_comando,
        width=13,
        font=("Courier New", 11)
    )

    entrada.pack(
        side="left",
        padx=5
    )

    # --------------------------------------------------------
    # EXECUTAR COMANDO
    # --------------------------------------------------------

    def executar_comando(event=None):

        comando = entrada.get().strip()

        # ----------------------------
        # SALVAR
        # ----------------------------

        if comando.upper() == "<O>":

            salvar()

            entrada.delete(0, tk.END)

            return

        # ----------------------------
        # SAIR
        # ----------------------------

        if comando.upper() == "<X>":

            fechar()

            return

        # ----------------------------
        # PINTAR
        # ----------------------------

        try:

            parte, valor = comando.split("=")

            coluna, linha = parte.lower().split("x")

            coluna = int(coluna)
            linha = int(linha)
            valor = int(valor)

            if coluna < 1 or coluna > largura:
                raise ValueError

            if linha < 1 or linha > altura:
                raise ValueError

            if valor < 0 or valor > 10:
                raise ValueError

            desenho[linha - 1][coluna - 1] = valor

            _, codigo = CORES[valor]

            botoes[linha - 1][coluna - 1].config(
                bg=codigo,
                activebackground=codigo
            )

            entrada.delete(0, tk.END)

        except ValueError:

            messagebox.showerror(
                "Comando inválido",
                "Use:\n\n"
                "3x4=8\n\n"
                "Coluna x Linha = Cor"
            )

    entrada.bind(
        "<Return>",
        executar_comando
    )

    tk.Button(
        painel,
        text="Aplicar",
        command=executar_comando,
        width=15
    ).pack(pady=5)

    # --------------------------------------------------------
    # BOTÃO SALVAR
    # --------------------------------------------------------

    tk.Button(
        painel,
        text="Salvar JPG",
        command=salvar,
        width=15,
        height=2,
        font=("Arial", 10, "bold")
    ).pack(pady=8)

    # --------------------------------------------------------
    # LIMPAR
    # --------------------------------------------------------

    def limpar():

        for linha in range(altura):

            for coluna in range(largura):

                desenho[linha][coluna] = 0

                botoes[linha][coluna].config(
                    bg="#FFFFFF",
                    activebackground="#DDDDDD"
                )

    tk.Button(
        painel,
        text="Limpar tudo",
        command=limpar,
        width=15
    ).pack(pady=5)

    # --------------------------------------------------------
    # FECHAR
    # --------------------------------------------------------

    def fechar():

        janela.destroy()

        janela_anterior.deiconify()

    tk.Button(
        painel,
        text="Fechar",
        command=fechar,
        width=15
    ).pack(pady=10)

    # --------------------------------------------------------
    # TAMANHO DA JANELA
    # --------------------------------------------------------

    janela.geometry(
        f"{largura_malha + 250}x"
        f"{max(altura_malha + 20, 470)}"
    )

    janela.protocol(
        "WM_DELETE_WINDOW",
        fechar
    )

    entrada.focus()


# ============================================================
# INICIAR
# ============================================================

if __name__ == "__main__":

    escolher_tamanho()
