#!/usr/bin/env python3
"""
@author Ashaya Sharma
@date   July 17, 2015 (initial)

Addition 1

Program that randomly generates basic addition problems involving 1 digit numbers
in a GUI and checks that user responses are correct.

MathSitter Beta

"""

from tkinter import *
from tkinter import messagebox
import random
import loaderMain

class Addition1(object):

    '''
    Function opens a text file with scores for each user and reads and then writes the updated scores from this module to the file
    Appends to file if designated user has no entry yet
    @modifies score text file
    '''
    def writeScoretoFile(self):

        #the following lines of code open a file and find the line where the designated user is on
        #if the user is not in the file, a line 0 is indicated
        
        f = open("score.txt", 'r')
        lineCount = 0;
        lineofUser = 0;
        for line in f:
            a = line
            lineCount = lineCount + 1;
            username = "";
            tempString = ""
            startOfScores = 0;
            scoreArray = []
            for x in range (0, len(a)):
                if a[x] == '\t':
                    startOfScores = x
                    break
                else:
                    username = username + a[x]
            if (username == self.username.get()):
                lineofUser = lineCount

        #appends to file if user is not in the file yet
        if(lineofUser == 0):
            f = open("score.txt", 'a')
            #this is for module 1. arrange accordingly
            f.write('\n' + self.username.get()+ '\t'+ str(self.questionsCorrect) +'\t' + str(self.attemptedQuestions) + '\t' + "0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t0\t")  
            f.close()

        #if the user is already in the file, the following few lines create an array of the scores for all the modules and modifies the one
        #corresponding to this module
        else:
            f = open("score.txt", 'r').readlines()
            temp = f[lineofUser-1]
            username2 = "";
            startOfScores = 0;
            scoreArray = []
            
            for x in range (0, len(temp)):
                if temp[x] == '\t':
                    startOfScores = x
                    break
                else:
                    username2 = username2 + temp[x]
            

            for i in range (startOfScores, len(temp)):
                if temp[i].isdigit():
                    tempString = tempString + temp[i]
                else:
                    if len(tempString) > 0:
                        scoreArray.append(int(tempString))
                        tempString = ""
                        

            #scoreArray[moduleNumber] = newValue
            scoreArray[0] = scoreArray[0]+self.questionsCorrect
            scoreArray[1] = scoreArray[1]+self.attemptedQuestions

            newString = username2

            x = 0
            while (x < len(scoreArray)):
                newString = newString +("\t"+str(scoreArray[x])) #writes one module
                x = x + 1

            f[lineofUser-1] = newString
            
            #write the updated scores to the file
            out = open("score.txt", 'w')
            out.writelines(f)
            out.close()



    #Closes the program
    def closeGame(self):
        messagebox.showinfo("Quit", "Program closed")
        self.root.destroy()
        self.writeScoretoFile()
        m1 = loaderMain.Loader(self.username.get())
        m1.root.mainloop()


    """
            This function generates a random addition expression to solve.
            @returns string containing algebraic expression that contains between 1 and 3 variables
            and ranges from 2 terms to 7 terms. Does not support terms that are fractions

            FUTURE: add support for brackets and fractions
    """
    def generateExpression(self):

            expression = ""; 
            #pick random size of string between 5 and 20
            expressionSize = random.randint(2,3);
            
            #put a number at the start
            expression = expression + str(random.randint(2,9));


            #loop through string
            for x in range(1, expressionSize+1):
                    #if previous element in string was number, make next operator
                    if (expression[x-1].isdigit()):
                        expression = expression +"+"

                    #else if previous was operator, next is number
                    elif (expression[x-1] == '+'):
                        expression = expression + str(random.randint(2,9));

            #at end of string check the last element, if it is an operator, add a number to the end so the expression is valid
            if (expression.endswith('+')):
                    expression = expression + str(random.randint(1,9));
            # TESTING PURPOSES print ("FINAL expression: " + expression);
            return expression;
    


    """
    @param question expression to be simplified and user's simplified expression
    @return true if user simplified expression matches question expression and false otherwise
    """

    def checkExpressions(self, expression, userExpression):
        #the user is wrong if they leave the answer blank so return false
        if (len(userExpression) == 0):
            return False
        
        a = int(0)
        for x in range(0, len(expression)):
            if(expression[x].isdigit() == True):
                a = a + int(expression[x])
        try:
            if (a == int(userExpression)):
                return True
        except ValueError:
            return False

        else: return False

    """
    Constructor sets up main GUI
    """
    def __init__(self, username):
        self.root = Tk()
        self.root.title("Basic Arithmetic")
        self.username = StringVar()
        self.username.set(username)
        #set window to fullscreen and focus
        #w, h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
        #self.root.overrideredirect(1)
        #self.root.geometry("%dx%d+0+0" % (w, h))

        self.root.focus_set()

        self.root.configure(bg = "#4C4CFF")

        self.mainFrame = Frame(self.root, width = 250);
        self.topFrame = Frame(self.root, width = 250);

        #place widgets on screen
        self.topFrame.pack();
        self.mainFrame.pack();

        self.score = StringVar();
        self.score.set(0);
        self.scoreCount = StringVar();
        self.scoreCount.set("0/10");
        self.userResponse = StringVar();
        self.userResponse.set("")
        self.computerQuestion = StringVar();

        self.attemptedQuestions = 0;
        self.questionsCorrect = 0;
        
        #load pictures of check mark and x
        self.pictures = (PhotoImage(file = "Images/nop.gif"), PhotoImage(file = "Images/cm2.gif"), PhotoImage(file = "Images/x2.gif"));                                                                                               
        #display an initial problem
        self.computerQuestion.set(self.generateExpression());
        
        self.GameName = Label(self.topFrame, bg = "#4C4CFF", pady = 15, width = 20, text = self.username.get()+": Addition 1", font = ('Helvetica', 11), fg = "#e5e5ff");
        self.GameName.pack(side = LEFT);
        self.butt2 = Button(self.topFrame, text = "Close", font = ('Helvetica', 9), command = self.closeGame);
        
        #paddingLabel1.pack(side = LEFT)
        self.butt2.pack(side = RIGHT);

        #set background colors
        self.mainFrame.configure(bg = "#4C4CFF");
        self.topFrame.configure(bg = "#4C4CFF");

        #Display question (takes text from generateExpression)
        self.question = Label(self.mainFrame, bg = "#4C4CFF", fg = "White", pady = 100, padx = 300, relief = GROOVE, textvariable = self.computerQuestion, font = ('Courier', 24), width = 100);
        self.question.pack();

        #creates an invisible layer which makes buttons centered (necessary on rpi for aesthetic purposes)
        self.paddingLabel2 = Label(self.mainFrame, bg = "#4C4CFF", pady = 30, padx = 30);
        self.paddingLabel2.pack();

        #entry to submit answer
        self.entry1 = Entry(self.mainFrame, takefocus = True, borderwidth= 20, bg = "#4C4CF0", fg = "White", relief = RAISED, font = ('Helvetica', 20), textvariable = self.userResponse);
        self.entry1.pack();

        #make a variable which holds the checkmark or cross set it to the background color to start
        self.checkMark = Label(self.mainFrame, image = self.pictures[0], bg ="#4C4CFF");

        #creates an invisible layer which makes buttons centered (necessary on rpi for aesthetic purposes)
        self.paddingLabel3 = Label(self.mainFrame, width = 75, bg="#4C4CFF");
        self.button1 = Button(self.mainFrame, text = "Submit", height = 5, width = 20, font = ('Helvetica', 10));

        #let user press the submit button or enter to submit their answer
        self.button1.bind("<Button-1>", self.incrementScore)
        self.root.bind("<Return>", self.incrementScore)

        #display the user's current score
        self.currentScore = Label(self.mainFrame, bg = "#4C4CFF", textvariable = self.scoreCount, font = ('Helvetica', 20), fg = "White", padx = 20);

        #place widgets on screen
        self.paddingLabel3.pack(side = LEFT);
        self.checkMark.pack(side = LEFT);
        self.button1.pack(side = LEFT);
        self.currentScore.pack(side = LEFT);

        #self.showIntro();



    """
    Updates score depending on correctness of user input and updates GUI
    Requests new expression if user is correct
    @modifies score, checkMark image, question

    """

    def incrementScore(self, event):
            self.attemptedQuestions = self.attemptedQuestions + 1
            userAnswer = self.userResponse.get()
            #trims whitespace
            userAnswer.replace(" ", "") 
            answerKey = self.computerQuestion.get()

            #check if the simplified expressions of both match and the user enters a valid expression and increment their score if they are right
            #generate a new expression for them to solve if they keep on going
            if (self.checkExpressions(answerKey, userAnswer) == True):
                    tempscore = int(self.score.get()) 
                    tempscore = tempscore +1
                    self.questionsCorrect = self.questionsCorrect + 1

                    #check if score is 10 and popup congratulations message
                    if (tempscore == 10):
                            messagebox.showinfo("Congratulations!", "Well Done! You mastered the module. You can keep practicing or quit");
                    
                    self.score.set(tempscore)
                    scoreString = str(tempscore)+ "/10"
                    self.scoreCount.set(scoreString)
                    self.computerQuestion.set(self.generateExpression());
                    self.checkMark.config(image = self.pictures[1])
                    #clear the answer textbox
                    self.userResponse.set("")

            #if they are incorrect but have a score greater than 5, send their score down to 5 otherwise send them back to 0
            else:
               tempscore = int(self.score.get())
               newscore = 0
               if (tempscore > 5):
                       self.score.set(5)
                       newscore = 5
               else:
                       self.score.set(0)
                       newscore = 0
               scoreString=str(newscore)+"/10"
               self.scoreCount.set(scoreString)
               self.checkMark.config(image = self.pictures[2])
               self.computerQuestion.set(answerKey)

