# Arup Guha
# 6/19/2024
# Stores the wordle class.
import random
import wordlefunctions
import pygame, sys
from pygame.locals import *

pygame.init()
    
class wordle:

    # Size of wordle and status.
    N = 5
    PLAYING = 0
    WIN = 1
    LOSE = 2

    # Conceptually this isn't part of the object, but it's
    # easier to have here.
    font = pygame.font.SysFont("Arial", 36)    

    def __init__(self,wordfile):

        # Open the file. Get # of words.
        wordfile = open(wordfile,"r")
        numW = int(wordfile.readline())

        # Randonly pick how many to skip.
        item = random.randint(0,numW-1)
        
        # Store the words here.
        self.mywords = set()
        
        # Read all the words.
        for i in range(numW):
            tmp = wordfile.readline().strip()
            self.mywords.add(tmp)

            # This is the word we want to make the solution.
            if i == item:
                self.solution = tmp

        # Close it!
        wordfile.close()
        
        # Reset for next word.
        self.curS = ""
        self.curI = 0;
        self.feedback = []
        self.guesses = []

    # Draws the letters on DISPLAYSURF
    def drawLetters(self,DISPLAYSURF):

        # Draw completed words.
        for i in range(self.curI):

            # Go through each letter.
            for j in range(self.N):

                # Draws the rectangle with the right color.
                boxpt = wordlefunctions.mapTopLeft(i,j)
                pygame.draw.rect(DISPLAYSURF, self.feedback[i][j], (boxpt[0], boxpt[1], wordlefunctions.SQ_SIZE, wordlefunctions.SQ_SIZE))

                # Draws the letter in black.
                letpt = wordlefunctions.mapCharTopLeft(i,j)
                wordlefunctions.draw(self.guesses[i][j], self.font, "black", DISPLAYSURF, letpt[0], letpt[1])

        # This draws the word the user is "thinking about"
        for j in range(len(self.curS)):
            letpt = wordlefunctions.mapCharTopLeft(self.curI,j)
            wordlefunctions.draw(self.curS[j], self.font, "black", DISPLAYSURF, letpt[0], letpt[1])
                
    # Update the current guess with this letter.
    def updatecurstr(self,ch):

        # Only do this if there's room.
        if len(self.curS) < 5:
            self.curS += ch

    # Backspace
    def backspace(self):

        # Only do if there's a character to delete.
        if len(self.curS) > 0:
            self.curS = self.curS[0:len(self.curS)-1]
        
    # Updates the guess in the object.
    def updateguess(self):

        # Not allowed to guess something that isn't a word.
        if not (self.curS in self.mywords):
            return False

        # Update word in this spot.
        self.guesses.append(self.curS)

        # Calculate and add new feedback.
        self.feedback.append(self.getfeedback(self.curS))
        self.curI += 1
        self.curS = ""

        # Successful operation.
        return True

    # Returns the current status of the game.
    def getstatus(self):

        # Your last guess was correct, you win!
        if self.curI > 0 and self.guesses[self.curI-1] == self.solution:
            return self.WIN

        # You've completed 6 guesses. You lost.
        if self.curI == 6:
            return self.LOSE

        # We're somewhere in the middle of the game.
        return self.PLAYING

    # Return the feedback array for this guess.
    def getfeedback(self,guess):

        # Initially no matches.
        res = ["gray", "gray", "gray", "gray", "gray"]

        # Which items in solution have been used already.
        used = [False, False, False, False, False]

        # First Mark Green.
        for i in range(self.N):
            if guess[i] == self.solution[i]:
                res[i] = "green"
                used[i] = True

        # Next Mark Yellow. i is letter in guess.
        for i in range(self.N):

            # These are to be ignored.
            if res[i] == "green":
                continue

            # j is letter in solution.
            for j in range(self.N):

                # Been previously matched, or not a match.
                if used[j] or guess[i] != self.solution[j]:
                    continue

                # Mark both the letter in guess and solution.
                res[i] = "yellow"
                used[j] = True
                break

        # Ta da!
        return res
