"Initialize the Missions module"

from __future__ import generators
import plus
import math
import string
import random
import Levels

missions = []
currentMission = None

class SuperMission(plus.Mission):
    "Python base class of the C++ Mission."
    name = "No Name"
    level_name = "No Level"
    preview = "No Preview"
    equipcost = 0
    pay = 0
    perfectspeed = 0
    worstspeed = 0
    
    easy_speedfail = 0
    easy_safetyfail = 0
    easy_accuracyfail = 0
    easy_default = 0
    med_speedfail = 0
    med_safetyfail = 0
    med_accuracyfail = 0
    med_default = 0
    med_bonus = 0
    hard_speedfail = 0
    hard_safetyfail = 0
    hard_accuracyfail = 0
    hard_default = 0
    hard_bonus = 0
    
    missionNumber = -1
    training = -1
    accuracy_type = 0
    safety_type = 0
    
    def __init__(self, levelIndex):
        plus.Mission.__init__(self)
        
        self.level = Levels.currentLevels[levelIndex]
        Levels.setLevel(self.level, True)
        plus.setStartPoint(self.level.startpoint)
        plus.setStartRotation(self.level.startrotation)
        
        self.Intro = None
        self.bDoingIntro = False
        self.introPause = 0
        self.voiceovers = {}
        self.trainingScrewups = ("Sounds/Voiceovers/SupervisorComments/TrainingScrewup1/TrainingScrewup1-1.wav", "Sounds/Voiceovers/SupervisorComments/TrainingScrewup1/TrainingScrewup1-2.wav")
        self.curVoice = None
        self.screwupTime = 0
        
        self.objectives = ()
        
    def __del__(self):
        if self.curVoice:
            plus.stopSound(self.curVoice)
            plus.removeSound(self.curVoice)

    def Tick(self):
        if self.bDoingIntro:
            self.introPause -= self.tickInterval
            if self.introPause <= 0:
                self.introPause = self.Intro.next()
                if self.introPause == 0:
                    self.DoIntro(False)
                    
        if self.screwupTime > 0:
            self.screwupTime -= .25
                    
        return plus.Mission.Tick(self)

    def DoIntro(self, on):
        if on:
            self.Intro = self.Introduction()
            self.bDoingIntro = True
        else:
            self.bDoingIntro = False
            
            self.Intro = None
            plus.introComplete()
            self.IntroComplete()
            
    def SwitchedVehicles(self, iVehicle):
        return None
        
    def SwitchedTools(self, iVehicle):
        return None

    def Introduction(self):
        "Default introduction waits one second, then goes."
        yield 1
        yield 0

    def IntroComplete(self):
        if not self.curVoice == None:
            plus.stopSound(self.curVoice)
            plus.removeSound(self.curVoice)
        plus.blackOut(False)
        plus.showObjective()
        
    def Screwup(self):
        plus.playSoundOnce(random.choice(self.trainingScrewups))
        
def sortByName(x, y):
    if x.name < y.name:
        return -1
    elif x.name > y.name:
        return 1
    else:
        return 0

def register(mission):
    "Called by derived Missions to keep a master list of available mission types."
    if issubclass(mission, SuperMission):
        extant = [x for x in missions if x.name == mission.name]
        if len(extant) == 0:
            missions.append(mission)

            print "We now have", len(missions), "missions!"

def enumAvailable():
    "Return a list of available missions via the C++ enumMission function."
    list = [x for x in missions]
    list.sort(sortByName)
    for each in list:
        md = plus.MissionDetail()
        md.name = each.name
        md.level_name = each.level_name
        md.description = each.__doc__
        md.preview = each.preview
        md.equipcost = each.equipcost
        md.pay = each.pay
        md.missionNumber = each.missionNumber
        md.training = each.training
        md.accuracy_type = each.accuracy_type
        md.safety_type = each.safety_type
        md.id = id(each)
        md.perfectspeed = each.perfectspeed
        md.worstspeed = each.worstspeed
        
        md.easy_speedfail = each.easy_speedfail
        md.easy_safetyfail = each.easy_safetyfail
        md.easy_accuracyfail = each.easy_accuracyfail
        md.easy_default = each.easy_default
        md.med_speedfail = each.med_speedfail
        md.med_safetyfail = each.med_safetyfail
        md.med_accuracyfail = each.med_accuracyfail
        md.med_default = each.med_default
        md.med_bonus = each.med_bonus
        md.hard_speedfail = each.hard_speedfail
        md.hard_safetyfail = each.hard_safetyfail
        md.hard_accuracyfail = each.hard_accuracyfail
        md.hard_default = each.hard_default
        md.hard_bonus = each.hard_bonus
        
        plus.enumMission(md)

def createMission(idnumber):
    "Call C++ setMission for the mission entry with this id."
    list = [x for x in missions if id(x) == idnumber]
    if len(list) > 0:
        print "Creating mission", list[0].name
        
        # make sure the correct level is loaded
        index = Levels.createLevelByName(list[0].level_name)        
        
        global currentMission
        newMission = list[0](index)
        currentMission = newMission
        plus.setMission(newMission)
        plus.setObjectives(newMission.objectives)
        
def createMissionByName(name):
    "Call C++ setMission for the mission entry with this name."
    list = [x for x in missions if x.name == name]
    if len(list) > 0:
        print "Creating mission", list[0].name
        
        index = Levels.createLevelByName(list[0].level_name)
        
        global currentMission
        newMission = list[0](index)
        currentMission = newMission
        plus.setMission(newMission)
        plus.setObjectives(newMission.objectives)

def clearMission():
    global currentMission
    currentMission = None
    