###########################################################
# HUD Avatar - Railshooter Module
# Creates the Animated Portrait of the Commander
###########################################################

# DESCRIPTION:
# This Class uses Panda's Direct GUI to create a 2d animated talking
# commander using the Heads Up Display (HUD).  The commander's dialogue
# gives hints and tips on how to play the game.  She also explains some
# of the story events that occur.  This class is an example of how to 
# use animated 2d images in the HUD as well as text that types out slowly
# over time.

# The rest of the HUD is covered by the HeadsUpDisplay class.


from direct.showbase.ShowBaseGlobal import *
from direct.interval.IntervalGlobal import *
from direct.gui.DirectGui import *
from direct.showbase import DirectObject
from direct.task import Task
from pandac.PandaModules import *

# Import Railshooter Modules
import ClassGlobals
import LoadTextures


########################################
# HUD Avatar Class
########################################
class HUDavatar(DirectObject.DirectObject):
    def __init__(self):   

	########################################
	# Initialize Variables
	########################################

	# Typing Speed
	self.typingSpeed = 0.015
	self.currentDialogue = ' '
	self.dialogueChoice = ' '
	self.dialogueDisplayTime = 3.0
	self.currentChar = 0
	self.timeOffset = 0
	self.endTransmissionTimer = 0
	self.endTime = 0

	# Commander Portrait Avatar Animation Variables
	self.blinkRate = 0.5 
	self.talkRate = 5
	self.blinkCloseRate = 90
	self.blinkOpenRate = 5
	self.animationCounter = 0
	self.mouthIsOpen = 0
	self.eyesAreOpen = 0

	# Holds the chat box text in order of occurence
	self.dialogue = {}
	self.dialogue[0] = 'Edge, the power core of the city is 100,000 meters to the North.'
	self.dialogue[1] = 'Incoming hostile units straight ahead.'
	self.dialogue[2] = 'Shoot down enemy projectiles with your rapid-fire blaster!'
	self.dialogue[3] = 'Hold down the fire button to Lock-On enemies with your Homing Laser!'
	self.dialogue[4] = 'Incoming Homing Missiles!  Shoot them down!'
	self.dialogue[5] = 'Get the blue power capsule!'
	self.dialogue[6] = 'Edge, you are half way to the core of the city.'
	self.dialogue[7] = 'Edge, you are nearing the core of the city.  Please be careful.'


	########################################
	# Create the Chatbox GUI Labels
	########################################

	# Chat Box Label Object
	self.chatBox = DirectLabel(image='Textures/chatBox.png', scale=(1.6, 0, 0.2), relief = None)
	self.chatBox.setPos(0, 0, -0.8)
	self.chatBox.setTransparency(1)

	# Holds the Name of the Speaker
	self.nameDisplay = DirectLabel(text='Commander:', text_fg = (1, 1, 1, 1), text_pos=(-0.94, 0), text_scale=(0.09, 0.09), relief = None, text_align=TextNode.ALeft, text_shadow=(0, 0, 0, 1))
	self.nameDisplay.setPos(0.2, 0, -0.73)

	# Holds the Text that gets Displayed in the ChatBox
	self.textDisplay = DirectLabel(text=' ', text_fg = (1, 1, 1, 1), text_pos=(-0.94, 0), text_scale=(0.085, 0.085), relief = None, text_align=TextNode.ALeft, text_shadow=(0, 0, 0, 1), text_wordwrap=20)
	self.textDisplay.setPos(0.2, 0, -0.83)

	# Create Commander's Portrait
	self.portrait = DirectLabel(image='Textures/CommanderSide1.png', scale=(0.2, 0.2, 0.2), relief = None)
	self.portrait.setPos(-1.0, 0, -0.8)

	# Hide Everything
	self.hideChatbox()


    	########################################
    	# Run the Typing Task
    	########################################

	# Does the Typing Effect of the Chatbox Dialogue
	taskMgr.add(self.typeDialogue, 'typeDialogue')


    ########################################
    # Main Chatbox Tasks
    ########################################

    # Type the Dialogue in the Heads Up Display over time
    def typeDialogue(self, task):

	# Update New Time
	self.currentTime = task.time - self.timeOffset

	# Update the End Transmission Timer
	if self.endTransmissionTimer > 0:
	    self.endTime = task.time - self.endTransmissionTimer

	# If ready for the next character, add it to dialogue string
	if self.currentTime >= self.typingSpeed:

	    # If there is still Dialogue
	    if self.currentChar < len(self.dialogueChoice):
	
	        # Add a new character
	        self.currentChar += 1	

	        # Get next Character in Dialogue String
	        self.currentDialogue = self.dialogueChoice[0:self.currentChar]

	        # Update HUD Chatbox with new String
                self.textDisplay['text'] = self.currentDialogue

	        # Incriment Animation Counter
	        self.animationCounter += 1

	        # When Correct Amount of Letters Pass, change Animation Frame
	        if self.animationCounter >= self.talkRate:

	            # Change Portrait for Talk Animation
	            self.commanderTalk()
		    self.animationCounter = 0

	        # Reset Timer back to Zero by updating the Time Offset
	        self.timeOffset = task.time
		

	    # If dialogue just ended
	    elif self.currentChar == len(self.dialogueChoice):

	        # Add a new character
	        self.currentChar += 1	

	        # Get next Character in Dialogue String
	        self.currentDialogue = self.dialogueChoice[0:self.currentChar]

	        # Update HUD Chatbox with new String
                self.textDisplay['text'] = self.currentDialogue

	        # Incriment Animation Counter
	        self.animationCounter += 1

		# Make Sure Mouth is Closed
		if self.mouthIsOpen == 1:
	    	    # Go to Closed Mouth Picture
	    	    self.mouthIsOpen = 0
	    	    self.portrait.setTexture(LoadTextures.commanderSide2, 1)
		    self.animationCounter = 0

	        # Reset Timer back to Zero by updating the Time Offset
	        self.timeOffset = task.time
		
		# Set End Time Offset to End the Task after a delay
		self.endTransmissionTimer = task.time
		

	    # If there is no dialogue left, just idle the commander till
	    # the message transmission ends
  	    else:

	        # Incriment Animation Counter
	        self.animationCounter += 1

	        # When Correct Amount of Letters Pass, change Animation Frame
	        if self.animationCounter >= self.blinkOpenRate and self.eyesAreOpen == 1:
	            # Change Portrait for Talk Animation
	            self.commanderIdle()
		    self.animationCounter = 0

		elif self.animationCounter >= self.blinkCloseRate and self.eyesAreOpen == 0:
	            # Change Portrait for Talk Animation
	            self.commanderIdle()
		    self.animationCounter = 0

	        # Reset Timer back to Zero by updating the Time Offset
	        self.timeOffset = task.time


	# Ends the Transmission after a delay once done Typing Message
	if self.endTime > self.dialogueDisplayTime:
	    self.endTransmission()
        return Task.cont


    ########################################
    # Main Chatbox Methods
    ########################################

    # Does Talking Animation for the Commander
    def commanderTalk(self):

	# If Mouth is Open
	if self.mouthIsOpen == 1:
	    # Go to Closed Mouth Picture
	    self.mouthIsOpen = 0
	    self.portrait.setTexture(LoadTextures.commanderSide2, 1)

	else:
	    # Go to Open Mouth Picture
	    self.mouthIsOpen = 1
	    self.portrait.setTexture(LoadTextures.commanderSide1, 1)


    # Does Idle Animation for the Commander
    def commanderIdle(self):

	# If Eyes are Open
	if self.eyesAreOpen == 1:
	    # Close Eyes
	    self.eyesAreOpen = 0
	    self.portrait.setTexture(LoadTextures.commanderSide2, 1)

	else:
	    # Open Eyes
	    self.eyesAreOpen = 1
	    self.portrait.setTexture(LoadTextures.commanderSide3, 1)


    # Ends a Message Transmission
    def startTransmission(self, choice):

	# Get next Character in Dialogue String
	self.dialogueChoice = self.dialogue[choice]

	# Show Chatbox
	self.showChatbox()

	# Reset Timer back to Zero by updating the Time Offset
	self.timeOffset = 0
	self.endTransmissionTimer = 0
	self.animationCounter = 0
	self.currentDialogue = ' '
        self.currentChar = 0	
	self.endTime = 0

	# Play Transmission-Out Animation
	# self.chatBoxIn.start()


    # Ends a Message Transmission
    def endTransmission(self):

	# Get next Character in Dialogue String
	self.currentDialogue = " "

	# Update HUD Chatbox with new String
        self.textDisplay['text'] = self.currentDialogue

	# Reset Timer back to Zero by updating the Time Offset
	self.timeOffset = 0
	self.endTransmissionTimer = 0
	self.animationCounter = 0
	self.currentDialogue = ' '
        self.currentChar = 0	
	self.endTime = 0

	# Play Transmission-Out Animation
	# self.chatBoxOut.start()

	# Hide Chatbox
	self.hideChatbox()


    # Hide the Chatbox
    def hideChatbox(self):
	self.chatBox.hide()
        self.textDisplay.hide()
	self.portrait.hide()
	self.nameDisplay.hide()

    # Show the Chatbox
    def showChatbox(self):
	self.chatBox.show()
        self.textDisplay.show()
	self.portrait.show()
	self.nameDisplay.show()
