from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "fullscreen 1")


import direct.directbase.DirectStart
from pandac.PandaModules import WindowProperties
from pandac.PandaModules import Filename
from pandac.PandaModules import PandaNode,NodePath,Camera,TextNode
from pandac.PandaModules import Vec3,Vec4,Point3
from pandac.PandaModules import AmbientLight,PointLight,Shader
from direct.actor.Actor import Actor
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
from direct.interval.IntervalGlobal import Sequence
from direct.gui.OnscreenText import OnscreenText
#import numpy
#panda imports
import direct.directbase.DirectStart

from pandac.PandaModules import *
# Get the location of the 'py' file I'm running:
mydir = os.path.abspath(sys.path[0])
 
# Convert that to panda's unix-style notation.
mydir = Filename.fromOsSpecific(mydir).getFullpath()

def addInstructions(pos, msg):
    return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
                        pos=(-1.3, pos), align=TextNode.ALeft, scale = .1)

class World(DirectObject):

    def __init__(self):

        #self.environ = loader.loadModel("models/world")      
        #self.environ.reparentTo(render)
        #self.environ.setPos(0,0,0)
        import sys,os
        from pandac.PandaModules import Filename
 
        mydir = os.path.abspath(sys.path[0])
        
       
 
        mydir = Filename.fromOsSpecific(mydir).getFullpath()        
 
        self.sky = loader.loadModel(mydir+"/models/Sky_01")
        self.sky.setScale(10,10,10)
        self.sky.setPos(0,0,-200)
        self.sky.reparentTo(render)
        self.road = loader.loadModel(mydir+"/models/Ground_01")
        self.road.setPos(0,0,-5)
        self.road.reparentTo(render)
        # Create Ralph       
        self.ralph = Actor(mydir+"/models/ralph.egg",
                                 {"run":mydir+"/models/ralph-run.egg.pz",
                                  "walk":mydir+"/models/ralph-walk.egg.pz"})
        self.ralph.setPos(-2.7,300,-5)
        self.ralph.setScale(0.2)
        self.ralph.loop("walk")
        self.ralph.reparentTo(render)
                    
        # Add a light to the scene.
        self.lightpivot = render.attachNewNode("lightpivot")
        self.lightpivot.setPos(-3,0.5,4)
        plight = PointLight('plight')
        plight.setColor(Vec4(1, 1, 1, 1))
        plight.setAttenuation(Vec3(0.7,0.05,0))
        plnp = self.lightpivot.attachNewNode(plight)
        plnp.setPos(0, 18, -5)
        

        ralphMarch = self.ralph.posInterval(20,Point3(-2.7, 200, -5),startPos=Point3(-2.7, 300, -5))                                                        
                                                        
        self.ralphpace = Sequence(ralphMarch, name = "ralphMarch")
        self.ralphpace.loop()  
 
        k = 1000
        input = PTAVecBase4.emptyArray(k);
        count = 0
        for i in range(10):
            for j in range(k/10):
                input[count] = Vec4(i*3,j*-8,0,0)
                count += 1

               
        
        lvec = PTAVecBase4([Vec4(-4,0,0,0),Vec4(4,0,0,0)]);
        self.ralph.setShaderInput("light", plnp)
        self.ralph.setShaderInput("fIN.Kd", PTAFloat([1.4]))
        self.ralph.setShaderInput("fIN.Ka", PTAFloat([0.2]))
        self.ralph.setShaderInput("Ly", input)
        self.ralph.setShaderInput("instances_position", lvec)
        self.ralph.setShader(Shader.load("shader.c"))
        
        self.ralph.setInstanceCount(k)
        
        self.inst = addInstructions(0.8, "There are 1000 Ralphs marching on the road now")
        
        # Make the mouse invisible, turn off normal mouse controls
        base.disableMouse()
        props = WindowProperties()
        props.setCursorHidden(True)
        base.win.requestProperties(props)
        # Set the current viewing target
        self.heading = 0
        self.pitch = 0
        md = base.win.getPointer(0)
        self.mousex = md.getX()
        self.mousey = md.getY()
        self.last = 0
        self.WASD = [0,0,0,0] 
        base.camera.setPos(0,0,0)
        

        taskMgr.add(self.controlCamera, "camera-task")
        self.accept("escape", sys.exit, [0])
        self.accept("w",self.setWASD,[0,1])
        self.accept("w-up",self.setWASD,[0,0])
        self.accept("a",self.setWASD,[1,1])
        self.accept("a-up",self.setWASD,[1,0])
        self.accept("s",self.setWASD,[2,1])
        self.accept("s-up",self.setWASD,[2,0])
        self.accept("d",self.setWASD,[3,1])
        self.accept("d-up",self.setWASD,[3,0])
        
        self.accept("arrow_left", self.rotateCam, [-1])
        self.accept("arrow_right", self.rotateCam, [1])       

    
    def setWASD(self, btn, value):
        self.WASD[btn] = value
    
    def rotateCam(self, offset):
        self.heading = self.heading - offset*10    
    def controlCamera(self, task):
        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        self.heading = self.heading - (x - self.mousex)*0.1
        self.pitch = self.pitch - (y - self.mousey)*0.1
        if (base.win.movePointer(0, 100, 100)):
            self.mousex=100
            self.mousey=100
        if (self.pitch < -45): self.pitch = -45
        if (self.pitch >  45): self.pitch =  45
        base.camera.setHpr(self.heading,self.pitch,0)
        LR= base.camera.getMat().getRow3(0)
        BF= base.camera.getMat().getRow3(1)
        elapsed = task.time - self.last
        if(self.WASD[0]):
            base.camera.setPos(base.camera.getPos()+BF * 30*elapsed)      
        if(self.WASD[1]):
            base.camera.setPos(base.camera.getPos()-LR * 30*elapsed)
        if(self.WASD[2]):
            base.camera.setPos(base.camera.getPos()-BF * 30*elapsed) 
        if(self.WASD[3]):
            base.camera.setPos(base.camera.getPos()+LR * 30*elapsed)
        if(base.camera.getZ()<0):
            base.camera.setZ(0)
        self.last = task.time
        return Task.cont
w = World()
run()

