from go_somewhere_significant import go_somewhere_significant
from Vector import *
import vsrandom
import universe
import launch
import faction_ships
import Director
import unit
import quest
import VS
import go_to_adjacent_systems
import go_somewhere_significant
import math


CARGOS = ['Pets','Artwork','Construction', "Software", "Liquor", "Furs", "Grain", "Generic_Foods",
          'Advanced_Fuels','Communications','Computers','Factory_Equipment', "Iron", "Movies",
          'Holographics','Home_Appliances','Medical_Equipment', 'Books',
          'Pre_Fabs','Plastics','Robot_Workers','Textiles', "Luxury_Foods",
          'Mining_Equipment','Food_Dispensers', "PlayThing_(tm)", "Weaponry",
          'Home_Entertainment','Tungsten','Wood', "Space_Salvage", "Space_Salvage", "Space_Salvage"]


class rescue (Director.Mission):

    def __init__ (self, creds, numsysaway, fac, numenemy, enfac, enfg = '', jumps = (), var_when_done = '', betweenNavpoints = [], pilotDeliveryPath = []):
        Director.Mission.__init__ (self)
        self.arrived = 0
        self.faction = fac
        self.enfaction = enfac
        self.enflightgroup = enfg
        self.cred = creds
        self.donevar = var_when_done
        self.you = VS.getPlayer()
        self.mplay = universe.getMessagePlayer( self.you)
        self.adjsys = go_to_adjacent_systems.go_to_adjacent_systems( self.you, numsysaway, jumps)
        self.numenemy = numenemy
        self.eject = None
        self.enemy = None
        self.enemySpawned = False
        self.numejectors = 0
        self.obj = 0
        self.beaconObj = 0
        self.maxBeaconRange = 15500
        self.willSpawnEnemy = vsrandom.random() < .8
        self.enemySpawnRange = 0
        self.enemyChasePilot = vsrandom.random() > .8
        self.greetTime = 10000000
	self.enemyGreetTime = 10000000
        self.betweenNavpoints = betweenNavpoints
        self.spawnSpot = (0,0,0)
        self.radarRange = faction_ships.calcRadarRange( self.you)
        self.nextSignalTime = 0
        self.pilotDeliveryPath = pilotDeliveryPath
        
    def spawnEnemies( self):
        L = launch.Launch()
        L.fg = "Shadow"
        L.faction = self.enfaction
        L.dynfg = self.enflightgroup
        L.type = faction_ships.getRandomFighter( self.enfaction)
        L.ai = "default"
        L.num = self.numenemy
        L.minradius = self.radarRange - 300
        L.maxradius = self.radarRange - 100
        self.enemy = L.launch(self.you)
        self.enemy.SetTarget(self.you)
        self.enemy.setFgDirective( "A.")

        
    def spawnPilot( self):
        self.eject = launch.launch_wave_around_area( "Pilot", self.faction, "eject", "printhello.py", 1, 10, 20, self.spawnSpot)
        self.eject.setMissionRelevant()
        self.eject.setName( "Pilot")
        self.eject.setFullname( "Pilot")
        vsrandom.randrange( 15, 35)
        #self.eject.SetPosition( VS.SafeEntrancePoint( self.spawnSpot, self.eject.rSize()))
        self.you.SetTarget( self.eject)
        self.greetTime = VS.GetGameTime() + 6
    
    
    def spawnCargo( self):
        numcargos = vsrandom.randrange( 2, 4)
        for i in range( numcargos):
            L = launch.Launch()
            L.fg = "Remnants"
            L.faction = "upgrades"
            L.type = CARGOS[ vsrandom.randrange( 0, len( CARGOS))]
            L.num = 1
            L.minradius = 100
            L.maxradius = 150
            L.ai = 'default'
            remnant = L.launch( self.eject)
            #remnant.SetMass( 4)
            remnant.SetHull( 5)
    
    
    def updateBeaconObjective( self):
        if not self.beaconObj:
            return
        ejectPosition = self.spawnSpot
        if self.eject:
            ejectPosition = self.eject.Position()
        distanceToSpawnSpot = calcDistance( self.you.Position(), ejectPosition)
        signalStrength = (self.maxBeaconRange - distanceToSpawnSpot) / self.maxBeaconRange
        if signalStrength < 0.01:
            signalStrength = 0
        signalStrength *= signalStrength        # b/c non-linear dependency
        bstr = ""
        stime = VS.GetGameTime() - self.nextSignalTime
        if signalStrength >= 0.01 and stime >= 0:
            bstr = ")"
            if stime > 0.3: bstr += ")"
            if stime > 0.6: bstr += ")"
            if stime > 0.99: bstr = ""
        if stime >= 0 and stime < 1.5:
            VS.setObjective( self.beaconObj, "Signal strength: " + str( int( 100*signalStrength)) + "% " + bstr)
            VS.setCompleteness( self.beaconObj, -signalStrength/2)
        if stime > 4:
            self.nextSignalTime = VS.GetGameTime() + 4
    
        
    def Execute(self):
        if (not self.you):
            VS.terminateMission(0)
            return
        if (not self.adjsys.Execute()):
            return
        
        if (self.arrived == 0):
            sys = VS.getSystemFile()
            import dynamic_battle
            if sys in dynamic_battle.rescuelist:
                del dynamic_battle.rescuelist[sys]
            
            self.arrived = 1

            np1 = universe.findUnit( self.betweenNavpoints[0])
            np1pos = np1.Position()
            if len( self.betweenNavpoints) == 2:
                np2 = universe.findUnit( self.betweenNavpoints[1])
                np2pos = np2.Position()
                print "PODXX between np1: " + unit.getUnitFullName( np1) + ", np2: " + unit.getUnitFullName( np2) + ", distance: " + str( calcDistance( np1pos, np2pos))
                self.spawnSpot = randomizeSpotBetween( np1pos, np2pos)
                self.obj = VS.addObjective( "Search between " + unit.getUnitFullName( np1) + " and " + unit.getUnitFullName( np2))
            else:
                print "PODXX around np1: " + unit.getUnitFullName( np1)
                self.spawnSpot = randomizeSpotAround( np1pos, 5000, 15000)
                self.obj = VS.addObjective( "Search around " + unit.getUnitFullName( np1))
                self.beaconObj = VS.addObjective( "Signal strength: 0%")
                self.nextSignalTime = VS.GetGameTime() + 4
                
            self.enemySpawnRange = .5 * calcDistance( self.you.Position(), self.spawnSpot)
            self.enemySpawnRange = vsrandom.randrange( 500, int( self.enemySpawnRange))
            print "PODXX spawnSpot: " + str( self.spawnSpot) + ", distance from np1: " + str( calcDistance( np1pos, self.spawnSpot)) + ", erange: " + str(self.enemySpawnRange)

        elif (self.arrived == 1):
            # waiting till spawn spot is in range
            distanceToSpawnSpot = calcDistance( self.you.Position(), self.spawnSpot)
            
            self.updateBeaconObjective()
                
            if distanceToSpawnSpot < self.radarRange - 100:
                self.spawnPilot()
                if self.faction == "merchant" and vsrandom.random() < .33:
                    self.spawnCargo()
                self.arrived = 2
                VS.setObjective( self.obj, "Tractor ejected pilot")
            
            if self.willSpawnEnemy and (not self.enemySpawned) and distanceToSpawnSpot <= self.enemySpawnRange:
                splittableQuantity = 2
                if self.enfaction == "kilrathi":
                    splittableQuantity = 1
                if distanceToSpawnSpot > 2600 and self.numenemy >= splittableQuantity and vsrandom.random() < .5:
                    self.numenemy -= 1
                    self.spawnEnemies()
                    self.numenemy = 1
                    self.enemySpawnRange = vsrandom.randrange( 650, 1300)
                else:
                    self.spawnEnemies()
                    self.enemySpawned = True
                self.enemyGreetTime = VS.GetGameTime() + 10
            if self.enemy and VS.GetGameTime() >= self.enemyGreetTime:
                universe.greet( universe.getRandomGreeting( self.enfaction), self.enemy, self.you)
                self.enemyGreetTime = 10000000
                
        elif (self.arrived == 2):
            self.updateBeaconObjective()
            
            if self.willSpawnEnemy and (not self.enemySpawned) and calcDistance( self.you.Position(), self.spawnSpot) <= self.enemySpawnRange:
                self.spawnEnemies()
                self.enemySpawned = True
            if self.enemy and VS.GetGameTime() >= self.enemyGreetTime:
                universe.greet( universe.getRandomGreeting( self.enfaction), self.enemy, self.you)
                self.enemyGreetTime = 10000000
                
            if ( self.eject ):
                if VS.GetGameTime() >= self.greetTime:
                    universe.greet( universe.getRandomGreeting( "common"), self.eject, self.you);
                    self.greetTime = 10000000
                if self.enemy and self.enemyChasePilot:
                    self.enemy.SetTarget( self.eject)
                    self.enemy.setFgDirective( "A.")
                self.numejectors = self.you.GetCargo( "Pilot").GetQuantity()
            else:
                if ( self.enemy ):
                    self.enemy.SetTarget( self.you)
                    self.enemy.setFgDirective( "A.")
                if ( self.numejectors < self.you.GetCargo( "Pilot").GetQuantity() ):
                    self.you.removeCargo( "Pilot", 1, 1)
                    carg = VS.Cargo( "Rescued pilot", "Rescued pilot", 1, 1, 0.01, 1.0)
                    carg.SetMissionFlag( 1)
                    VS.setCompleteness( self.obj, 1)
                    if self.beaconObj:
                        VS.eraseObjective( self.beaconObj)
                        self.beaconObj = 0
                    if (not self.you.addCargo( carg)):
                        print 'failed to add cargo: ' + str(carg.GetContent()) + ', consider mission success'
                        self.Win( self.you,1)
                    else:
                        self.arrived = 3
                        self.cargname = carg.GetContent()
                        if len( self.pilotDeliveryPath):
                            self.adjsys = go_to_adjacent_systems.go_to_adjacent_systems( self.you, 0, self.pilotDeliveryPath)
                else:
                    print "rescue mission failed"
                    self.Lose( 1)
        elif (self.arrived == 3):
            self.arrived = 4
            #self.adjsys = go_somewhere_significant.go_somewhere_significant( self.you, 1, 2500)
            self.adjsys = go_somewhere_significant.go_somewhere_significant( self.you, 1, 2500, 0, '', '', 0)
            VS.addObjective( "Take pilot to " + unit.getUnitFullName( self.adjsys.SignificantUnit(), True))
        elif (self.arrived==4):
            if (self.you.GetCargo( self.cargname).GetQuantity() == 0):
                self.Lose( 1)
            elif (self.adjsys.SignificantUnit().isDocked( self.you) or self.you.isDocked( self.adjsys.SignificantUnit()) or self.adjsys.SignificantUnit().getDistance( self.you)<15):
                if (self.you.removeCargo( self.cargname, 1, 1)):
                    self.Win( self.you, 1)
                else:
                    self.Lose( 1)
    def Win (self,un,terminate):
        un.addCredits( self.cred)
        VS.AdjustRelation( self.you.getFactionName(), self.faction, .02, 1)
        if len( self.donevar):
            quest.removeQuest( self.you.isPlayerStarship(), self.donevar, 1)
        if (terminate):
            VS.terminateMission(1)

    def Lose ( self, terminate):
        VS.AdjustRelation( self.you.getFactionName(), self.faction, -.02, 1)
        if len( self.donevar):
            quest.removeQuest( int( self.mplay[1:]), self.donevar, -1)
        if (terminate):
            VS.terminateMission(0)
    def initbriefing(self):
        print "ending briefing"
    def loopbriefing(self):
        print "loop briefing"
        Briefing.terminate();

    def endbriefing(self):
        print "ending briefing"
