import pygame, random, math
import entities, structures, map

pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode([1280, 720])
window.fill([126, 250, 30])
pygame.display.set_caption("Don't Take my Stuff!")
pygame.key.set_repeat(10)
pygame.time.set_timer(pygame.USEREVENT, 30000) #Cleanup Timer
pygame.time.set_timer(pygame.USEREVENT + 1, 1000 / 60) #60 Frames Per Second
pygame.time.set_timer(pygame.USEREVENT + 2, 1000 / 3) #3 Animations Per Second
pygame.time.set_timer(pygame.USEREVENT + 3, 1000) #1 Second Countdown
mouse = 0, 0
all = pygame.sprite.Group()
font = pygame.font.Font("./font/Lintsec.ttf", 19)
fontbig = pygame.font.Font("./font/Lintsec.ttf", 70)
fontbig2 = pygame.font.Font("./font/Lintsec.ttf", 60)
screen = "menu"
click = pygame.mixer.Sound("./sfx/select.wav")
gameover = pygame.mixer.Sound("./sfx/gameover.wav")
switch = pygame.mixer.Sound("./sfx/switch tools.wav")
parting = pygame.sprite.Group()
maxSpace = 0
message = None

trashbag = pygame.image.load("./images/trashbag.png")
cart = pygame.image.load("./images/cart.png")
shop = pygame.transform.scale(pygame.image.load("./images/shop.png"), [60, 60])

time = 60
money = 50
energy = 100
mood = 100

currentTool = None

trashBags = 5
cartSpace = maxSpace
cartPrice = 100

trashPickedUp = 0

junk = pygame.sprite.Group()
walls = pygame.sprite.Group()
floors = pygame.sprite.Group()
dumpsters = pygame.sprite.Group()

running = True

player = entities.Player()

class Button(pygame.sprite.Sprite):
    def __init__(self, text, pos):
        pygame.sprite.Sprite.__init__(self)
        font = pygame.font.Font("./font/Lintsec.ttf", 19)
        self.image = font.render(str(text), 1, [255, 255, 255])
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = list(pos)
        self.clicked  = False
    def draw(self):
        global window
        window.blit(self.image, [self.rect.left, self.rect.top])

    def click(self):
        global mouse, click
        if self.rect.collidepoint(mouse):
            self.clicked = True
            click.play()
        else:
            self.clicked = False

        return self.clicked

class Parameters(pygame.sprite.Sprite):
    def __init__(self):
        global trashBags, cartSpace, trashPickedUp, currentTool, money, maxSpace, mood, message, parting, energy
        pygame.sprite.Sprite.__init__(self)
        self.bags = trashBags
        self.space = cartSpace
        self.trash = trashPickedUp
        self.current = currentTool
        self.money = money
        self.maxSpace = maxSpace
        self.mood = mood
        self.message = message
        self.parting = parting
        self.energy = energy
    def update(self):
        global trashBags, cartSpace, trashPickedUp, currentTool, money, maxSpace, mood, message, parting, energy
        self.bags = trashBags
        self.space = cartSpace
        self.trash = trashPickedUp
        self.current = currentTool
        self.money = money
        self.maxSpace = maxSpace
        self.mood = mood
        self.message = message
        self.parting = parting
        self.energy = energy

parameters = Parameters()

def clickArea(mouse, x1, x2, y1, y2):
    if mouse[0] > x1 and mouse[0] < x2:
        if mouse[1] > y1 and mouse[1] < y2:
            return True
        else:
            return False
    else:
        return False

def returnParameters():
    global parameters, trashBags, cartSpace, trashPickedUp, money, maxSpace, mood, parting, message, energy
    trashBags = parameters.bags
    cartSpace = parameters.space
    trashPickedUp = parameters.trash
    money = parameters.money
    maxSpace = parameters.maxSpace
    mood = parameters.mood
    parting = parameters.parting
    message = parameters.message
    energy = parameters.energy

def createJunk(amt):
    global all
    group = pygame.sprite.Group()
    for i in range(amt):
        junk = entities.junk([random.randint(0, 14) * 80, random.randint(0, 7) * 80])
        group.add(junk)
        all.add(junk)
    return group

def createWalls(amt):
    global all
    group = pygame.sprite.Group()
    for i in range(amt):
        wall = structures.wall([random.randint(0, 14) * 80, random.randint(0, 7) * 80], "wall")
        group.add(wall)
        all.add(wall)
    return group

def createFlooring(amt):
    global all
    group = pygame.sprite.Group()
    for i in range(amt):
        floor = structures.floor([random.randint(0, 14) * 80, random.randint(0, 7) * 80])
        group.add(floor)
        all.add(floor)
    return group

def createDumpsters(amt):
    global all
    group = pygame.sprite.Group()
    for i in range(amt):
        dumpster = structures.dumpster([random.randint(0, 7) * 160, random.randint(0, 7) * 80])
        group.add(dumpster)
        all.add(dumpster)
    return group

def update(group, action):
    global junk, walls, floors, dumpsters, all, window, mouse, parameters, parting
    if group == all:
        all.update(str(action), window, mouse, parameters)
    elif group == junk:
        junk.update(str(action), window, mouse, parameters)
    elif group == walls:
        walls.update(str(action), window, mouse, parameters)
    elif group == floors:
        floors.update(str(action), window, mouse, parameters)
    elif group == dumpsters:
        dumpsters.update(str(action), window, mouse, parameters)
    elif group == parting:
        parting.update(str(action), window, mouse, parameters)

    returnParameters()

def resetGame(newtime, newmoney, newenergy, newmood):
    global time, money, energy, mood, currentTool, trashBags, trashPickedUp, cartSpace, parameters, maxSpace

    time = newtime
    money = newmoney
    energy = newenergy
    mood = newmood

    currentTool = None
    trashBags = 5
    trashPickedUp = 0
    maxSpace = 0
    cartSpace = maxSpace

    parameters.update()

def generateMap():
    global all, walls, floors, dumpsters, junk
    junk = createJunk(20)
    walls = createWalls(10)
    floors = createFlooring(20)
    dumpsters = createDumpsters(2)

def statsBar(percent, pos):
    global window
    for i in range(percent):
        render = pygame.surface.Surface([2, 10])
        render.fill([255 - i * 2.55, i * 2.55, 0])
        window.blit(render, [pos[0] + (i*2), pos[1]])

startButton = Button("Start Game", [554, 290])
quitButton = Button("Quit Game", [565, 370])
howToButton = Button("How to Play", [545, 330])
returnToMenu = Button("Return to Menu", [549, 540])
back = Button("Back", [5, 5])
buybags = Button("Buy Trash Bags", [205, 650])
upgradecart = Button("Upgrade Cart", [856, 650])
yes = Button("yes", [526, 410])
no = Button("no", [712, 410])

#generateMap()
resetGame(60, 50, 100, 100)

all, walls, floors, dumpsters, junk = map.generateMap(1)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse = event.pos[0], event.pos[1]
            pressed = pygame.mouse.get_pressed()
            if pressed[0] == 1:
                if screen == "game":
                    if clickArea(mouse, 1030, 1070, 675, 715) or clickArea(mouse, 1080, 1120, 675, 715) or clickArea(mouse, 930, 990, 650, 710):
                        if clickArea(mouse, 1030, 1070, 675, 715) and maxSpace > 0:
                            currentTool = "cart"
                            switch.play()
                        elif clickArea(mouse, 1080, 1120, 675, 715):
                            currentTool = "trash bags"
                            switch.play()
                        elif clickArea(mouse, 930, 990, 650, 710):
                            screen = "shop"
                            click.play()
                    elif currentTool == "cart" and cartSpace > 0:
                        parameters.update()
                        update(junk, "remove")
                        returnParameters()
                    elif currentTool == "trash bags" and trashBags > 0:
                        parameters.update()
                        update(junk, "remove")
                        returnParameters()
                elif screen == "menu":
                    if startButton.click():
                        screen = "game"
                        startButton.clicked = False
                        resetGame(600, 50, 100, 100)
                        returnToMenu.clicked = False
                        all.empty()
                        walls.empty()
                        floors.empty()
                        dumpsters.empty()
                        junk.empty()
                        all, walls, floors, dumpsters, junk = map.generateMap(1)
                    if quitButton.click():
                        running = False
                        quitButton.clicked = False
                    if howToButton.click():
                        screen = "how"
                        howToButton.clicked = False
                elif screen == "how":
                    if back.click():
                        screen = "menu"
                        back.clicked = False
                elif screen == "game over":
                    if returnToMenu.click():
                        screen = "menu"
                elif screen == "you win!":
                    if returnToMenu.click():
                        screen = "menu"
                        returnToMenu.clicked = False
                elif screen == "part":
                    if no.click():
                        update(parting, "removefromparting")
                        screen = "game"
                        no.clicked = False
                    elif yes.click():
                        update(parting, "kill")
                        screen = "game"
                        yes.clicked = False
                        returnParameters()
                elif screen == "shop":
                    if back.click():
                        screen = "game"
                        back.clicked = False
                    if buybags.click() and money >= 5:
                        trashBags += 5
                        money -= 5
                        parameters.update()
                        buybags.clicked = False
                    if upgradecart.click() and money >= cartPrice:
                        maxSpace += 5
                        money -= cartPrice
                        cartSpace += 5
                        cartPrice += int(1.5 * float(cartPrice))
                        parameters.update()
                        upgradecart.clicked = False
            elif pressed[2] == 1:
                if screen == "game":
                    if currentTool == "cart" or currentTool == "trash bags":
                        parameters.update()
                        update(dumpsters, "dump")
        elif event.type == pygame.KEYDOWN:
            if screen == "game":
                pressed = pygame.key.get_pressed()
                if pressed[pygame.K_LEFT]:
                    update(all, "scrollright")
                    player.scroll(-1, 0)
                    if pygame.sprite.spritecollide(player, junk, False) or pygame.sprite.spritecollide(player, walls, False) or pygame.sprite.spritecollide(player, dumpsters, False):
                        update(all, "scrollleft")
                if pressed[pygame.K_RIGHT]:
                    update(all, "scrollleft")
                    player.scroll(1, 0)
                    if pygame.sprite.spritecollide(player, junk, False) or pygame.sprite.spritecollide(player, walls, False) or pygame.sprite.spritecollide(player, dumpsters, False):
                        update(all, "scrollright")
                if pressed[pygame.K_UP]:
                    update(all, "scrollup")
                    player.scroll(0, -1)
                    if pygame.sprite.spritecollide(player, junk, False) or pygame.sprite.spritecollide(player, walls, False) or pygame.sprite.spritecollide(player, dumpsters, False):
                        update(all, "scrolldown")
                if pressed[pygame.K_DOWN]:
                    update(all, "scrolldown")
                    player.scroll(0, 1)
                    if pygame.sprite.spritecollide(player, junk, False) or pygame.sprite.spritecollide(player, walls, False) or pygame.sprite.spritecollide(player, dumpsters, False):
                        update(all, "scrollup")
                if pressed[pygame.K_b]:
                    if currentTool == "trash bags" and money >= 5:
                        trashBags += 5
                        money -= 5
                        parameters.update()

        elif event.type == pygame.USEREVENT and screen == "game":
            update(dumpsters, "clear")
            mood += 50
            if mood > 100:
                mood = 100
            energy += 50
            if energy > 100:
                energy = 100
        elif event.type == pygame.USEREVENT + 3 and screen == "game":
            if time > 0:
                time -= 1
            else:
                screen = "game over"
                gameover.play()
        elif event.type == pygame.USEREVENT + 2 and screen == "game":
            player.animate()
            player.moving = False
        elif event.type == pygame.USEREVENT + 1:
            if screen == "game":
                window.fill([191, 255, 128])
                update(floors, "draw")
                update(dumpsters, "draw")
                update(walls, "draw")
                update(junk, "draw")
                player.draw(window)

                #Toolbar
                rect = pygame.surface.Surface([1000, 80])
                window.blit(rect, [140, 640])
                if len(str(time % 60)) == 1:
                    text = font.render("time left: " + str(int(math.floor(time / 60))) + ":0" + str(time % 60), 1, [255, 255, 255])
                else:
                    text = font.render("time left: " + str(int(math.floor(time / 60))) + ":" + str(time % 60), 1, [255, 255, 255])
                window.blit(text, [145, 645])
                # text = font.render("money: " + str(money) + " dollars", 1,
                #                    [255, 255, 255])
                # window.blit(text, [375, 645])
                text = font.render("energy:", 1,
                                   [255, 255, 255])
                window.blit(text, [145, 672])
                statsBar(energy, [265, 676])

                text = font.render("mood:", 1,
                                   [255, 255, 255])
                window.blit(text, [145, 700])
                statsBar(mood, [245, 704])

                text = font.render("tools", 1,
                                   [255, 255, 255])
                window.blit(text, [1030, 645])

                window.blit(cart, [1030, 675])
                window.blit(trashbag, [1080, 675])

                window.blit(shop, [930, 650])

                if currentTool == "trash bags":
                    pygame.draw.rect(window, [255, 0, 0], [1080, 675, 40, 40], 2)
                    text = font.render("trash bags left: " + str(trashBags), 1,
                                       [255, 255, 255])
                    window.blit(text, [494, 672])
                elif currentTool == "cart":
                    pygame.draw.rect(window, [255, 0, 0], [1030, 675, 40, 40], 2)
                    text = font.render("space in cart: " + str(cartSpace), 1,
                                       [255, 255, 255])
                    window.blit(text, [494, 672])

                text = font.render("current tool: " + str(currentTool), 1,
                                   [255, 255, 255])
                window.blit(text, [494, 645])

                text = font.render("money: " + str(money) + " dollars", 1,
                                   [255, 255, 255])
                if currentTool == None:
                    window.blit(text, [494, 672])
                else:
                    window.blit(text, [494, 700])

                if len(parting) > 0 and not type(parting) == list:
                    screen = "part"

                if mood <= 0 or energy <= 0:
                    screen = "game over"

                if len(junk) <= 0:
                    screen = "you win!"

            elif screen == "you win!":
                window.fill([0, 0, 0])
                returnToMenu.draw()
                text = fontbig.render("You Win!", 1, [255, 255, 255])
                rect = int(640 - (text.get_rect().width / 2))
                window.blit(text, [rect, 180])

            elif screen == "part":
                window.fill([191, 255, 128])
                update(floors, "draw")
                update(dumpsters, "draw")
                update(walls, "draw")
                update(junk, "draw")
                player.draw(window)

                #DIALOG
                rect = pygame.surface.Surface([360, 360])
                window.blit(rect, [460, 180])

                text = font.render("this item is very", 1, [255, 255, 255])
                rect = 640 - (text.get_rect().width / 2)
                window.blit(text, [rect, 260])

                text = font.render("meaningful and", 1, [255, 255, 255])
                rect = 640 - (text.get_rect().width / 2)
                window.blit(text, [rect, 280])

                text = font.render("sentimental to you.", 1, [255, 255, 255])
                rect = 640 - (text.get_rect().width / 2)
                window.blit(text, [rect, 300])

                text = font.render("do you want to", 1, [255, 255, 255])
                rect = 640 - (text.get_rect().width / 2)
                window.blit(text, [rect, 320])

                text = font.render("part ways with it?", 1, [255, 255, 255])
                rect = 640 - (text.get_rect().width / 2)
                window.blit(text, [rect, 340])

                no.draw()
                yes.draw()

            elif screen == "shop":
                window.fill([0, 0, 0])
                text = fontbig.render("SHOP", 1, [255, 255, 255])
                rect = 640 - ((text.get_rect().width + 80) / 2)
                window.blit(text, [rect + 80, 5])
                window.blit(shop, [rect, 5])
                text = font.render("MONEY: " + str(money) + " dollars", 1, [255, 255, 255])
                rect = 640 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 75])

                window.blit(pygame.transform.scale(trashbag, [200, 200]), [220, 110])

                text = fontbig2.render("trash bags", 1, [255, 255, 255])
                rect = 320 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 320])

                text = font.render("Trash Bags Owned: " + str(trashBags), 1, [255, 255, 255])
                rect = 320 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 400])

                text = font.render("Trash Bags can hold small junk", 1, [255, 255, 255])
                rect = 320 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 440])

                text = font.render("and can hold one item per bag.", 1, [255, 255, 255])
                rect = 320 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 465])

                text = font.render("price: 5 dollars for 5 bags.", 1, [255, 255, 255])
                rect = 320 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 510])

                if money >= 5:
                    text = font.render("you can afford this item.", 1, [255, 255, 255])
                    rect = 320 - ((text.get_rect().width) / 2)
                    buybags.draw()
                    pygame.draw.rect(window, [255, 255, 255], [buybags.rect.left - 10, buybags.rect.top - 10,
                                                               buybags.rect.width + 20,
                                                               buybags.rect.height + 18], 2)
                else:
                    text = font.render("you cannot afford this item.", 1, [255, 255, 255])
                    rect = 320 - ((text.get_rect().width) / 2)

                window.blit(text, [rect, 535])

                window.blit(pygame.transform.scale(cart, [200, 200]), [860, 110])

                text = fontbig2.render("cart", 1, [255, 255, 255])
                rect = 960 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 320])

                if maxSpace == 0:
                    text = font.render("You currently don't own a cart.", 1, [255, 255, 255])
                    rect = 960 - ((text.get_rect().width) / 2)
                    window.blit(text, [rect, 400])
                else:
                    text = font.render("Current Cart Maximum Space: " + str(maxSpace), 1, [255, 255, 255])
                    rect = 960 - ((text.get_rect().width) / 2)
                    window.blit(text, [rect, 400])

                text = font.render("Carts can hold a mix of large and small", 1, [255, 255, 255])
                rect = 960 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 440])

                text = font.render("items. It can be upgraded to hold more.", 1, [255, 255, 255])
                rect = 960 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 465])

                text = font.render("price: " + str(cartPrice) + " dollars to hold 5 more items", 1, [255, 255, 255])
                rect = 960 - ((text.get_rect().width) / 2)
                window.blit(text, [rect, 510])

                if money >= cartPrice:
                    text = font.render("you can afford this item.", 1, [255, 255, 255])
                    rect = 960 - ((text.get_rect().width) / 2)
                    upgradecart.draw()
                    pygame.draw.rect(window, [255, 255, 255], [upgradecart.rect.left - 10, upgradecart.rect.top - 10, upgradecart.rect.width + 20, upgradecart.rect.height + 18], 2)
                else:
                    text = font.render("you cannot afford this item.", 1, [255, 255, 255])
                    rect = 960 - ((text.get_rect().width) / 2)

                window.blit(text, [rect, 535])

                back.draw()

                pygame.draw.rect(window, [255, 255, 255], [5, 100, 630, 600], 2)
                pygame.draw.rect(window, [255, 255, 255], [645, 100, 630, 600], 2)

            elif screen == "menu":
                text = fontbig.render("Don't take my Stuff!", 1, [255, 255, 255])
                rect = 640 - text.get_rect().width/2
                window.fill([0, 0, 0])
                window.blit(text, [rect, 10])
                startButton.draw()
                quitButton.draw()
                howToButton.draw()
            elif screen == "how":
                window.fill([0, 0, 0])
                text = fontbig.render("how to play", 1, [255, 255, 255])
                rect = 640 - text.get_rect().width / 2
                window.blit(text, [rect, 10])
                back.draw()
                text = font.render("use the arrow keys to move around.", 1, [255, 255, 255])
                window.blit(text, [10, 200])
                text = font.render("left click to pick up junk.", 1, [255, 255, 255])
                window.blit(text, [10, 230])
                text = font.render("right click on a dumpsterto dump junk you're carrying into the dumpster.", 1, [255, 255, 255])
                window.blit(text, [10, 260])
                text = font.render("goal of the game is to clean the entire house before the time runs out.", 1, [255, 255, 255])
                window.blit(text, [10, 320])
                text = font.render("keep an eye on your mood and energy, if either hit zero you lose.", 1, [255, 255, 255])
                window.blit(text, [10, 350])
            elif screen == "game over":
                window.fill([0, 0, 0])
                returnToMenu.draw()
                text = fontbig.render("Game Over", 1, [255, 255, 255])
                rect = int(640 - (text.get_rect().width / 2))
                window.blit(text, [rect, 180])
    pygame.display.flip()
pygame.quit()