"""
Hardpoint
thepolm3
Idea by Kamikaze_Blargle

for map extensions;
"hardpoint":[(x,y),(x,y),(x,y)]

you can do
"hardpoint":[(x,y,z),(x,y,z),(x,y,z)]
"""

from twisted.internet.task import LoopingCall
from twisted.internet.reactor import seconds,callLater
from pyspades.constants import *
from pyspades.server import Territory

HARDCORE = False #all bullets are lethal
ANNOY = 6 #times
LIFETIME = 60 #seconds
HIDE_POS = (0,0,63)

def apply_script(protocol, connection, config):

    class HardTerritory(Territory):
        def add_player(self, player):
            if self.id==self.protocol.capturing_entity:
                Territory.add_player(self,player)


    class HardConnection(connection):

        def on_hit(self,damage,player,value,type):
            if player and player!=self and HARDCORE: return 100
            else: return connection.on_hit(self,damage,player,value,type)
            
        def on_command(self,command,parameters):

            if command=="time":
                i=self.protocol.capturing_entity
                self.send_chat("If they hold it for %d seconds, they win!" %(self.protocol.end-seconds()))
                self.send_chat("%s holds the %dth cp!" %(self.protocol.entities[i].team.name,i))
                return False
            return connection.on_command(self,command,parameters)
            
    class HardProtocol(protocol):
        telling=None
        end=None
        capturing_entity=0
        game_mode = TC_MODE

        def get_cp_entities(self):
            entities=[]
            if not self.telling:
                self.telling=LoopingCall(self.tell_time)
                self.telling.start(LIFETIME/ANNOY)
            self.end=None
            extensions=self.map_info.extensions
            if extensions.has_key("hardpoint"):
                positions=extensions["hardpoint"]
                for pos in positions:
                    if len(pos)>2: x,y,z=pos
                    else:
                        x,y=pos
                        z=self.map.get_z(x,y)
                    entity=HardTerritory(0,self,*HIDE_POS)
                    entity.team=None
                    entity.callbackpos=(x,y,z)
                    entities.append(entity)
                entities[0].x,entities[0].y,entities[0].z=entities[0].callbackpos
                return entities
            oldentities = protocol.get_cp_entities(self)
            for entity in oldentities:
                newentity=HardTerritory(0,self,*HIDE_POS)
                newentity.callbackpos=entity.x,entity.y,entity.z
                newentity.team=None
                entities.append(newentity)
            entities[0].x,entities[0].y,entities[0].z=entities[0].callbackpos
            return entities

        def tell_time(self):
            if 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 next_cp(self):
            if self.end and self.end-seconds()<5:
                if self.capturing_entity>=len(self.entities):
                    score=0
                    for entity in entities:
                        if entity.team==self.blue_team:score+=1
                        else:score-=1
                    if score>0:self.entities[0].team=self.blue_team
                    elif score<0:self.entities[0].team=self.green_team
                    elif score==0:self.entities[0].team=None
                    self.reset_game(None,self.entities[0],True)
                    protocol.on_game_end(self)
                else:
                    entity=self.entities[self.capturing_entity]
                    entity.x,entity.y,entity.z=HIDE_POS
                    entity.update()
                    self.capturing_entity+=1
                    entity=self.entities[self.capturing_entity]
                    entity.x,entity.y,entity.z=entity.callbackpos
                    entity.update()
                    self.send_chat("%s has captured a control point!" %(self.entities[self.capturing_entity].team.name))

        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):
            if cp.id==self.capturing_entity:
                self.end=LIFETIME+seconds()
                team=cp.team.name
                callLater(LIFETIME,self.next_cp)
                self.send_chat("If they hold it for %d seconds!" %(self.end-seconds()))
                self.send_chat("%s has captured a control point" %(team))
                protocol.on_cp_capture(self,cp)

    return HardProtocol, HardConnection
