import math

from siege import game
from siege.graphic import Color, Renderable, TextureCache
from siege.sfml import Sprite
from siege.util import Vector
from siege.world import World, WorldTime


class SkyRenderable(Renderable):
    def __init__(self):
        Renderable.__init__(self)
        world = World.get()
        world.time.minutes.onChange.listen(self.handleTimeChange)
        self.stars = Sprite(TextureCache.getAbsolute("mods/core/environment/stars.png").get())
        self.sun = Sprite(TextureCache.getAbsolute("mods/core/environment/sun.png").get())
        self.sun.setColor(Color(255, 255, 255, 180))
        self.moon = Sprite(TextureCache.getAbsolute("mods/core/environment/moon.png").get())
        self.starsAlpha = [255, 255, 255, 200, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 200, 255, 255, 255]
        self.currentHour = world.time.hours.get()
        self.handleTimeChange(self.currentHour - 1, self.currentHour)

    def handleTimeChange(self, previous, current):
        world = World.get()
        self.currentHour = world.time.hours.get()
        nextHour = 0 if self.currentHour == 23 else self.currentHour + 1
        start = self.starsAlpha[self.currentHour]
        finish = self.starsAlpha[nextHour]
        starsColor = self.stars.getColor()
        starsColor.a = int(start + (finish - start) * (float(current) / world.time.MINUTES_IN_HOUR))
        self.stars.setColor(starsColor)

    def render(self, target):
        target.draw(self.stars)
        if self.currentHour >= 3 and self.currentHour <= 20:
            #Draw the sun - Noon (12) it should be exactly in the center
            self.sun.setPosition(self.determinePosition(3, self.currentHour, 18).toSfml())
            target.draw(self.sun)
        if self.currentHour <= 4 or self.currentHour >= 19:
            #Draw the moon - Midnight (0) it should be exactly in the center
            hour = self.currentHour
            if hour < 12:
                hour += 24
            hour -= 19
            self.moon.setPosition(self.determinePosition(0, hour, 10).toSfml())
            target.draw(self.moon)
        #TODO: Draw clouds

    def determinePosition(self, start, time, duration):
        world = World.get()
        start *= WorldTime.MINUTES_IN_HOUR * WorldTime.TIME_IN_MINUTE
        time = (time * WorldTime.MINUTES_IN_HOUR + world.time.minutes.get()) * WorldTime.TIME_IN_MINUTE + world.time.seconds
        duration *= WorldTime.MINUTES_IN_HOUR * WorldTime.TIME_IN_MINUTE
        progress = float(time - start) / duration
        math.sin(progress * math.pi)
        position = Vector(0, 0)
        center = self.view.getCenter()
        position.x = progress * 1800 - 900 + center.x
        position.y = center.y + 100 - math.sin(progress * math.pi) * 600
        return position

    @staticmethod
    def handleWorldLoaded(world):
        game.render.addRenderable(SkyRenderable(), 50)
