from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

import sys

from si_hangman import get_word, make_guess, find_all_elements


def paint_gallows(qp):
    qp.drawLine(75, 60, 75, 20)
    qp.drawLine(150, 20, 75, 20)
    qp.drawLine(150, 20, 150, 200)


class HangManGUI(QWidget):
    alphabet = ['a', 'b', 'c', 'd', 'e',
                'f', 'g', 'h', 'i', 'j', 'k',
                'l', 'm', 'n', 'o', 'p', 'q', 'r',
                's', 't', 'u', 'v', 'w', 'x',
                'y', 'z']

    keyPressed = pyqtSignal(str)
    POSX = 300
    POSY = 300
    WIDTH = 650
    HEIGHT = 450

    MAX_LIVES = 6

    DRAW_CALLS = (
        lambda qp: qp.drawEllipse(60, 60, 30, 30),
        lambda qp: qp.drawLine(75, 90, 75, 135),
        lambda qp: qp.drawLine(75, 105, 50, 100),
        lambda qp: qp.drawLine(75, 105, 100, 100),
        lambda qp: qp.drawLine(75, 135, 50, 160),
        lambda qp: qp.drawLine(75, 135, 100, 160)
    )

    def __init__(self):
        self.buttonList = []
        super(HangManGUI, self).__init__()

        self.word = get_word()
        self.lives = self.MAX_LIVES
        self.guessed_letters = [""] * len(self.word)
        self.still_playing = True
        self.victory = False

        self.setStyleSheet("background-color:white;")

        self.init_ui()

    def init_ui(self):
        self.keyPressed.connect(self.on_key)

        self.setGeometry(self.POSX, self.POSY, self.WIDTH, self.HEIGHT)
        self.setWindowTitle('Sports Interactive HangMan')
        self.show()

    def paint_body(self, qp: QPainter):
        for i in range(self.MAX_LIVES-self.lives):
            self.DRAW_CALLS[i](qp)

    def paint_hangman(self, qp: QPainter):
        pen = QPen(Qt.black, 3, Qt.SolidLine)
        qp.setPen(pen)

        paint_gallows(qp)
        self.paint_body(qp)

        for i in range(len(self.guessed_letters)):
            add = 50 * i
            qp.drawText(40 + add, 240, self.guessed_letters[i])
            qp.drawLine(20 + add, 250, 60 + add, 250)

    def paint_victory(self, qp: QPainter):
        pen = QPen(Qt.red, 50, Qt.SolidLine)
        font = QFont()
        font.setStyleHint(QFont().Monospace)
        font.setFamily('monospace')
        font.setPixelSize(48)
        qp.setPen(pen)
        qp.setFont(font)
        if self.victory:
            qp.drawText(250, 200, "You Win")
        else:
            qp.drawText(250, 200, "You Lose")

    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)

        self.paint_hangman(qp)
        if not self.still_playing:
            self.paint_victory(qp)

        qp.end()

    def update_game(self):
        if "".join(self.guessed_letters) == self.word:
            self.finish_game(True)
        elif not self.lives:
            self.finish_game(False)

    def onButtonClick(self, button):
        button.setEnabled(False)

    def keyPressEvent(self, key_event: QKeyEvent) -> None:
        super(HangManGUI, self).keyPressEvent(key_event)
        self.keyPressed.emit(key_event.text())
        if key_event.key() == Qt.Key_Escape:
            sys.exit(None)

    def on_key(self, key):
        if self.still_playing:
            if key.isalpha():
                if make_guess(self.word, key):
                    for pos in find_all_elements(self.word, key):
                        self.guessed_letters[pos] = key
                else:
                    self.lives -= 1

                self.update_game()
                self.update()

    def finish_game(self, win: bool):
        self.still_playing = False
        self.victory = win
        pass


def main():
    app = QApplication(sys.argv)
    gui = HangManGUI()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
