import random
import time

from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from math import pi
from direct.actor.Actor import Actor
from direct.interval.IntervalGlobal import Sequence
from panda3d.core import Point3, KeyboardButton, CollisionBox, CollisionSphere, CollisionNode, CollisionTraverser, \
    CollisionHandlerQueue
from panda3d.core import Vec3

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        # Отрисовка
        World_path = "MyModels/World.obj"
        self.World = self.loader.loadModel(World_path)
        if self.World is None:
            print("Мир не загрузился")
            return
        self.World.reparentTo(self.render)
        self.World.setScale(100)
        self.World.setPos(0, 0, 0)
        """
        Money_path = "MyModels/Money.obj"
        self.Money = self.loader.loadModel(Money_path)
        if self.Money is None:
            print("Деньги не загрузились")
            return
        self.Money.reparentTo(self.render)
        self.Money.setScale(10)
        self.Money.setPos(0, 0, 0)
        """
        Grass_path = "MyModels/Grass.obj"
        self.Grass = self.loader.loadModel(Grass_path)
        if self.Grass is None:
            print("Трова не загрузилась")
            return
        self.Grass.reparentTo(self.render)
        self.Grass.setScale(10)
        self.Grass.setPos(0, 10, -800)

        Planks_path = "MyModels/Planks.obj"
        self.Planks = self.loader.loadModel(Planks_path)
        if self.Planks is None:
            print("Доски не загрузились")
            return
        self.Planks.reparentTo(self.render)
        self.Planks.setScale(10)
        self.Planks.setPos(0, 10, -1000)

        

        Tree_path = "MyModels/Tree.obj"
        self.Tree = self.loader.loadModel(Tree_path)
        if self.Tree is None:
            print("Дерево не загрузилось")
            return
        self.Tree.reparentTo(self.render)
        self.Tree.setScale(10)
        self.Tree.setPos(0, 10, -1000)

        Water_path = "MyModels/Water.obj"
        self.Water = self.loader.loadModel(Water_path)
        if self.Water is None:
            print("Вода не загрузилась")
            return
        self.Water.reparentTo(self.render)
        self.Water.setScale(8)
        self.Water.setPos(0, 10, -1000)

        Char_path = "MyModels/Char.obj"
        self.Char = self.loader.loadModel(Char_path)
        if self.Char is None:
            print("Герой не загрузился")
            return
        self.Char.reparentTo(self.render)
        self.Char.setScale(10)
        self.Char.setPos(0,30,0)
        #####################################################





        """
        posInterval1 = self.PandaActor.posInterval(13,Point3(0,-10,0),
                                                   startPos=Point3(0,10,0))
        posInterval2 = self.PandaActor.posInterval(13, Point3(0,10,0),
                                                   startPos=Point3(0,-10,0))
        """














        #################################################################
        #Колизии гг
        cs = CollisionSphere(0, 0, 1, 1)
        box = CollisionBox(5, 5, 5, 10)
        cnodepath = self.Char.attachNewNode(CollisionNode('Egor'))
        cnodepath.node().addSolid(cs)
        cnodepath.show()
        Collider = self.Char.attachNewNode(CollisionNode('Collider'))
        Collider.node().addSolid(CollisionBox((-1, -4, 0), (1, 4, 2)))
        Collider.show()

        ###############################################################

        #Колизии мира
        levelCollider = self.World.attachNewNode(CollisionNode('LevelCollider'))
        levelCollider.node().addSolid(CollisionBox((-4, -0.1, -2), (4, 0.1, 2)))
        levelCollider.show()
        ##########################################################################

        #Колизии дерево(большого припятствия)
        cnodepath2 = self.Tree.attachNewNode(CollisionNode('cnodepath2'))
        cnodepath2.node().addSolid(CollisionSphere(0,0,0,1))
        cnodepath2.show()

        ###########################################################
        #Обработка прыжка
        self.cTrav = CollisionTraverser()
        self.queue = CollisionHandlerQueue()

        self.cTrav.addCollider(cnodepath, self.queue)

        cnodepath.node().setIntoCollideMask(0) #0 - кто толкает, 1 - кто ждет толчка

        cnodepath.node().setFromCollideMask(1)

        levelCollider.node().setIntoCollideMask(1) #коллизия уровня ждет столкновения, он терпила!
        levelCollider.setPos(0,0,0)
        ##############################################################################


        ####################################################
        #Переменые
        self.IsGround = False
        self.isbig = False
        self.random = random.randint(0,3)
        self.random2 = random.randint(0, 2)
        ###################################################
        #Таски
        self.taskMgr.add(self.update2, "update2")

        self.taskMgr.add(self.checkCollision, "checkCollision")
        self.taskMgr.add(self.lookat, "lookat")
        self.taskMgr.add(self.train3, "train")
        self.taskMgr.add(self.train4, "train2")
        self.taskMgr.add(self.train5, "train8")
        self.taskMgr.add(self.train6, "train9")
        ########################
        #Управление
        self.keyMap = {
            "left": False,
            "right": False,
            "space": False
        }

        self.accept('a', self.updateKey, ["left", True])
        self.accept('a-up', self.updateKey, ["left", False])
        self.accept('d', self.updateKey, ["right", True])
        self.accept('d-up', self.updateKey, ["right", False])
        self.accept('space', self.updateKey, ["space", True])
        self.accept('space-up', self.updateKey, ["space", False])

    def updateKey(self, key, status):
            self.keyMap[key] = status

    def update2(self,task):
        fps = task.time
        if self.keyMap["left"]:
            if self.Char.getPos() > -30:
                self.Char.setPos(self.Char.getPos() + Vec3(-5, 0, 0))

        if self.keyMap["right"]:
            if self.Char.getPos() < 30:
                self.Char.setPos(self.Char.getPos() + Vec3(5,0, 0))

        if self.keyMap["space"]:
            if self.IsGround == True:
                self.Char.setPos(self.Char.getPos() + Vec3(0, 20, 0))
            self.IsGround = False
        return task.cont
    ##############################################
    #Другие функции

    ##############################################
    #Спавн препятствий


    def train3(self,task):
        self.random = random.randint(1, 2)
        self.Tree.setPos(self.Tree.getPos() + Vec3(0, 0, 10))
        if self.Tree.getPos().z > 50:
            self.Tree.setPos(self.Tree.getPos()+ Vec3(0,0,-1000))

            if self.random == 2:
                self.Tree.setPos(20, 10, -1000)

            if self.random == 1:
                self.Tree.setPos(-20, 10, -1000)

        return task.cont
    def train5(self, task):
        self.Planks.setPos(self.Planks.getPos() + Vec3(0, 0, 10))
        if self.Planks.getPos().z > 50:
            self.Planks.setPos(self.Planks.getPos() + Vec3(0, 0, -1000))
            if self.random == 1:
                self.Planks.setPos(20, 10, -1000)

            if self.random == 2:
                self.Planks.setPos(-20, 10, -1000)
        return task.cont
    def train4(self,task):
        self.Water.setPos(self.Water.getPos() + Vec3(0, 0, 10))
        if self.Water.getPos().z > 50:
            self.Water.setPos(self.Water.getPos() + Vec3(0, 0, -1000))
        return task.cont
    def train6(self,task):
        self.Grass.setPos(self.Grass.getPos() + Vec3(0, 0, 10))
        if self.Grass.getPos().z > 50:
            self.Grass.setPos(self.Grass.getPos() + Vec3(0, 0, -1000))
            if self.random == 2:
                self.Grass.setPos(20, 10, -1000)

            if self.random == 1:
                self.Grass.setPos(-20, 10, -1000)
        return task.cont


    ###########################################
    def checkCollision(self, task):
        fps = task.time
        if self.IsGround == True:
            j = 1

        else:
            self.Char.setPos(self.Char.getPos() + Vec3(0, -0.5,0 ))
        self.cTrav.traverse(self.render)
        for entry in self.queue.getEntries():
            name = entry.getIntoNodePath().getName()
            if name == "LevelCollider":
                self.IsGround = True

        return task.cont

    def lookat(self,task):
        self.camera.setPos(self.Char.getX(), self.Char.getY() + 10, self.Char.getZ())
        return task.cont


app = MyApp()
app.run()

