from functools import partial
import math

from core.terraform.helper import plantOrganicAction
from core.terraform.stamps import createStampColor, loadStamps

from siege import game
from siege.util import Random, RangeUint, TileRect, Vector
from siege.worldgen import Biome, FillMode, Terraform
from siege.world.realm import Layer, TilePosition


class DesertBiome(Biome):
    def __init__(self):
        Biome.__init__(self)
        self.name = "Desert"
        self.layer = "surface"
        self.frequency = 10
        self.width = RangeUint(5, 10)
        self.height = RangeUint(30, 60)
        self.heightTolerance = 3
        self.widthIncrement = 32
        self.groundId = game.content.get('dirt').id
        self.wallId = self.groundId
        self.sky = 'mods/core/environment/sky.png'
        self.back1.images.append('mods/core/environment/desert/back1.png')
        self.back1.offset = -100
        self.back1.scroll = Vector(0.5, 0.1)
        self.back2.images.append('mods/core/environment/desert/back2.png')
        self.back2.offset = -175
        self.back2.scroll = Vector(0.3, 0.075)
        self.back3.images.append('mods/core/environment/desert/back3.png')
        self.back3.offset = -250
        self.back3.scroll = Vector(0.1, 0.05)

    def getOccurrences(self, realmSize):
        return RangeUint(1, max(2, realmSize.width / 1536))

    def isCompatible(self, biome):
        return biome.name is not "Mountain"

    def getStamps(self, remainingSpace):
        return loadStamps('deserts')

    def getRules(self):
        tileRules = {}
        sandId = game.content.get('sand').id
        tileRules[createStampColor(155, 128, 94)] = (sandId, 0)
        tileRules[createStampColor(125, 100, 67)] = (0, sandId)
        tileRules[createStampColor(145, 108, 59)] = (sandId, sandId)
        tileRules[createStampColor(80, 60, 40)] = (self.groundId, self.wallId)
        return tileRules

    def getActions(self, biomeData):
        return [self.placeSand]

    def getPostActions(self, biomeData):
        postActions = []
        postActions.append(partial(plantOrganicAction, 'cactus_tree', Layer.Back, (10, 12), True, False))
        postActions.append(partial(plantOrganicAction, 'prickly_pear_plant', Layer.Item, (7, 11), True, False))
        # postActions.append(partial(placeOnSurfaceAction, 'scrub_brush', (12, 20)))
        return postActions

    def placeSand(self, area, ratio, game, world, realm, data):
        # Take the center point of the desert and set a min and max depth that will be turned to sand
        #Min and max will decrease as it moves away from the center
        #Replace the backwall with sand as well
        #Think about what will happen if the sand fills and the space is empty beneath it
        groundLayer = realm.layers[Layer.Ground]
        wallLayer = realm.layers[Layer.Wall]
        sandId = game.content.get('sand').id
        for x in xrange(0, area.width):
            depth = int(round(math.sin(math.pi * x / area.width) * Random.get(30, 45) + 1))
            y = 0
            while wallLayer.isEmpty(TilePosition(area.x + x, area.y + y, realm.size)) and y < area.height:
                y += 1
            finalArea = TileRect(area.x + x, area.y + y, 1, depth)
            Terraform.fillTiles(groundLayer, finalArea, sandId, FillMode.ALL)
            Terraform.fillTiles(wallLayer, finalArea, sandId, FillMode.ALL)
