"""
Copyright (C) 2008  Matthew and Joey Marshall <joey@arcticpaint.com>

See main.py for full notice.
"""
from __future__ import division
import sys
import rabbyt, math
from pyglet.text import HTMLLabel
import snowui
from pyglet.window import mouse, key
import pyglet

from gamelib.cable import Cable
from gamelib.station import Station, COLORS, _COLORS_LOOKUP, FIGURES
from gamelib.menu import Text

from gamelib.input import TextWidget
from gamelib.ingame_menu import IngameMenu
#from gamelib.minimap import Minimap

import simplejson

class ConnectionOption(snowui.Button):
    selected_shape = None
    selected_color = None

    def __init__(self, **kwargs):
        snowui.Button.__init__(self, **kwargs)
        self.shape.bottom, self.shape.left = self.orig_shape

        self.hover_color = tuple(self.rgb)+(.5,)
        self.default_color = tuple(self.rgb)+(1,)
        self.fade_time = .1

    def render(self):
        rabbyt.Sprite.render(self)
        if self.selected_shape == self or self.selected_color == self:
            self.ui.cas_selection_sprite.xy = self.xy
            self.ui.cas_selection_sprite.render()


    def handle_mouse_press(self, x, y, button, modifiers):
        if button == mouse.LEFT:
            if self.type == "figure":
                ConnectionOption.selected_shape = self

                self.ui.selected_filter.connection.match_figure = self.name

            if self.type == "color":
                ConnectionOption.selected_color = self

                self.ui.selected_filter.connection.match_color = self.name

    def collide(self, xy):
        w = (self.shape.width/2)
        b = self.x, self.y, w+4
        return rabbyt.collisions.collide_single(b, [xy])

class HelpBubble(snowui.Button):

    def __init__(self, ui, text, **kwargs):
        snowui.Button.__init__(self, callback=self.close,
                texture="help_bubble.png", **kwargs)
        self.hover_color = (1,1,1,.8)
        self.default_color = (1,1,1,1)
        self.y += 30
        self.ui = ui
        self.text = HTMLLabel(text, multiline=True, width=210, x=self.x+25,
                y=self.y+100)
        self.text.font_size = 12

    def render(self):
        r = rabbyt.collisions.aabb_collide_single(
                        rabbyt.Quad(self.ui.view.bounds), [self])
        if r:
            self.ui.view.set_viewport()
            snowui.Button.render(self)
            self.text.draw()
            self.ui.gui_view.set_viewport()

    def close(self):
        self.ui.remove(self)

    def collide(self, xy):
        x,y = self.ui.view.to_world_pixels(xy)
        # gotta wait until Matthew makes just a tuple work with this.
        return rabbyt.collisions.aabb_collide_single(
                rabbyt.Quad((x,y,x,y)), [self])



class UI(snowui.GUI):
    def __init__(self, map, view, window):
        snowui.GUI.__init__(self, bounds="always")


        self.build_button = snowui.widget_setting(snowui.Button,
                texture="button.png", bounds="rect",
                callback=self.set_mode,
                default_color=(0,0.7,0,1), hover_color=(0,1,0,1))


        self.game_speed = 1

        self.quit_game = False
        self.map = map
        self.window = window
        self.world = map.world
        self.world.ui = self

        self.world.stepables.append(self)

        self.final_score = 0

        self.view = view
        self.zoom_index = 1
        self.zoom_levels = [1, 2, 3, 5]
        self.center_on = None
        self.gui_view = snowui.View(window)
        self.gui_view.x = self.gui_view.width/2
        self.gui_view.y = self.gui_view.height/2

        window.event(self.on_resize)

        self.time_left_label = Text(str(self.time_left), x=self.view.width/2,
                y=self.view.height-30, anchor_x="center", font_size=25)
        self.add(self.time_left_label)

        if self.map.data.has_key("help_bubbles"):
            for b in self.map.data["help_bubbles"]:
                xy = self.world.station_placeholders[b["index"]].xy
                self.add(HelpBubble(self, b["text"], xy=xy))

        self.hud = IngameHud(self)
        self.add(self.hud)

        self.hud_popup = snowui.Widget(texture="hud_popup.png", bounds="rect",
                x=self.view.width/2-139/2)
        self.add(self.hud_popup)
        self.hud_popup.is_active = False
        self.hud_popup.y = -174

        self.selected_filter = None
        self.cas_selection_sprite = rabbyt.Sprite("connection_selection.png")


        self.dropped_items = {}

        self.stats_popup = snowui.Button(texture="stats_popup.png", bounds="rect",
                x=-105, y=-145, hover_color=(1,.5,1,1), default_color=(1,1,.5,1),
                callback=self.toggle_stats)
        self.add(self.stats_popup)
        self.stats_hidden = True
        self.stats_text = {}


        self.clear_stats_button = self.build_button(icon="icon_clear.png",
                callback=self.clear_stats)
        self.add(self.clear_stats_button)
        self.clear_stats_button.x = 35 + self.stats_popup.attrgetter("x")
        self.clear_stats_button.y = self.stats_popup.attrgetter("y")



        self._cash = self.map.data["settings"]["cash"]
        self.cash_label = Text("$"+str(self._cash), rx=252/2+50,
                ry=24, anchor_x="center", font_size=12, color=(0,0,0,255))
        self.hud.add(self.cash_label)
        self.cost_label = HTMLLabel("")

        self._score = 0
        self.score_label = Text("score: "+str(self._score),
                rx=252/2+50, ry=6, anchor_x="center", font_size=12, color=(0,0,0,255))
        self.hud.add(self.score_label)


        self.connection_sprite = rabbyt.Sprite(shape=(0,20,1,-20), alpha=0)
        self.world.renderables["hud"].append(self.connection_sprite)

        self.hud_options_shape = {}
        self.hud_options_color = {}

        for i,name in enumerate(FIGURES+(None,)):
            if name:
                tex = name+".png"
            else:
                tex = "all.png"
            s = ConnectionOption(texture=tex, rx=80, ry=140-25*i)
            s.type = "figure"
            s.ui = self
            s.name = name
            self.hud_popup.add(s)
            self.hud_options_shape[str(name)] = s

        for i,(name, color) in enumerate(COLORS+((None,(1,1,1)),)):
            if name is None:
                s = ConnectionOption(texture="all.png", rx=40, ry=140-25*i,
                        rgb=color)
            else:
                s = ConnectionOption(rx=40, ry=140-25*i, rgb=color)
            s.type = "color"
            s.ui = self
            s.name = name
            self.hud_popup.add(s)
            self.hud_options_color[str(name)] = s

        #self.minimap_border = snowui.Widget(texture="minimap/border.png", y=self.view.height-170)
        #self.add(self.minimap_border)

        #self.minimap = Minimap(self, shape=(0, 150,150, 0), y=self.view.height-150, x=0)
        #self.add(self.minimap)

        #b = snowui.Button(texture="minimap/zoom.png", y=self.minimap_border.y+5,
                #x=130, callback=self.minimap.zoom_big)
        #self.add(b)


    def on_resize(self,width, height):
        self.view.width = self.gui_view.width = width
        self.view.height = self.gui_view.height = height
        self.gui_view.x = self.gui_view.width/2
        self.gui_view.y = self.gui_view.height/2

        self.toggle_stats(fast_remove=True)
        self.toggle_stats(fast_remove=True)
        if self.ingame_menu.is_active == False:
            self.ingame_menu.x = self.view.width
        self.set_mode(self.mode)
        self.time_left_label.x = self.view.width/2
        self.time_left_label.y = self.view.height-30

        #self.minimap.x=self.view.width-151
        #self.minimap.y=self.view.height-150
        #self.minimap_border.y=self.view.height-170
        #self.minimap.pane.shape=(self.view.width/3*self.minimap.zoom,
                #self.view.height/3*self.minimap.zoom)

    @property
    def time_left(self):
        return int((self.map.data["settings"]["time"]*60-rabbyt.get_time())//60)+1

    def step(self):
        t = self.time_left
        if t <= 0:
            self.final_score = self.score
            self.remove(self.time_left_label)
            self.world.stepables.remove(self)
            self.ingame_menu.enter_highscore()
        else:
            t = str(t)
            if t != self.time_left_label.text:
                self.time_left_label.text = t

    def _set_cash(self, c):
        self._cash = c
        self.cash_label.text = "$"+str(self._cash)
    cash = property(lambda self: self._cash, _set_cash)

    def _set_score(self, c):
        self._score = c
        self.score_label.text = "score: "+str(self._score)
    score = property(lambda self: self._score, _set_score)

    def setup(self):
        """
        A hack. We can't push any more handlers until after the UI is pushed.
        """
        self.mouse_xy = (110,110)
        self.keyboard = key.KeyStateHandler()
        self.window.push_handlers(self.keyboard)
        self.scroll_speed = 600

        self.mode = None
        self.selected = None
        self.selection_sprite = rabbyt.Sprite("selection.png")
        self.selection_sprite.alpha = rabbyt.lerp(start=.5, end=1, dt=.7,
                extend="reverse")
        self.hovered_filter = None


        #self.hud.add(self.build_button(icon="icon_connect.png", rx=5,
                #cb_data="connect"))
        #self.hud.add(self.build_button(icon="icon_build.png", rx=10+56,
                #cb_data="build"))


        self.ingame_menu = IngameMenu(self)
        self.add(self.ingame_menu)


        self.hud.setup()

    def update_stats(self):
        if self.stats_hidden == False:
            self.toggle_stats(fast_remove=True)
            self.toggle_stats(fast_remove=True)
    def clear_stats(self):
        self.dropped_items = {}
        self.update_stats()

    def toggle_stats(self, fast_remove=False):
        if self.stats_hidden == True:
            if fast_remove:
                self.stats_popup.x = 0
                self.stats_popup.y = 0
            else:
                self.stats_popup.x = rabbyt.lerp(end=0, dt=.1)
                self.stats_popup.y = rabbyt.lerp(end=0, dt=.1)
            self.stats_popup.hover_color = (1,1,1,1)
            self.stats_popup.default_color = (1,1,1,.8)
            self.stats_popup.do_fade(self.stats_popup.rgba, (1,1,1,1))


            l = self.dropped_items.items()
            l.sort()
            for i,((figure, color), value) in enumerate(l):
                row = i//6
                s = snowui.Widget(texture=figure+".png", rgb=_COLORS_LOOKUP[color],
                        rx=10+row*50, ry=140-i*20 + row*6*20)
                self.stats_popup.add(s)
                if not self.stats_text.has_key((figure, color)):
                    t = Text("", font_size=10, color=(0,0,0,255))
                    self.stats_text[(figure, color)] = t

                t = self.stats_text[(figure, color)]
                t.rx = s.rx+15
                t.ry = s.ry

                # Update them sequentially over time so it doesn't bog down the
                # system.
                def update_text(v, vv):
                    v.text = str(vv)
                self.world.clock.schedule_once(
                        (lambda v, vv:(lambda dt:update_text(v,vv)))(t, value),
                        .1*i)
                self.stats_popup.add(t)


        else:
            #if not fast_remove:
            self.stats_popup.x = rabbyt.lerp(end=-105, dt=.1)
            self.stats_popup.y = rabbyt.lerp(end=-145, dt=.1)
            self.stats_popup.hover_color = (1,.5,1,1)
            self.stats_popup.default_color = (1,1,.5,1)

            # TODO: Wait .7 sec to remove?
            for c in self.stats_popup.children:
                c.parent = None
            self.stats_popup.children = []

        self.stats_hidden = not self.stats_hidden


    def set_game_speed(self, speed):
        self.game_speed = speed

        for b in self.hud.speed_buttons:
            b.default_color = (1,1,1,1)
            b.rgba = (1,1,1,1)
            b.hover_color = (.7,1,.7,1)

        c = (.4,1,.4,1)
        self.hud.speed_buttons[speed].default_color = c
        self.hud.speed_buttons[speed].hover_color = c
        self.hud.speed_buttons[speed].rgba = c


    def end_game(self):
        self.quit_game = True

    def scroll_screen(self, dt):
        x, y = self.mouse_xy
        ss = self.scroll_speed*dt
        if x < 10:
            self.view.x -= ss
            self.center_on = None
        elif x > self.window.width-10:
            self.view.x += ss
            self.center_on = None
        if y < 4:
            self.view.y -= ss
            self.center_on = None
        elif y > self.window.height - 10:
            self.view.y += ss
            self.center_on = None

        k = self.keyboard
        if k[key.RIGHT] or k[key.D]:
            self.view.x += ss
            self.center_on = None
        if k[key.LEFT] or k[key.A]:
            self.view.x -= ss
            self.center_on = None
        if k[key.UP] or k[key.W]:
            self.view.y += ss
            self.center_on = None
        if k[key.DOWN] or k[key.S]:
            self.center_on = None
            self.view.y -= ss

        if self.center_on:
            if self.center_on[0]:
                diffx = self.center_on[0]-self.view.x
                if abs(diffx) < 10:
                    self.center_on = (None,self.center_on[1])
                else:
                    self.view.x += diffx/abs(diffx) * abs(diffx)/10
            if self.center_on[1]:
                diffy = self.center_on[1]-self.view.y
                if abs(diffy) < 10:
                    self.center_on = (self.center_on[0], None)
                else:
                    self.view.y += diffy/abs(diffy) * abs(diffy)/10

        self.view.keep_within(self.map.scroll_bounds)

        do_scroll_x = do_scroll_y = True
        l,t,r,b = self.map.scroll_bounds
        w = abs(l-r)
        h = abs(t-b)
        if w < self.view.scale_w:
            do_scroll_x = False
        if h < self.view.scale_h:
            do_scroll_y = False

        #if self.center_on:
            #if do_scroll_x:
                #self.view.x = rabbyt.lerp(end=self.center_on[0], dt=.2)
            #if do_scroll_y:
                #self.view.y = rabbyt.lerp(end=self.center_on[1], dt=.2)
        #print  self.center_on , (int(self.view.xy[0]), int(self.view.xy[1]))
        #if self.center_on == (int(self.view.xy[0]), int(self.view.xy[1])):
            #self.center_on = None

        if not do_scroll_x:
            self.view.x = (l+r)/2
        if not do_scroll_y:
            self.view.y = (t+b)/2

        self.view.set_viewport()

        x,y = self.view.to_world_pixels((x,y))
        f = self.collide_objects((x,y), self.world.filters)
        if f:
            f = f[0]
            if f is not self.hovered_filter:
                if self.hovered_filter:
                    self.hovered_filter.red = rabbyt.lerp(end=1, dt=.5)
                self.hovered_filter = f
                f.red = rabbyt.lerp(end=.5, dt=.2)
        elif self.hovered_filter:
                self.hovered_filter.red = rabbyt.lerp(end=1, dt=.2)
                self.hovered_filter = None

    def render(self):

        if self.mode == "build" or self.mode == "station_places":
            for sp in self.world.station_placeholders:
                if not sp.station:
                    sp.render()
        if self.selected:
            self.selection_sprite.xy = self.selected.xy
            self.selection_sprite.render()

        self.gui_view.set_viewport()
        snowui.GUI.render(self)

        x,y = self.view.to_world_pixels(self.mouse_xy)
        if self.mode == "build" and self.selected:
            s = self.collide_objects((x,y), self.world.stations)
            interfering = []
            if s:
                s = s[0]
                endpoint = s.xy
                if s != self.selected:
                    interfering = self.check_interfering_cables(s, self.selected)
                    if not interfering:
                        length = math.hypot(self.selected.y-s.y,
                                    self.selected.x-s.x)
                        cost = int(20 + length**1.2//6)
                        txt = "(-$%i)"%cost
                        if self.cost_label.text != txt:
                            self.cost_label.text = txt
                            self.cost_label.color = (255,0,0,255)
                            self.cost_label.font_size = 15
                        self.cost_label.x = x
                        self.cost_label.y = y
                        self.view.set_viewport()
                        self.cost_label.draw()
            else:
                endpoint = (x,y)
                interfering = self.check_interfering_cables_xy(self.selected, (x,y))
            if interfering:
                self.connection_sprite.rgb = rabbyt.lerp((1,0,0), (1,1,1), dt=.5)
                for cable in interfering:
                    cable.flash_error()
            dx = endpoint[0] - self.connection_sprite.x
            dy = endpoint[1] - self.connection_sprite.y
            self.connection_sprite.scale_x = math.hypot(dy, dx)
            self.connection_sprite.rot = math.degrees(math.atan2(dy, dx))
            self.connection_sprite.alpha = rabbyt.lerp(.5, 0, dt=.5)



    def set_mode(self, mode):
        if mode == self.mode:
            return
        if mode == "build":
            for s in self.world.stations:
                s.alpha = rabbyt.lerp(start=1, end=.5, dt=.4, extend="reverse")
            self.hud.build_button.rgba = self.hud.build_button.default_color = (.9,.9,1,1)
        elif self.mode == "build":
            # we are switching away from build mode
            self.hud.build_button.rgba = self.hud.build_button.default_color = (1,1,1,1)
            for s in self.world.stations:
                s.alpha = rabbyt.lerp(end=1, dt=.2)
            self.connection_sprite.alpha = rabbyt.lerp(end=0, dt=.5)
        self.mode = mode
        self.selected = None

        if not mode:
            self.window.set_mouse_cursor(self.cursors["default"])
        elif self.cursors.has_key(mode):
            self.window.set_mouse_cursor(self.cursors[mode])
        else:
            self.window.set_mouse_cursor(self.cursors["build"])

    def handle_mouse_motion(self, x, y, dx, dy):
        self.mouse_xy = (x,y)

    def handle_mouse_press(self, x, y, button, modifiers):
        if button == mouse.LEFT and (self.hud_popup.collide((x,y)) or\
                self.stats_popup.collide((x,y))):
            #self.hud.collide((x,y)) or
            return
        x,y = self.view.to_world_pixels((x,y))
        if button == mouse.LEFT:
            # Connection
            s = self.collide_objects((x,y), self.world.stations)
            if s:
                self.set_mode("build")
                s = s[0]
                if s == self.selected:
                    return

                if not self.selected:
                    self.selected = s
                    self.connection_sprite.xy = self.selected.xy
                    self.connection_sprite.alpha = rabbyt.lerp(0,.5, dt=.5)
                else:
                    interfering = self.check_interfering_cables(self.selected, s)
                    if not interfering:
                        length = math.hypot(self.selected.y-s.y,
                                    self.selected.x-s.x)
                        cost = int(20 + length**1.2//6)
                        if self.cash < cost:
                            # TODO: Better alert user that they don't have
                            # enough cash.
                            self.hud.rgb = rabbyt.ease_in(start=(1,0,0),
                                    end=(1,1,1), dt=1, method="bounce")
                        else:
                            c = Cable(self.world, (self.selected,s),
                                    fade_in=0.7)
                            self.selected = None
                            self.cash -= cost
                            self.world.sound_manager.play("connection", s.xy,
                                    random_pitch=.5)
                        self.connection_sprite.alpha = rabbyt.lerp(end=0, dt=.5)
                    else:
                        for cable in interfering:
                            cable.flash_error()

            if self.mode == "build":
                # Tower
                sp = self.collide_objects((x,y),
                        self.world.station_placeholders)
                if sp:
                    sp = sp[0]
                    if not sp.station:
                        if self.cash < 20:
                            # TODO: Better alert user that they don't have
                            # enough cash.
                            self.hud.rgb = rabbyt.ease_in(start=(1,0,0),
                                        end=(1,1,1), dt=1, method="bounce")
                        else:
                            s = Station(self.world, sp, fade_in=.7)
                            self.cash -= 20


            # Check to see if we click on a filter.
            f = self.collide_objects((x,y), self.world.filters)
            if f:
                f = f[0]

                if self.hud_popup.is_active and self.selected_filter:
                    self.selected_filter.blue = 1

                self.hud_popup.is_active = True
                self.hud_popup.y = rabbyt.lerp(end=0, dt=.5)
                f.blue = 0
                self.selected_filter = f
                c = str(f.connection.match_color)
                ConnectionOption.selected_color = self.hud_options_color[c]

                fig = f.connection.match_figure
                ConnectionOption.selected_shape =\
                        self.hud_options_shape[str(fig)]

        else:
            if self.selected:
                self.selected = None
            else:
                self.set_mode(None)
            if self.hud_popup.is_active:
                self.hud_popup.is_active = False
                self.hud_popup.y = rabbyt.lerp(end=-174,
                    dt=.5)
                self.selected_filter.blue = 1

    def check_interfering_cables(self, a, b):
        """
        This function checks to see if a cable can be built from a to b
        without interfering with any other cables.

        A list of interfering cables is returned.
        """
        # Check to make sure they aren't already connected:
        for c in a.connections:
            if b is c.opposite_station:
                return [c.cable]

        # Check for intersections:
        bounds = rabbyt.Quad((min(a.x, b.x), max(a.y, b.y), 
                    max(a.x, b.x), min(a.y, b.y)))
        interfering = []
        cables = set(self.world.cables)
        cables.difference_update(
                set([c.cable for c in a.connections + b.connections]))
        for cable in rabbyt.collisions.aabb_collide_single(bounds, cables):
            if line_intersect(a.xy, b.xy, 
                    cable.endpoints[0].xy, cable.endpoints[1].xy):
                interfering.append(cable)
        interfering.extend(self.check_interfering_angles(a, b.xy))
        interfering.extend(self.check_interfering_angles(b, a.xy))
        return interfering
    def check_interfering_cables_xy(self, a, xy):
        """
        Returns a list of cables that conflict with building a cable from
        a to xy.

        A list of interfering cables is returned.
        """
        x,y =xy
        # Check for intersections:
        bounds = rabbyt.Quad((min(a.x, x), max(a.y, y), 
                    max(a.x, x), min(a.y, y)))
        interfering = []
        cables = set(self.world.cables)
        cables.difference_update(set([c.cable for c in a.connections]))
        for cable in rabbyt.collisions.aabb_collide_single(bounds, cables):
            if line_intersect(a.xy, xy, 
                    cable.endpoints[0].xy, cable.endpoints[1].xy):
                interfering.append(cable)

        interfering.extend(self.check_interfering_angles(a, xy))
        return interfering

    def check_interfering_angles(self, station, xy):
        angle = math.degrees(math.atan2(xy[1]-station.y, xy[0]-station.x)) % 360
        interfering = []
        min_angle = 30
        for c in station.connections:
            diff = abs(c.angle_d-angle)
            if min_angle > diff or (360-min_angle) < diff:
                interfering.append(c.cable)
        return interfering


    def collide_objects(self, xy, objects):
        x,y = xy
        return rabbyt.collisions.aabb_collide_single(
                rabbyt.Quad((x,y,x,y)), objects)

    def zoom_in(self):
        if self.zoom_index == 0:
            return False
        self.zoom_index -= 1
        z = self.zoom_levels[self.zoom_index]
        self.view.zoom = rabbyt.ease(start=self.view.zoom,
                end=z, dt=0.5)
        return True

    def zoom_out(self):
        if self.zoom_index == len(self.zoom_levels)-1:
            return
        self.zoom_index += 1
        z = self.zoom_levels[self.zoom_index]
        self.view.zoom = rabbyt.ease(start=self.view.zoom,
                end=z, dt=0.5)

    def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
        if scroll_y > 0:
            if self.zoom_in():
                x,y = self.view.to_world_pixels((x,y))
                self.center_on = (int(x),int(y))
        else:
            self.zoom_out()
            self.center_on = None

    def handle_key_press(self, symbol, *args):
        if symbol == key.ESCAPE:
            self.ingame_menu.open()
        elif symbol == key.B:
            self.set_mode("build")
        elif symbol == key.F:
            self.window.set_fullscreen(not self.window.fullscreen)
        elif symbol == key.P:
            from gamelib.main import profiler
            profiler.enabled = not profiler.enabled
        elif symbol == key.MINUS:
            self.zoom_out()
        elif symbol == key.PLUS or symbol == key.EQUAL:
            self.zoom_in()


def line_intersect(p1, p2, p3, p4):
    # I'm sure there's a better way to do this, but this was the first thing
    # I could come up with...
    if (p2[0] - p1[0]) == 0:
        p1 = p1[0]+.1, p1[1]
    if (p4[0] - p3[0]) == 0:
        p3 = p3[0]+.1, p3[1]
    m1 = (p2[1] - p1[1])/(p2[0] - p1[0])
    m2 = (p4[1] - p3[1])/(p4[0] - p3[0])
    b1 = p1[1] - m1*p1[0]
    b2 = p3[1] - m2*p3[0]

    if m1 == m2:
        # Lines are parallel 
        return False

    x = (b2 - b1)/(m1-m2)

    if (p1[0] < x < p2[0] or p2[0] < x < p1[0]) and \
            (p3[0] < x < p4[0] or p4[0] < x < p3[0]):
        return True
    else:
        return False


class IngameHud(snowui.Widget):
    def __init__(self, ui):
        self.ui = ui
        snowui.Widget.__init__(self, texture="hud2.png",
                bounds="rect", x=0, y=0)

    def setup(self):
        # Setup speed control
        speed_button = snowui.widget_setting(snowui.Button, bounds="rect",
                callback=self.ui.set_game_speed)
        self.speed_buttons = [
            speed_button(texture="b_pause.png", x=75+220, y=10, cb_data=0),
            speed_button(texture="b_play.png", x=220, y=10, cb_data=1),
            speed_button(texture="b_fast.png", x=40+220, y=10, cb_data=2)
        ]
        for b in self.speed_buttons:
            self.add(b)
        self.ui.set_game_speed(1)

        # Ingame menu button
        self.add(snowui.Button(texture="b_menu.png", x=330, y=4,
                bounds="rect",  callback=self.ui.ingame_menu.open))

        # Game actions (Build etc)
        self.build_button = snowui.Button(texture="b_build.png", x=40, y=30,
                bounds="rect", callback=self.ui.set_mode, cb_data="build")
        self.add(self.build_button)
