import direct.directbase.DirectStart
from direct.showbase import DirectObject
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from direct.gui.DirectGui import *
from direct.task import Task 
import VRHandler
import sys
#from direct.gui.OnscreenText import OnscreenText 

class World(DirectObject):

  def __init__(self):
  
    base.disableMouse()
 
    camera.setPos ( 0, 0, 12 )          
    camera.setHpr ( 0, -90, 0 )

    self.x5 = randFloat(-3, 3)
    self.y5 = randFloat(-3, 3)

    self.flash = loader.loadModel("models/flash.egg")
    self.flash.setPos(0, 0, 9)
    self.flash.setHpr(0, -90, 0)

    self.tracker = VRHandler.VRHandler("imve13", render, "Tracker0")
    taskMgr.add(self.updatePaddleFromTracker,"updatePaddleFromTrackerTask")
    
    self.collHandler = CollisionHandlerEvent()
    self.collHandler.addInPattern("%fn-into-%in")
    self.cTrav = CollisionTraverser()
    base.cTrav = self.cTrav
    
    self.loadPlanets()

    self.music = loader.loadSfx("sounds/ingame_loop.ogg")
    self.music.setLoop(True)
    self.music.play()
    self.gameover = loader.loadSfx("sounds/death.ogg")

    self.explosion = loader.loadSfx("sounds/explosion.ogg")
    self.camera = loader.loadSfx("sounds/camera.wav")
    

    
    self.x = 0
    self.y = 0
    self.mouseSpeed = 5
    self.hits = 0
    self.score = 0

    self.showFlash = Func(self.showFlashFunc)
    self.hideFlash = Func(self.hideFlashFunc)

    if base.mouseWatcherNode.hasMouse():
      self.x=base.mouseWatcherNode.getMouseX()	
      self.y=base.mouseWatcherNode.getMouseY()

    taskMgr.add(self.mousecheck, "mouse")
    taskMgr.add(self.flycheck, "fly")

    self.bla = OnscreenText("Hits: "+str(self.hits), style=1, fg=(1,1,1,1), pos=(0.9,-0.95), scale = .07)
    self.showscore = OnscreenText("Score: "+str(self.score), style=1, fg=(1,1,1,1), pos=(0.9,-0.85), scale = .07)

  def showFlashFunc(self):
    self.flash.reparentTo(render)

  def hideFlashFunc(self):
    self.flash.detachNode()

  def loadPlanets(self):
    self.objects = []

    #self.sky = loader.loadModel("models/solar_sky_sphere")
    #self.sky.reparentTo(render)
    #self.sky.setScale(100)
    #self.sky_tex = loader.loadTexture("models/g04.jpg")
    #self.sky.setTexture(self.sky_tex, 1)

    myFog = Fog("Fog Name")
    myFog.setColor(.1, .3, .4)
    myFog.setExpDensity(.02)
    render.setFog(myFog)
    base.setBackgroundColor(.1, .3, .4)

    self.molecule1 = loader.loadModel('models/helium')
    self.molecule1.reparentTo(render)
    #self.molecule1_tex = loader.loadTexture('models/dna.bonds.jpg')
    #self.molecule1.setTexture(self.molecule1_tex, 1)
    self.molecule1.setHpr ( 0, -40, 90 )

    cNode = CollisionNode('molecule1')
    cNode.addSolid(CollisionSphere(0,0,0,1.05))
    self.molecule1C = self.molecule1.attachNewNode(cNode)
    #self.molecule1C.show()

    self.molecule2 = loader.loadModel('models/helium')
    self.molecule2.reparentTo(render)
    #self.molecule2_tex = loader.loadTexture('models/dna_cpk_lg.jpg')
    #self.molecule2.setTexture(self.molecule2_tex, 1)
    self.molecule2.setHpr ( 0, 0, 90 )
    self.molecule2.setPos (-2, 2, 0)
    self.molecule2.setScale(1.5)

    cNode2 = CollisionNode('molecule1')
    cNode2.addSolid(CollisionSphere(0,0,0,0.8))
    self.molecule2C = self.molecule2.attachNewNode(cNode2)
    #self.molecule1C.show()

    self.molecule3 = loader.loadModelCopy("models/helium")
    #self.molecule3_tex = loader.loadTexture("models/25.jpg")
    #self.molecule3.setTexture(self.molecule3_tex, 1)
    self.molecule3.reparentTo(render)
    self.molecule3.setPos (3, 0, 0)
    self.molecule3.setHpr ( 0, -90, 0 )
    self.molecule3.setScale(0.5)

    cNode3 = CollisionNode('molecule1')
    cNode3.addSolid(CollisionSphere(0,0,0,.5))
    self.molecule3C = self.molecule3.attachNewNode(cNode3)
    #self.molecule1C.show()


    self.molecule4 = loader.loadModelCopy("models/helium")
    #self.molecule4_tex = loader.loadTexture("models/24.jpg")
    #self.molecule4.setTexture(self.molecule4_tex, 1)
    self.molecule4.reparentTo(render)
    self.molecule4.setPos (-3, 0, 0)
    self.molecule4.setHpr ( 0, 0, 90)
    self.molecule4.setScale(0.3)

    cNode4 = CollisionNode('molecule1')
    cNode4.addSolid(CollisionSphere(0,0,0,.3))
    self.molecule4C = self.molecule4.attachNewNode(cNode4)
    #self.molecule1C.show()
    
    self.molecule6 = loader.loadModel('models/helium')
    self.molecule6.reparentTo(render)
    self.molecule6.setHpr ( 0, -40, 90 )

    cNode6 = CollisionNode('molecule1')
    cNode6.addSolid(CollisionSphere(0,0,0,1.05))
    self.molecule6C = self.molecule6.attachNewNode(cNode6)
    #self.molecule1C.show()

    self.molecule7 = loader.loadModel('models/helium')
    self.molecule7.reparentTo(render)
    self.molecule7.setHpr ( 0, 0, 90 )
    self.molecule7.setPos (-2, 2, 0)
    self.molecule7.setScale(1.5)

    cNode7 = CollisionNode('molecule1')
    cNode7.addSolid(CollisionSphere(0,0,0,1.5))
    self.molecule7C = self.molecule7.attachNewNode(cNode7)
    #self.molecule1C.show()

    self.molecule8 = loader.loadModelCopy("models/helium.egg")
    self.molecule8.reparentTo(render)
    self.molecule8.setPos (3, 0, 0)
    self.molecule8.setHpr ( 0, -90, 0 )
    self.molecule8.setScale(0.5)

    cNode8 = CollisionNode('molecule1')
    cNode8.addSolid(CollisionSphere(0,0,0,.5))
    self.molecule8C = self.molecule8.attachNewNode(cNode3)
    #self.molecule1C.show()


    self.molecule9 = loader.loadModelCopy("models/helium.egg")
    self.molecule9.reparentTo(render)
    self.molecule9.setPos (-3, 0, 0)
    self.molecule9.setHpr ( 0, 0, 90)
    self.molecule9.setScale(0.3)

    cNode9 = CollisionNode('molecule1')
    cNode9.addSolid(CollisionSphere(0,0,0,.3))
    self.molecule9C = self.molecule9.attachNewNode(cNode9)
    #self.molecule1C.show()


    #-------fotografiermolekül-----------
    self.molecule5 = loader.loadModel("models/planet_sphere")
    #self.molecule5_tex = loader.loadTexture("models/24.jpg")
    #self.molecule5.setTexture(self.molecule4_tex, 1)
    self.molecule5.setColor(1, 0, 0, 1)
    self.molecule5.reparentTo(render)
    self.molecule5.setHpr ( 0, 0, 90)
    self.molecule5.setScale(0.5)

    cNode5 = CollisionNode('molecule1')
    cNode5.addSolid(CollisionSphere(0,0,0,.5))
    self.molecule5C = self.molecule5.attachNewNode(cNode5)
    #self.molecule1C.show()

    self.molecule5Fly = LerpPosInterval(self.molecule5, randFloat(10, 20), Vec3(self.x5, self.y5, 200), 
    Vec3(self.x5, self.y5, -100))
    self.molecule5Fly.start()

    self.x1 = randFloat(-8, 8)
    self.y1 = randFloat(-8, 8)
      
    self.molecule1Fly = LerpPosHprInterval(self.molecule1, randFloat(5, 10), Vec3(self.x1, self.y1, 15), 
Vec3(180,0,0), Vec3(self.x1, self.y1, -100), Vec3(0,-90,180))
    self.molecule1Fly.start()

    
    self.x2 = randFloat(-8, 8)
    self.y2 = randFloat(-8, 8)

    self.molecule2Fly = LerpPosHprInterval(self.molecule2, randFloat(5, 10), Vec3(self.x2, self.y2, 15), Vec3(0, 0, 90),
      Vec3(self.x2, self.y2, -100), Vec3(360,0,0))
    self.molecule2Fly.start()

    
    self.x3 = randFloat(-8, 8)
    self.y3 = randFloat(-8, 8)

    self.molecule3Fly = LerpPosHprInterval(self.molecule3, randFloat(5, 10), Vec3(self.x3, self.y3, 15), Vec3(0, 0, 10),
      Vec3(self.x3, self.y3, -100), Vec3(360,0,0))
    self.molecule3Fly.start()

    
    self.x4 = randFloat(-8, 8)
    self.y4 = randFloat(-8, 8)

    self.molecule4Fly = LerpPosHprInterval(self.molecule4, randFloat(5, 10), Vec3(self.x4, self.y4, 15), Vec3(0, 0, 10),
      Vec3(self.x4, self.y4, -100), Vec3(360,0,0))
    self.molecule4Fly.start()

    self.x6 = randFloat(-8, 8)
    self.y6 = randFloat(-8, 8)
      
    self.molecule6Fly = LerpPosHprInterval(self.molecule6, randFloat(5, 10), Vec3(self.x6, self.y6, 15), 
Vec3(180,0,0), Vec3(self.x6, self.y6, -100), Vec3(0,-90,180))
    self.molecule6Fly.start()

    
    self.x7 = randFloat(-8, 8)
    self.y7 = randFloat(-8, 8)

    self.molecule7Fly = LerpPosHprInterval(self.molecule7, randFloat(5, 10), Vec3(self.x7, self.y7, 15), Vec3(0, 0, 90),
      Vec3(self.x7, self.y7, -100), Vec3(360,0,0))
    self.molecule7Fly.start()

    
    self.x8 = randFloat(-8, 8)
    self.y8 = randFloat(-8, 8)

    self.molecule8Fly = LerpPosHprInterval(self.molecule8, randFloat(5, 10), Vec3(self.x8, self.y8, 15), Vec3(0, 0, 10),
      Vec3(self.x8, self.y8, -100), Vec3(360,0,0))
    self.molecule8Fly.start()

    
    self.x9 = randFloat(-8, 8)
    self.y9 = randFloat(-8, 8)

    self.molecule9Fly = LerpPosHprInterval(self.molecule9, randFloat(5, 10), Vec3(self.x9, self.y9, 15), Vec3(0, 0, 10),
      Vec3(self.x9, self.y9, -100), Vec3(360,0,0))
    self.molecule9Fly.start()



    self.spaceship = loader.loadModel("models/microship3.egg")
    self.spaceship.reparentTo(render)
    self.spaceship.setPos(0, -1.5, -1)
    self.spaceship.setHpr(0, -90, 0)

    self.shiptrack = self.tracker.createTracker(0)

    cNode = CollisionNode('spaceship')
    cSphere = CollisionSphere(0,0,0,.7)
    cNode.addSolid(cSphere)

    self.spaceshipC = self.spaceship.attachNewNode(cNode)
    self.spaceshipC.setPos(0, 0, .22)
    #self.spaceshipC.show()
    self.cTrav.addCollider(self.spaceshipC, self.collHandler)

    self.accept("escape", sys.exit)    #Exit the program when escape is pressed
    self.accept("arrow_up", self.moveUp)
    self.accept("arrow_down", self.moveDown)
    self.accept("l_ctrl", self.moveFwd)
    self.accept("kpd_0", self.moveBwd)
    self.accept("arrow_left", self.moveLeft)
    self.accept("arrow_right", self.moveRight)
    self.accept("enter", self.newGame)

    self.accept("mouse1", self.shoot)
    
    self.accept("spaceship-into-molecule1", self.handleCollision)



  def shoot(self):
   if self.hits != 3:
    self.camera.play()
    self.seq = Sequence(
      self.showFlash,
      Wait(.1),
      self.hideFlash)
    self.seq.start()  
    if (self.spaceship.getPos()[0]-1 < self.molecule5.getPos()[0] < self.spaceship.getPos()[0]+1) and (self.spaceship.getPos()[1]-1 < self.molecule5.getPos()[1] < self.spaceship.getPos()[1]+1) and (self.molecule5.getPos()[2] < 0):
      self.score = self.score + (math.sqrt(pow(self.spaceship.getPos()[0]-self.molecule5.getPos()[0],2)) + math.sqrt(pow(self.spaceship.getPos()[1]-self.molecule5.getPos()[1],2)))*10
      self.score = math.floor(self.score)
      self.showscore.destroy()
      self.showscore = OnscreenText("Score: "+str(self.score), style=1, fg=(1,1,1,1), pos=(0.9,-0.85), scale = .07)

  def updatePaddleFromTracker(self,task):
	self.spaceship.setPos(-(self.shiptrack.getPos()[0])*15,
		-(self.shiptrack.getPos()[2]-1.1)*15,
		-(self.shiptrack.getPos()[1]+0.1)*20)
       
	return Task.cont
  
  def handleCollision(self, entry):
          self.explosion.play()
	  self.hits = self.hits + 1
	  self.bla.destroy()
	  self.bla = OnscreenText("Hits: "+str(self.hits), style=1, fg=(1,1,1,1), pos=(0.9,-0.95), scale = .07)
	  if self.hits > 2:
		  self.spaceship.detachNode()
		  self.bla.destroy()
		  self.music.stop()
		  self.gameover.play()
		  self.ende = OnscreenText("Joes Mission ist leider gescheitert :(\nFuer neues Spiel Enter druecken", style=1, fg=(1,1,1,1), pos=(0,0.7), scale = .15)
		  self.credits = OnscreenText('--= ATOMIC: Explorer =--\nGame Design by Julia Schmidt & Christian Afonso\n"The Asteroid Belt" from "Max Fighter" composed by Christian Afonso', style=1, fg=(1,1,1,1), pos=(0,-0.1), scale = .1)
  	  
  
  def newGame(self):
	  if self.hits == 3:
		  self.spaceship.reparentTo(render)
		  self.hits = 0
                  self.score = 0
		  self.ende.destroy()
		  self.credits.destroy()
		  self.music.play()
		  self.bla = OnscreenText("Hits: "+str(self.hits), style=1, fg=(1,1,1,1), pos=(0.9,-0.95), scale = .07)
      		  self.showscore.destroy()
      		  self.showscore = OnscreenText("Score: "+str(self.score), style=1, fg=(1,1,1,1), pos=(0.9,-0.85), scale = .07)
		  
	
  
  def moveUp(self):
    self.spaceship.setY(self.spaceship.getY()+.2)
    
  def moveDown(self):
    self.spaceship.setY(self.spaceship.getY()-.2)
    
  def moveLeft(self):
    self.spaceship.setX(self.spaceship.getX()-.2)
    
  def moveRight(self):
    self.spaceship.setX(self.spaceship.getX()+.2)

  def moveFwd(self):
    self.spaceship.setZ(self.spaceship.getZ()-.2)
    
  def moveBwd(self):
    self.spaceship.setZ(self.spaceship.getZ()+.2)


  def mousecheck(self,task):

    xn = 0
    yn = 0
    x = self.x
    y = self.y

    if base.mouseWatcherNode.hasMouse():
      xn=base.mouseWatcherNode.getMouseX()	
      yn=base.mouseWatcherNode.getMouseY()

    #if (xn != x):
    #self.spaceship.setX((xn-x)*self.mouseSpeed)
    #if (yn != y):
    #self.spaceship.setY((yn-y)*self.mouseSpeed)
    x = xn
    y = yn

    return Task.cont

  def flycheck(self, task):

    #------foto-molekül neu starten-----
    if self.molecule5Fly.isStopped():
      self.x5 = randFloat(-3, 3)
      self.y5 = randFloat(-3, 3)

      self.molecule5Fly = LerpPosInterval(self.molecule5, randFloat(10, 20), Vec3(self.x5, self.y5, 200), Vec3(self.x5, self.y5, -100))
      self.molecule5Fly.start()
#-------------------
    if self.molecule1Fly.isStopped():
      self.x1 = randFloat(-4, 4)
      self.y1 = randFloat(-4, 4)
      
      self.molecule1Fly = LerpPosHprInterval(self.molecule1, randFloat(2, 5), Vec3(self.x1, self.y1, 15), 
Vec3(180,0,0), Vec3(self.x1, self.y1, -100), Vec3(0,-90,180))
      self.molecule1Fly.start()

    if self.molecule2Fly.isStopped():
      self.x2 = randFloat(-8, 8)
      self.y2 = randFloat(-8, 8)

      self.molecule2Fly = LerpPosHprInterval(self.molecule2, randFloat(2, 5), Vec3(self.x2, self.y2, 15), Vec3(0, 0, 90),
      Vec3(self.x2, self.y2, -100), Vec3(360,0,0))
      self.molecule2Fly.start()

    if self.molecule3Fly.isStopped():
      self.x3 = randFloat(-8, 8)
      self.y3 = randFloat(-8, 8)

      self.molecule3Fly = LerpPosHprInterval(self.molecule3, randFloat(2, 5), Vec3(self.x3, self.y3, 15), Vec3(0, 0, 10),
      Vec3(self.x3, self.y3, -100), Vec3(360,0,0))
      self.molecule3Fly.start()

    if self.molecule4Fly.isStopped():
      self.x4 = randFloat(-8, 8)
      self.y4 = randFloat(-8, 8)

      self.molecule4Fly = LerpPosHprInterval(self.molecule4, randFloat(5, 10), Vec3(self.x4, self.y4, 15), Vec3(0, 0, 10),
      Vec3(self.x4, self.y4, -100), Vec3(360,0,0))
      self.molecule4Fly.start()



    if self.molecule6Fly.isStopped():
      self.x6 = randFloat(-4, 4)
      self.y6 = randFloat(-4, 4)
      
      self.molecule6Fly = LerpPosHprInterval(self.molecule6, randFloat(2, 5), Vec3(self.x6, self.y6, 15), 
Vec3(180,0,0), Vec3(self.x6, self.y6, -100), Vec3(0,-90,180))
      self.molecule6Fly.start()

    if self.molecule7Fly.isStopped():
      self.x7 = randFloat(-8, 8)
      self.y7 = randFloat(-8, 8)

      self.molecule7Fly = LerpPosHprInterval(self.molecule7, randFloat(2, 5), Vec3(self.x7, self.y7, 15), Vec3(0, 0, 90),
      Vec3(self.x7, self.y7, -100), Vec3(360,0,0))
      self.molecule7Fly.start()

    if self.molecule8Fly.isStopped():
      self.x8 = randFloat(-8, 8)
      self.y8 = randFloat(-8, 8)

      self.molecule8Fly = LerpPosHprInterval(self.molecule8, randFloat(2, 5), Vec3(self.x8, self.y8, 15), Vec3(0, 0, 10),
      Vec3(self.x8, self.y8, -100), Vec3(360,0,0))
      self.molecule8Fly.start()

    if self.molecule9Fly.isStopped():
      self.x9 = randFloat(-8, 8)
      self.y9 = randFloat(-8, 8)

      self.molecule9Fly = LerpPosHprInterval(self.molecule9, randFloat(5, 10), Vec3(self.x9, self.y9, 15), Vec3(0, 0, 10),
      Vec3(self.x9, self.y9, -100), Vec3(360,0,0))
      self.molecule9Fly.start()

   
    return Task.cont

w = World()

run()
