###########################################################
# HeadsUpDisplay - Railshooter Module
# Loads the HUD using the Direct GUI
###########################################################

# DESCRIPTION:
# This Class uses Panda's Direct GUI to create a Heads Up Display (HUD).
# The Heads Up Display includes all the 2d menu items, life-meters, and 
# score counters.  Also, the Direct GUI is used to create a fader object
# to allow for screen flashing.  This Class does not include the Splash 
# Screen and the Opening Menu (these are contained in the StartMenu Class).

# The Chatbox and Commander Avatar code is contained in the HUDavatar 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 HUDavatar
import Level1
import LoadTextures


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

	########################################
	# Initialize Variables
	########################################
	
	# Keeps Track of Movie Bars for Realtime Cinematics
 	self.isMovieBarOn = 1

	# Create Sceen Fader Label Object
	# This object changes colors to create the Screen Fading and
	# Flashing Effects
	self.fader = DirectLabel(text='     ', text_bg = (0, 0, 0, 1), text_scale=(5, 5))
	self.fader.setPos(0, 100, 0)
	self.fader.setTransparency(1)

	# List that Holds the Lifebar Labels and Make the Lifebar
	self.lifeBar = {}
	self.maxLifeBar = ClassGlobals.p1.health/2
	self.currentLifeBar = self.maxLifeBar

	# Load the Red Bar Texture
	self.redBar = loader.loadTexture('Textures/lifebarRed.png')


    ########################################
    # Main HUD Methods
    ########################################

    # Create the Game's Heads Up Display
    def createHUD(self):

	# Create Lifebar
	self.createLifebar(-1.0, 0.87, self.lifeBar, self.maxLifeBar)

	# Create Score Display
        self.statusBar = DirectLabel(relief = None, image='Textures/HUDlevel.png', scale=(0.3, 1.0, 0.15))
        self.statusBar.setPos(0.8, 0, 0.81)
	self.statusBar.setTransparency(1)

        self.scoreBar = DirectLabel(text = str(ClassGlobals.p1.score), text_scale=(0.07, 0.07), text_fg = (1, 1, 1, 1), relief = None)
        self.scoreBar.setPos(0.82, 0, 0.84)

	# Hide the HUD
	self.hideHUD()
	

	# Create Movie Bars
	self.createMovieBars()
	self.toggleMovieBars()

	# Load Level Name Label
	self.level1name = DirectLabel(text='Infinitron Metropolis', text_fg = (1, 1, 1, 0), relief = None, text_scale=(0.1, 0.1))
	self.level1name.setPos(-0.6, 1, 0.7)
	self.level1name.setTransparency(1)
	self.level1name.hide()


	# Load GameOver Label
	self.gameOver = DirectLabel(image='Textures/GameOver.png', relief = None, scale=1.2)
	self.gameOver.setPos(0, 0, -0.03)
	self.gameOver.setTransparency(1)
	self.gameOver.hide()

	# Load Final Score Label
	self.gameScore = DirectLabel(text='Final Score: ' + str(ClassGlobals.p1.score), text_fg=(1, 1, 0.5, 1), relief = None, text_scale=(0.1, 0.1))
	self.gameScore.setPos(0, 0, 0.0)
	self.gameScore.setTransparency(1)
	self.gameScore.hide()

	# Load the Continue Label
	self.continueButton = DirectButton(text = "Continue?", command = self.continueGame, scale = (0.09, 0.09, 0.09), relief = None)
	self.continueButton.setTransparency(1)
	self.continueButton.setPos(0, 0, -0.2)
	self.continueButton.hide()

	# Add Task to Update the HUD Status
        taskMgr.add(self.updateHUD, 'HUDtask')

	# Avatar Message Box
	self.chatBox1 = HUDavatar.HUDavatar()


    # Update the Information in the Heads Up Display over time
    def updateHUD(self, task):
        self.scoreBar['text'] = str(ClassGlobals.p1.score)
        return Task.cont


    # Hide the Game's Heads Up Display
    def hideHUD(self):
	self.healthBar.hide()
        self.statusBar.hide()
	self.scoreBar.hide()
	for i in range(self.maxLifeBar):
	    self.lifeBar[i].hide()

    # Show the Game's Heads Up Display
    def showHUD(self):
	self.healthBar.show()
        self.statusBar.show()
	self.scoreBar.show()
	for i in range(self.maxLifeBar):
	    self.lifeBar[i].show()


    ########################################
    # Movie Bar Methods
    ########################################

    # Create the HUD MovieBars
    def createMovieBars(self):
	# Create Movie Bars
	self.topBar = DirectLabel(text='     ', text_bg = (0, 0, 0, 1), text_scale=(3, 3))
	self.topBar.setPos(0, 0, 1.94)

	self.bottomBar = DirectLabel(text='     ', text_bg = (0, 0, 0, 1), text_scale=(3, 3))
	self.bottomBar.setPos(0, 0, -4.615)


    # Toggle Movie Bars On and Off
    def toggleMovieBars(self):
	if self.isMovieBarOn == 1:
	
	    # Set Movie Bar Variable Off
	    self.isMovieBarOn = 0
		
	    # Create Intervals to Move the Movie Bars
	    open1 = self.topBar.posInterval(3, 
	    		Point3(0, 0, 2.19), 
	    		startPos=Point3(0, 0, 1.94))
    	    open1.start()

	    open2 = self.bottomBar.posInterval(3, 
	    		Point3(0, 0, -4.86), 
	    		startPos=Point3(0, 0, -4.615))
    	    open2.start()
	else:
	    # Set Movie Bar Variable On
	    self.isMovieBarOn = 1
		
	    # Create Intervals to Move the Movie Bars
	    open3 = self.topBar.posInterval(1, 
	    		Point3(0, 0, 1.94), 
	    		startPos=Point3(0, 0, 2.19))
    	    open3.start()

	    open4 = self.bottomBar.posInterval(1, 
	    		Point3(0, 0, -4.615), 
	    		startPos=Point3(0, 0, -4.86))
    	    open4.start()


    ########################################
    # Lifebar Methods
    ########################################

    # Create the Lifebar Objects
    def createLifebar(self, x, y, lifeBar, stat):

	# Create as many Lifebar Pieces as is in Stat 
	for i in range(stat):
	    # Load New Lifebar Piece
            bar = DirectLabel(image='Textures/lifebar.png')
	    bar.setScale(0.016, 0.04, 0.045)

	    # Position New Health Bar piece
	    newX = x+(0.0217*(i))
	    bar.setPos(newX, 0, y)

	    # Add to List of Life Bar Pieces
	    lifeBar[i] = bar

	# Creates the Health Text Label
        self.healthBar = DirectLabel(relief = None, scale=(0.6, 1.0, 0.15), image='Textures/HUDlifemeter.png')
	self.healthBar.setPos(x+0.5, 0, y-0.038)
	self.healthBar.setTransparency(1)


    # Reset Life Bar
    def resetLifebar(self):

	# Reset Lifebar Amount
	self.currentLifeBar = self.maxLifeBar

	for i in range(self.maxLifeBar):
	    self.lifeBar[i].setTextureOff()
	    self.lifeBar[i].setColor(1, 1, 1, 1)


    # Update Lifebar
    def damageLifebar(self, lifeBar, amount):

	# Hide Life Bar Pieces from End to represent Damage
	for i in range(amount):
	    if self.currentLifeBar-i-1 >= 0:

		# Load Red Bar Texture
	        lifeBar[self.currentLifeBar-i-1].setTexture(self.redBar, 1)

		# Do Color Fading Effect
		redOut = lifeBar[self.currentLifeBar-i-1].colorInterval(2, Vec4(0, 0, 0, 1), startColor=Vec4(1, 1, 1, 1), blendType = 'easeOut')
		redOut.start()

	# Reduce Lifebar Counter
	self.currentLifeBar -= amount


    ########################################
    # Screen Color Flashing/Fading Methods
    ########################################

    # Flash to Color
    def flash(self, fadeSpeed, r, g, b, a):

	# Create Flash Intervals
	faderOut = self.fader.colorInterval(fadeSpeed, 
				Vec4(r, g, b, a), 
				startColor=Vec4(r, g, b, 0))

 	faderIn = self.fader.colorInterval(fadeSpeed, 
				Vec4(r, g, b, 0), 
				startColor=Vec4(r, g, b, a))

	# Sequence to Play the Flash
	flash = Sequence(faderOut,
			faderIn)

	# Do not do this if Game Over sign is up
	if ClassGlobals.gameIsOver == 0:
	    flash.start()

    # Fade-Out to Color
    def fadeOut(self, fadeSpeed, r, g, b, a):
 	faderInt = self.fader.colorInterval(fadeSpeed, 
				Vec4(r, g, b, a), 
				startColor=Vec4(r, g, b, 0))
	faderInt.start()

    # Fade-In to Color
    def fadeIn(self, fadeSpeed, r, g, b, a):
 	faderInt = self.fader.colorInterval(fadeSpeed, 
				Vec4(r, g, b, 0), 
				startColor=Vec4(r, g, b, a))
	faderInt.start()


    ########################################
    # Intro Screen Methods
    ########################################

    # Prints the name of the Level
    def showLevelName(self):

	# Cause Name to Fade in and Stay for 1 Second before fading out
 	nameFade1 = self.level1name.colorInterval(2, 
				Vec4(1, 1, 1, 1), 
				startColor=Vec4(0, 0, 0, 0))
 	nameFade2 = self.level1name.colorInterval(1, 
				Vec4(0, 0, 0, 0), 
				startColor=Vec4(1, 1, 1, 1))

	introNameSeq = Sequence(Wait(1.0),
				Func(self.level1name.show),
				nameFade1,
				Wait(1.0),
				nameFade2)
	introNameSeq.start()


    ########################################
    # Game Over Screen Methods
    ########################################

    # Prints Game Over on Screen
    def showGameOver(self):

        # Do not do this if game already ended
	if ClassGlobals.gameIsOver == 0:
	
	    # Mark Game as Over
	    ClassGlobals.gameIsOver = 1

	    # Deactivate Mouse
	    if ClassGlobals.mouseIsEnabled == 1:
	    	ClassGlobals.mouseIsEnabled = 0
	    	ClassGlobals.mouser.stopMouse()

	    # Hide the HUD
	    self.hideHUD()

	    # Disable Lazy Camera and Begin Tracking the Player
	    ClassGlobals.lazyCamera1.toggleLazyCam()
	    camera.reparentTo(Level1.railDummy)
	    ClassGlobals.lazyCamera1.togglePlayerTracking()

	    # If Player Won the Game, change text to say Congratulations
	    if ClassGlobals.p1.isAlive == 1:
                self.gameOver.setTexture(LoadTextures.winMap, 1)
                # Remove Move Player Task
                taskMgr.remove('moveP1')


	    # Update Score Value for Label
	    self.gameScore['text'] = 'Final Score: ' + str(ClassGlobals.p1.score)

	    # Fade in GameOver
 	    deathFadeInt = self.fader.colorInterval(5, 
				Vec4(0, 0, 0, 1), 
				startColor=Vec4(0, 0, 0, 0))
	
 	    gameOverFadeIn = self.gameOver.colorInterval(1, 
				Vec4(1, 1, 1, 1), 
				startColor=Vec4(0, 0, 0, 0))

 	    gameOverScoreFadeIn = self.gameScore.colorInterval(1, 
				Vec4(1, 1, 1, 1), 
				startColor=Vec4(0, 0, 0, 0))

 	    continueFadeIn = self.continueButton.colorInterval(1, 
				Vec4(1, 1, 1, 1), 
				startColor=Vec4(0, 0, 0, 0))


	    gameOverSeq = Sequence(Func(ClassGlobals.hud1.toggleMovieBars),
				deathFadeInt,
				Func(ClassGlobals.hud1.toggleMovieBars),
				Func(self.gameOver.show),
				gameOverFadeIn,
				Func(self.gameScore.show),
				gameOverScoreFadeIn,
				Func(self.continueButton.show),
				continueFadeIn,
				Func(ClassGlobals.stage1.endLevel),
				)
	    gameOverSeq.start()


    # Hide the Game Over Screen
    def hideGameOver(self):
	self.gameOver.hide()
        self.gameScore.hide()
	self.continueButton.hide()


    # Runs the Game Again
    def continueGame(self):

	# Broadcast the Continue Game Message
	# This is Accepted in Railshooter.py
	messenger.send('continue')
