"""
King of the hill ^^
thepolm3

feel free to set the base position via map extensions using
"KOTH":(x,y)
or
"KOTH":(x,y,z)
and then
"spawn_radius":(min,max)
"""

from twisted.internet.task import LoopingCall
from twisted.internet.reactor import seconds,callLater
from pyspades.constants import *
from pyspades.server import Territory
from random import randint

ANNOY = 6 #times
HOLD_HILL_FOR = 90 #seconds
SPAWN_RADIUS = (70,100) #between these away from the tent
DEFAULT_KOTH = (256,256)

def apply_script(protocol, connection, config):
    class KOTHConnection(connection):

        def get_respawn_time(self):
            if self.team!=self.protocol.entities[0].team: return connection.get_respawn_time(self)/2
            return connection.get_respawn_time(self)

        def on_spawn_location(self,pos):
            e=self.protocol.entities[0]
            xa,ya,za,z,count=e.x,e.y,e.z,64,0
            while z>=63 and count<100:
                x,y=[randint(*SPAWN_RADIUS),randint(0,SPAWN_RADIUS[1])]
                if randint(0,1): y,x=x,y
                x*=(randint(1,2)*2)-3
                y*=(randint(1,2)*2)-3
                x,y=x+xa,y+ya
                print(x,y)
                count+=1
                z=self.protocol.map.get_z(x,y)
            return (x,y,z)

        def on_command(self,command,parameters):

            if command=="time":
                self.send_chat("If they hold it for %d seconds, they win!" %(self.protocol.end-seconds()))
                self.send_chat("%s holds the hill" %(self.protocol.entities[0].team.name))
                return False
            return connection.on_command(self,command,parameters)
            
    class KOTHProtocol(protocol):

        telling=None
        end=None
        game_mode = TC_MODE

        def get_cp_entities(self):
            global SPAWN_RADIUS
            if not self.telling:
                self.telling=LoopingCall(self.tell_time)
                self.telling.start(HOLD_HILL_FOR/ANNOY)
            self.end=None
            #gets the coords
            extensions=self.map_info.extensions
            KOTH=DEFAULT_KOTH
            if extensions.has_key("KOTH"):
                KOTH=extensions["KOTH"]
            if extensions.has_key("spawn_radius"):
                KOTH=extensions["spawn_radius"]

            #makes it allow a z if it wants
            if len(KOTH)>2: x,y,z=KOTH
            else:
                x,y=KOTH
                z=self.map.get_z(x,y)

            #create territory
            entity=Territory(0,self,x,y,z)
            entity.team=None

            #y'all just got RETURNED
            return [entity]
        def hill_is_held(self):
            if self.entities:
                for player in self.entities[0].players:
                    if player.team==self.entities[0].team:
                        return True
                return False

        def tell_time(self):
            valid = self.hill_is_held()
            if not valid and self.end:
                self.end+=HOLD_HILL_FOR/ANNOY
                self.send_chat("If they capture it again, they have %ds left!" %(self.end-seconds()))
                self.send_chat("%s has abandoned the hill!" %(self.entities[0].team.name))
            if valid and self.end and self.end-seconds()>0:
                self.send_chat("If they hold it for %d seconds, they win!" %(self.end-seconds()))
                self.send_chat("%s holds the hill" %(self.entities[0].team.name))

        def win(self):
            if self.end and self.end-seconds()<5:
                self.reset_game(None,self.entities[0],True)
                protocol.on_game_end(self)

        def reset_game(self, player = None, territory = None, ovverule=False):
            if ovverule:
                return protocol.reset_game(self, player, territory)
            elif territory:
                territory.update()

        def on_game_end(self):
            return
            
        def on_cp_capture(self,cp):
            #this must be our only cp
            self.end=HOLD_HILL_FOR+seconds()
            team=cp.team.name
            callLater(HOLD_HILL_FOR,self.win)
            self.send_chat("If they hold it for %d seconds, they win!" %(self.end-seconds()))
            self.send_chat("%s has captured the hill" %(team))
            protocol.on_cp_capture(self,cp)

    return KOTHProtocol, KOTHConnection
