import random

from pygsear.Event import TIMEOUT_Event, EventGroup
from pygsear import conf

import Creature
import Target

class Level:
    def __init__(self):
        self.targets = conf.game.addGroup()
        self.events = EventGroup()
        start_spawning = TIMEOUT_Event(self.target_spawn_rate, callback=self.spawn)

        game = conf.game
        game.events.add(start_spawning)
        self.events.add(start_spawning)

    def make_target(self, ev=None):
        game = conf.game

        target = self.target_type(**self.target_kwargs)
        target.lifetime = random.normalvariate(self.target_lifetime, self.target_lifetime_sigma)
        target_death = TIMEOUT_Event(target.lifetime, callback=target.die)
        game.events.add(target_death)
        self.events.add(target_death)
        self.targets.add(target)

        target.set_positionRandom()
        while target.collidelist(conf.game.sprites.sprites()):
            target.set_positionRandom()
        game.sprites.add(target)

        target.is_good_target = getattr(target, self.good_target_check)

    def spawn(self, ev=None):
        self.make_target()

        game = conf.game

        t = random.normalvariate(self.target_spawn_rate, self.target_spawn_rate_sigma)
        next_spawn = TIMEOUT_Event(t, callback=self.spawn)
        game.events.add(next_spawn)
        self.events.add(next_spawn)


class Level_01(Level):
    def __init__(self):
        self.instructions = """Find Even Numbers"""

        self.bgimagetile = 'level1.png'

        self.creature_type = Creature.Blob

        self.target_type = Target.Number_Target
        self.target_kwargs = {}
        self.ntargets = 10
        self.good_target_check = 'is_even'
        self.target_lifetime = 20000
        self.target_lifetime_sigma = 10000
        self.target_spawn_rate = 6700
        self.target_spawn_rate_sigma = 3000

        self.next_level_score = 20

        Level.__init__(self)

    def good_target_callback(self):
        conf.game.score.addPoints(10)

    def bad_target_callback(self):
        conf.game.score.addPoints(-5)


class Level_02(Level):
    def __init__(self):
        self.instructions = """Find Odd Numbers"""

        self.bgimagetile = 'level0.png'

        self.creature_type = Creature.Egg

        self.target_type = Target.Number_Target
        self.target_kwargs = {}
        self.ntargets = 10
        self.good_target_check = 'is_odd'
        self.target_lifetime = 20000
        self.target_lifetime_sigma = 10000
        self.target_spawn_rate = 600
        self.target_spawn_rate_sigma = 30

        self.next_level_score = 50

        Level.__init__(self)

    def good_target_callback(self):
        conf.game.score.addPoints(10)

    def bad_target_callback(self):
        conf.game.score.addPoints(-5)


class Level_03(Level):
    def __init__(self):
        self.instructions = """Find Odd Numbers"""

        self.bgimagetile = 'level0.png'

        self.creature_type = Creature.Egg

        self.target_type = Target.Number_Target
        self.target_kwargs = {'minimum': 1, 'maximum': 20}
        self.ntargets = 10
        self.good_target_check = 'is_odd'
        self.target_lifetime = 20000
        self.target_lifetime_sigma = 10000
        self.target_spawn_rate = 600
        self.target_spawn_rate_sigma = 30

        self.next_level_score = 500

        Level.__init__(self)

    def good_target_callback(self):
        conf.game.score.addPoints(10)

    def bad_target_callback(self):
        conf.game.score.addPoints(-5)


class PosZeroNeg(Level):
    def __init__(self, screen, level=0):
        Level.__init__(self)
        Target.Phrase.instances.empty()
        self.makeTargets(self.nTargets)

        if level==0:
            self.instructions = [
                "The object is to",
                "find ten negative numbers",
                "Positive numbers cause the",
                "snake to grow longer!"
            ]
            self.kinds = 'pos-zero-neg'
            self.hitActions = {
                'neg':  [(self.changeScore, 1)],
                'zero': [(self.changeScore, 0)],
                'pos': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets=5
            self.minNumber=-9
            self.maxNumber=9
            self.fontSize=50
        if level==1:
            self.instructions = [
                "The object is to",
                "find ten positive numbers",
                "Negative numbers cause the",
                "snake to grow longer!"
            ]
            self.kinds = 'pos-zero-neg'
            self.hitActions = {
                'pos':  [(self.changeScore, 1)],
                'zero': [(self.changeScore, 0)],
                'neg': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets=10
            self.minNumber=-29
            self.maxNumber=19
            self.fontSize=50
        if level==2:
            self.instructions = [
                "The object is to",
                "find ten positive numbers",
                "Negative numbers cause the",
                "snake to grow longer!"
            ]
            self.kinds = 'pos-zero-neg'
            self.hitActions = {
                'pos':  [(self.changeScore, 1)],
                'zero': [(self.changeScore, 0)],
                'neg': [(self.snake.changeLength, 10), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets=30
            self.minNumber=-29
            self.maxNumber=19
            self.fontSize=25

    def makeTargets(self, nTargets=0):
        hitActions = {
            'neg':  [(self.changeScore, 1)],
            'zero': [(self.changeScore, 0)],
            'pos': [(self.snake.changeLength, 5)]
        }
        for t in range(nTargets):
            number = Target.Phrase(minVal=self.minNumber, maxVal=self.maxNumber, fontSize=self.fontSize)
            number.setKinds(self.kinds)
            number.hitActions = self.hitActions[number.kind]
            number.placeRandomly()
            self.targets.add(number)

class Phrases(Level):
    def __init__(self, screen, level=0):
        Game.__init__(self, screen, level)
        Target.Phrase.instances.empty()
        self.setLevel(level)
        self.setBackground()
        self.makeTargets(self.nTargets)

        if level==0:
            self.instructions = [
                "The object is to",
                "find 10 even numbers.",
                "Odd numbers make",
                "the snake grow longer!"
            ]
            self.kinds = 'odd-even'
            self.hitActions = {
                'even': [(self.changeScore, 1)],
                'odd': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets = 5
            self.minTerms = 1
            self.maxTerms = 1
            self.opTypes = ['+']
            self.fontSize = 50
            self.minVal = 1
            self.maxVal = 9
        if level==1:
            self.instructions = [
                "The object is to",
                "find 10 even totals.",
                "Phrases with an odd total",
                "make the snake grow longer!"
            ]
            self.kinds = 'odd-even'
            self.hitActions = {
                'even': [(self.changeScore, 1)],
                'odd': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets = 8
            self.minTerms = 2
            self.maxTerms = 2
            self.opTypes = ['+']
            self.fontSize = 50
            self.minVal = 1
            self.maxVal = 9
        if level==2:
            self.instructions = [
                "The object is to",
                "find 10 even totals",
                "Phrases with an odd total",
                "make the snake grow longer!"
            ]
            self.kinds = 'odd-even'
            self.hitActions = {
                'even': [(self.changeScore, 1)], 
                'odd': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets = 8
            self.minTerms = 2
            self.maxTerms = 2
            self.opTypes = ['+', 'x']
            self.fontSize = 50
            self.minVal = 1
            self.maxVal = 12

    def makeTargets(self, nTargets=1):
        for t in range(nTargets):
            ph = Target.Phrase(
                minTerms = self.minTerms,
                maxTerms=self.maxTerms,
                opTypes=self.opTypes,
                minVal=self.minVal,
                maxVal=self.maxVal,
                fontSize=self.fontSize
            ) 
            ph.setKinds(self.kinds)
            ph.hitActions = self.hitActions[ph.kind]
            ph.placeRandomly()
            self.targets.add(ph)        

class Shapes(Level):
    def __init__(self, screen, level=0):
        Game.__init__(self, screen, level)
        self.setLevel(level)
        self.setBackground()
        self.makeTargets(self.nTargets)

        if level==0:
            self.instructions = [
                "The object is to",
                "find 10 squares.",
                "Rectangles make",
                "the snake grows longer!"
            ]
            self.kinds = 'rectangle-square'
            self.colors = [WHITE]
            self.hitActions = {
                'square': [(self.changeScore, 1)],
                'rectangle': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')  ]
            }
            self.nTargets = 5
            self.minSize = 30
            self.maxSize = 70
        if level==1:
            self.instructions = [
                "The object is to",
                "find 10 squares.",
                "Rectangles make",
                "the snake grows longer!"
            ]
            self.kinds = 'rectangle-square'
            self.colors = [WHITE, BLUE]
            self.hitActions = {
                'square': [(self.changeScore, 1)],
                'rectangle': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets = 10
            self.minSize = 20
            self.maxSize = 50
        if level==2:
            self.instructions = [
                "The object is to",
                "find 10 squares.",
                "Rectangles make",
                "the snake grows longer!"
            ]
            self.kinds = 'rectangle-square'
            self.colors = [WHITE, BLUE, RED, YELLOW, GREEN]
            self.hitActions = {
                'square': [(self.changeScore, 1)],
                'rectangle': [(self.snake.changeLength, 5), (self.snake.changeImages, 'mistake')]
            }
            self.nTargets = 15
            self.minSize = 5
            self.maxSize = 40

    def makeTargets(self, nTargets=1):
        shapeTypes = {'square':Target.Square, 'rectangle':Target.Rectangle}
        for t in range(nTargets):
            kind = random.choice(('rectangle', 'square'))
            color = random.choice(self.colors)
            sh = shapeTypes[kind](
                minSize=self.minSize,
                maxSize=self.maxSize,
                color=color 
            )
            sh.hitActions = self.hitActions[kind]
            sh.placeRandomly()
            self.targets.add(sh)        
