import pygame
from pygame.locals import *
import os
import random


import pygame.draw


from . import util
from .pgu import gui

try:
    # import pgu.html
    from . import html
except ImportError:
    # a fake html write function.
    class __html(object):
        def write(self, *args):
            pass

    html = __html()

from .const import *
from . import units

from . import messages

from . import cyclic_list
import pygame.sprite

# class


class StatsDraw:
    """draws the stats health, coal, water, steam on the left side of interface."""

    def __init__(self):
        self.frames = 0
        self.update_frame = {}
        self.update_which = cyclic_list.cyclic_list(
            ["Health", "Coal", "Water", "Steam"]
        )
        self.frames_health = 0

    def draw_img(self, screen, min, max, current, color, where_rect, astat):
        """eg. min - 0, max - 100, current - 45"""

        # this draws an image cutting off the top bit

        height = ((max - min) // (max * 1.0)) * current
        graph_height = where_rect.h
        height = (graph_height // (max * 1.0)) * current

        clip_rect = pygame.Rect(where_rect)
        clip_rect.x = 0
        clip_rect.y = 0
        clip_rect.h = int(height)

        diff = where_rect.h - int(height)
        clip_rect.y += diff

        im_border = None

        if astat == "Health":
            # show the heart every pulse every half a second or so.
            if self.frames_health > (FPS // 2):
                k = "heart.png"
                if self.frames_health > FPS:
                    self.frames_health = 0
            else:
                k = "heart_pulse.png"

            im = self.images[k]

            if k + "laplacian" not in self.images:
                self.images[k + "laplacian"] = pygame.transform.laplacian(im)

            im_border = self.images[k + "laplacian"]

            c = clip_rect.clip(im.get_rect())
            if not c.width and not c.height:
                s = None
            else:
                print((im, c))
                s = im.subsurface(c)

        else:
            raise ValueError("not implemented for this stat")

        draw_rect = pygame.Rect(where_rect)
        draw_rect.y += diff
        if s:
            screen.blit(s, draw_rect)

        if im_border:
            screen.blit(im_border, where_rect)

        return where_rect

    def draw_rect(self, screen, min, max, current, color, where_rect):
        """eg. min - 0, max - 100, current - 45"""
        draw_rect = pygame.Rect(where_rect)

        height = ((max - min) // (max * 1.0)) * current

        graph_height = draw_rect.h

        height = (graph_height // (max * 1.0)) * current

        draw_rect.h = int(height)
        draw_rect.y += where_rect.h - draw_rect.h

        # draw_rect = multr( dxdy, draw_rect)

        s = screen.subsurface(draw_rect)
        s.fill(color)
        return where_rect

    def update_stats(self, screen, stats, robots, max_robots):
        # def update_stats(self, screen, stats):
        # print stats
        # print max_robots

        # return []

        self.interface.dirty["left_background"] = 1
        self.interface.update_left_background(screen)

        stat_rect = {}
        stat_rect["Health"] = S_HEALTH
        stat_rect["Coal"] = S_COAL
        stat_rect["Water"] = S_WATER
        stat_rect["Steam"] = S_STEAM
        stat_rect["CannonPressure"] = S_CANNON_PRESSURE

        stat_color = {}
        stat_color["Health"] = (255, 0, 0)
        stat_color["Coal"] = (0, 0, 0)
        stat_color["Water"] = (0, 0, 255)
        stat_color["Steam"] = (200, 200, 200)
        stat_color["CannonPressure"] = (100, 100, 200)

        updates = []
        update_thisone = self.update_which.nextone()

        for astat in ["Health", "Coal", "Water", "Steam", "CannonPressure"]:
            # update cannon pressure every frame.  Spread the others out.
            if not (astat in [update_thisone, "CannonPressure"]):
                continue

            where_rect = stat_rect[astat]
            color = stat_color[astat]
            min = 0
            max = int(stats["Max" + astat])
            current = int(stats[astat])
            # print where_rect

            # only draw the screen where the rectangle will be drawn.
            if 0:
                c = screen.get_clip()
                screen.set_clip(where_rect)
                screen.blit(self.images["background_status_left.png"], S_STATUS)
                screen.set_clip(c)

            if astat in ["Health"]:
                r = self.draw_img(screen, min, max, current, color, where_rect, astat)
            else:
                r = self.draw_rect(screen, min, max, current, color, where_rect)
            updates.append(r)

        # robots.
        if 1:
            where_rect = S_PEASANTS_REMAINING
            #             color = (200,200,40)
            #             min =0
            #             max = max_robots
            #             current = int(len(robots))
            #
            #             updates = []
            #             r = self.draw_rect(screen, min, max, current, color, where_rect)

            # top right corner remaining 'robots' are shown.

            if self.robots_update:
                r = where_rect
                sc = screen.subsurface(where_rect)
                sc.fill((0, 0, 0))
                img = self.robots_image
                w = sc.get_width() - img.get_width()
                h = sc.get_height() - img.get_height()

                for n in range(0, int(self.robots_total)):
                    sc.blit(img, (random.randrange(0, w), random.randrange(0, h)))

                updates.append(r)

        self.frames_health += 1
        self.frames += 1
        return updates


class Interface:
    def __init__(self):
        """ """

        self.frames = 0
        self.message = messages.generate()
        self.last_message = ""

        self.message_font = pygame.font.Font(data_dir("menu", "vinque.ttf"), 20)
        self.equipment_message_font = pygame.font.Font(
            data_dir("menu", "vinque.ttf"), 14
        )

        self.stats = {}
        self.stats_draw = StatsDraw()
        self.stats_draw.interface = self

        self.equipment_last_message = ""
        self.equipment_message = ""

    def loop(self):
        self.frames += 0

    def load(self):
        """loads the graphics/sounds/resources needed."""

        images_needed = [
            "health_overlay.png",
            "coal_overlay.png",
            "water_overlay.png",
            "steam_overlay.png",
            "background_status_left.png",
            "background_bottom.png",
            "background_illustration.png",
            "background_equipment.png",
            "background_buttons.png",
            "background_messages.png",
            "button_save.png",
            "button_load.png",
            "button_quit.png",
            "button_news.png",
            "button_save_rollover.png",
            "button_load_rollover.png",
            "button_quit_rollover.png",
            "button_news_rollover.png",
            "button_save_down.png",
            "button_load_down.png",
            "button_quit_down.png",
            "button_news_down.png",
            "heart.png",
            "heart_pulse.png",
        ]
        self.images = {}
        self.stats_draw.images = self.images

        for i in images_needed:
            image_path = data_dir("gfx", i)
            print(image_path)
            if os.path.exists(image_path):
                self.images[i] = pygame.image.load(image_path)
                if i in ["heart.png", "heart_pulse.png"]:
                    self.images[i] = self.images[i].convert_alpha()
                else:
                    self.images[i] = self.images[i].convert()
            else:
                self.images[i] = None

        def scale_images(images):
            screen_size = pygame.display.get_surface().get_size()
            # scaler = pygame.transform.smoothscale
            scaler = pygame.transform.scale
            new_images = {}

            orig_size = 640, 480
            for i, surf in list(images.items()):
                if images[i]:
                    r = surf.get_rect()
                    size_scale = util.scale_rect(r, orig_size, screen_size)[2:]

                    new_images[i] = scaler(surf, size_scale)
                else:
                    new_images[i] = surf
            return new_images

        self.images = scale_images(self.images)

        self.bkgrb = pygame.Surface((S_BOTTOM_MESSAGES.w, S_BOTTOM_MESSAGES.h))
        self.bkgrb = self.bkgrb.convert_alpha()
        self.bkgrb.fill((0, 0, 0, 70))

        self.dirty = {}
        d = self.dirty

        d["messages"] = 1
        d["bottom_background"] = 1
        d["left_background"] = 1
        d["background_equipment"] = 1
        d["background_illustration"] = 1
        d["background_buttons"] = 1
        d["background_messages"] = 1
        d["equipment_words"] = 1
        d[""] = 1

    def event(self, g, e):
        pass

        # TODO: handle button clicks.
        if e.type == MOUSEBUTTONDOWN:
            x, y = e.pos
            print((x, y))

            if S_BUTTONS_SAVE.collidepoint(x, y):
                print("save")

            if S_BUTTONS_LOAD.collidepoint(x, y):
                print("load")

            if S_BUTTONS_QUIT.collidepoint(x, y):
                print("quit")

            if S_BUTTONS_NEWS.collidepoint(x, y):
                print("news")
        if e.type == KEYDOWN:
            if e.key == K_m:
                print("ASDFSADF")
                self.new_random_message()

    def new_stats(self, stats):
        """draws the stats with new values."""

    def new_random_message(self):
        self.last_message = self.message
        self.message = messages.generate()
        self.message = self.message.replace("ZANTHOR", "<b>ZANTHOR</b>")
        self.message = self.message.replace("Zanthor", "<b>ZANTHOR</b>")
        self.message = self.message.replace("zanthor", "<b>ZANTHOR</b>")
        self.dirty["messages"] = 1
        self.dirty["background_messages"] = 1

    def new_upgrade_message(self, upgrade_what):
        if upgrade_what:
            self.last_message = self.message
            self.message = messages.generate_upgrade_message(upgrade_what)
        self.dirty["messages"] = 1
        self.dirty["background_messages"] = 1

    def update_messages(self, screen):
        """ """

        # the messages are the same... no need to update.
        if not self.dirty["messages"]:
            if self.message == self.last_message:
                self.dirty["messages"] = 0
                return []

        if self.dirty["messages"]:
            self.dirty["messages"] = 0

            font = self.message_font  # pygame.font.Font(None, 18)
            rect = S_MESSAGES
            rect2 = pygame.Rect(S_MESSAGES)
            rect2.x -= 1
            rect2.y += 1

            aa = 0
            # color = (0x55,0xff,0x55) #(80,80,80)
            color = (0xFF, 0x55, 0x55)  # (80,80,80)
            color2 = (0, 0, 0)  # (80,80,80)

            bgcolor = (0, 0, 0, 0)
            s = screen
            # screen.blit(self.bkgrb, S_MESSAGES)

            # pgu.html.render(font,rect,text,aa,color,bgcolor)
            html.write(s, font, rect2, self.message, aa, color2)
            html.write(s, font, rect, self.message, aa, color)

            return [rect]
        else:
            return []

    def update_bottom_background(self, screen):
        if self.dirty["bottom_background"]:
            self.dirty["bottom_background"] = 0
            screen.blit(self.images["background_bottom.png"], S_BOTTOM)

            return [S_BOTTOM]
        else:
            return []

    def update_left_background(self, screen):
        if self.dirty["left_background"]:
            # FIXME: HACK: TODO: this should be 0 when stats update properly.
            self.dirty["left_background"] = 0
            screen.blit(self.images["background_status_left.png"], S_STATUS)
            return [S_STATUS]
        else:
            return []

    def new_equipment(self, stats):
        self.equipment_last_message = self.equipment_message
        self.equipment_message = "<br><br>"

        for upword in units.upgrade_words:
            self.equipment_message += "%s/%s " % (
                stats["upgrade_amounts"][upword].idx,
                5,
            )
            self.equipment_message += "" + upword.replace("Up", "") + "<br>"
            # TODO: HACK: fix up 5 to be the maximum for that level.

        self.dirty["equipment_words"] = 1
        self.dirty["background_equipment"] = 1

    def update_background_equipment(self, screen):
        if self.dirty["background_equipment"]:
            self.dirty["background_equipment"] = 0
            screen.blit(self.images["background_equipment.png"], S_ITEMS)
            return [S_ITEMS]
        else:
            return []

    def update_equipment_words(self, screen):
        """ """

        # the messages are the same... no need to update.
        if not self.dirty["equipment_words"]:
            if self.equipment_message == self.equipment_last_message:
                self.dirty["equipment_words"] = 0
                return []

        if self.dirty["equipment_words"]:
            self.dirty["equipment_words"] = 0

            font = self.equipment_message_font  # pygame.font.Font(None, 18)
            rect = S_ITEMS
            rect2 = pygame.Rect(S_ITEMS)
            rect2.x -= 1
            rect2.y += 1

            aa = 0
            color = (0x55, 0xFF, 0x55)  # (80,80,80)
            color2 = (0, 0, 0)
            bgcolor = (0, 0, 0, 0)
            s = screen

            # pgu.html.render(font,rect,text,aa,color,bgcolor)
            html.write(s, font, rect2, self.equipment_message, aa, color2)
            html.write(s, font, rect, self.equipment_message, aa, color)

            return [rect]
        else:
            return []

    def update_background_illustration(self, screen):
        if self.dirty["background_illustration"]:
            self.dirty["background_illustration"] = 0
            screen.blit(self.images["background_illustration.png"], S_ROBOT)

            return [S_ROBOT]
        else:
            return []

    def update_background_buttons(self, screen):
        if self.dirty["background_buttons"]:
            self.dirty["background_buttons"] = 0
            s = screen.subsurface(S_BUTTONS)
            surf = self.images["background_bottom.png"]

            screen.blit(surf, S_BUTTONS, S_BOTTOM_BUTTONS)
            return [S_BUTTONS]
        else:
            return []

    def update_background_buttons(self, screen):
        if self.dirty["background_messages"]:
            self.dirty["background_messages"] = 0
            surf = self.images["background_bottom.png"]

            screen.blit(surf, S_MESSAGES, S_BOTTOM_MESSAGES)
            return [S_MESSAGES]
        else:
            return []

    def update(self, tv, screen):
        """returns a list of rects."""

        if self.equipment_message == "":
            self.new_equipment(tv.castle.unit.stats)

        updates = []

        # temporary interface boxes.
        if 0:
            s = screen.subsurface(S_HEALTH)
            s.fill((255, 0, 0))
            updates.append(S_HEALTH)

            s = screen.subsurface(S_COAL)
            s.fill((0, 0, 0))
            updates.append(S_COAL)

            s = screen.subsurface(S_WATER)
            s.fill((0, 0, 255))
            updates.append(S_WATER)

            s = screen.subsurface(S_STEAM)
            s.fill((200, 200, 200))
            updates.append(S_STEAM)

        updates.extend(self.update_bottom_background(screen))
        updates.extend(self.update_left_background(screen))

        updates.extend(self.update_background_buttons(screen))
        updates.extend(self.update_background_illustration(screen))
        updates.extend(self.update_background_equipment(screen))

        updates.extend(self.update_background_buttons(screen))

        # updates.extend( self.update_status_left(screen) )
        # updates.extend( self.update_background_equipment(screen) )
        # updates.extend( self.update_(screen) )

        if 0:
            screen.blit(self.images["background_status_left.png"], S_STATUS)
            updates.append(S_STATUS)

            screen.blit(self.images["background_equipment.png"], S_ITEMS)
            updates.append(S_ITEMS)

            screen.blit(self.images["background_illustration.png"], S_ROBOT)
            updates.append(S_ROBOT)

        # s = screen.subsurface(S_MESSAGES)
        # s.fill((0,200,0))

        m = self.update_messages(screen)
        updates.extend(m)

        ew = self.update_equipment_words(screen)
        updates.extend(ew)

        stats_rects = self.stats_draw.update_stats(
            screen, self.tv.castle.unit.stats, self.tv.robots, self.max_robots
        )
        updates.extend(stats_rects)

        # s = screen.subsurface(S_ROBOT)
        # s.fill((200,200,200))
        # updates.append(S_ROBOT)

        # s = screen.subsurface(S_ITEMS)
        # s.fill((250,250,250))
        # updates.append(S_ITEMS)

        # s = screen.subsurface(S_BUTTONS)
        # s.fill((150,150,200))

        if 0:
            s = screen.subsurface(S_BUTTONS_SAVE)
            s.fill((50, 50, 20))
            s = screen.subsurface(S_BUTTONS_LOAD)
            s.fill((50, 50, 20))
            s = screen.subsurface(S_BUTTONS_QUIT)
            s.fill((50, 50, 200))
            s = screen.subsurface(S_BUTTONS_NEWS)
            s.fill((50, 150, 200))

            updates.append(S_BUTTONS)

        # print updates

        return updates


if __name__ == "__main__":
    pass
