import math

from siege import game
from siege.graphic import Renderable, TextureCache
from siege.sfml import Sprite
from siege.util import PixelRect, Sizes, Vector
from siege.world import World


class UndergroundRenderable(Renderable):
    IMAGE_SIZE = 200

    def __init__(self):
        Renderable.__init__(self)
        self.sprites = []
        texture = TextureCache.get("underground/dirt.png").get()
        for y in xrange(2):
            sprite = Sprite(texture)
            sprite.setTextureRect(PixelRect(0, self.IMAGE_SIZE * y, self.IMAGE_SIZE, self.IMAGE_SIZE).toSfml())
            self.sprites.append(sprite)

    def render(self, target):
        #Determine if the player can even see the underground
        viewport = self.getViewport()
        startDepth = World.get().getRealm().groundLevel * Sizes.TILE
        if viewport.y + viewport.height < startDepth:
            #Underground is not on screen at all
            return

        #We want it to scroll correctly so we need to consistently place the tiles
        start = Vector(int(math.floor(viewport.x / self.IMAGE_SIZE) * self.IMAGE_SIZE), startDepth)
        if viewport.y > startDepth:
            #We are below the starting depth - Fill the entire screen
            start.y = startDepth + int(math.floor((viewport.y - startDepth) / self.IMAGE_SIZE) * self.IMAGE_SIZE)
        height = min(int(math.ceil((viewport.y + viewport.height - startDepth) / self.IMAGE_SIZE)), int(math.ceil(viewport.height / self.IMAGE_SIZE)))
        for y in xrange(height):
            for x in xrange(int(math.ceil(viewport.width / self.IMAGE_SIZE) + 1)):
                #TODO: Come up with a way to consistently draw different sprites
                sprite = self.sprites[0]
                sprite.setPosition(Vector(start.x + x * self.IMAGE_SIZE, start.y + y * self.IMAGE_SIZE).toSfml())
                target.draw(sprite)

    @staticmethod
    def handleWorldLoaded(world):
        underground = UndergroundRenderable()
        game.render.addRenderable(underground, 350)
        game.events['camera_moved'].listen(underground.updateView)
        game.events['camera_centered'].listen(underground.setViewCenter)
