#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
PANDA3D 3D空间GUI演示
展示如何在3D场景中使用GUI元素
"""

from direct.showbase.ShowBase import ShowBase
from direct.gui.DirectGui import *
from direct.gui.OnscreenText import OnscreenText
from direct.gui.OnscreenImage import OnscreenImage
from panda3d.core import *
from direct.task import Task

class GUI3DDemo(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        # 设置背景色
        self.setBackgroundColor(0.1, 0.1, 0.3)
        
        # 设置相机位置
        self.cam.setPos(0, -10, 0)
        self.cam.lookAt(0, 0, 0)
        
        # 尝试加载中文字体
        self.chinese_font = self.loadChineseFont()
        
        # 创建标题（2D界面）
        self.title = OnscreenText(
            text="PANDA3D 3D空间GUI演示",
            pos=(0, 0.9),
            scale=0.08,
            fg=(1, 1, 1, 1),
            align=TextNode.ACenter,
            font=self.chinese_font if self.chinese_font else None
        )
        
        # 创建基本的2D GUI
        self.create2DGUI()
        
        # 创建3D场景中的GUI元素
        self.create3DGUI()
        
        # 加载一个简单的3D模型作为背景
        self.createScene()
        
        print("3D GUI演示启动成功!")
        print(f"中文字体加载状态: {'成功' if self.chinese_font else '失败，使用默认字体'}")
        print("你可以看到2D界面元素和3D空间中的GUI")
    
    def loadChineseFont(self):
        """尝试加载中文字体"""
        import os
        font_paths = [
            '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc',
            '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc',
            '/usr/share/fonts/truetype/arphic/ukai.ttc',
            '/usr/share/fonts/truetype/arphic/uming.ttc',
        ]
        
        for font_path in font_paths:
            if os.path.exists(font_path):
                try:
                    font = self.loader.loadFont(font_path)
                    if font:
                        return font
                except:
                    continue
        return None
    
    def create2DGUI(self):
        """创建传统的2D GUI元素"""
        # 控制面板标题
        self.controlTitle = OnscreenText(
            text="控制面板",
            pos=(-1.2, 0.8),
            scale=0.06,
            fg=(1, 1, 0, 1),
            align=TextNode.ALeft,
            font=self.chinese_font if self.chinese_font else None
        )
        
        # 旋转控制按钮
        self.rotateButton = DirectButton(
            text="旋转场景",
            pos=(-1.2, 0, 0.6),
            scale=0.05,
            command=self.toggleRotation,
            frameColor=(0.2, 0.6, 0.8, 1),
            text_font=self.chinese_font if self.chinese_font else None
        )
        
        # 颜色变化按钮
        self.colorButton = DirectButton(
            text="变换颜色",
            pos=(-1.2, 0, 0.4),
            scale=0.05,
            command=self.changeColors,
            frameColor=(0.8, 0.2, 0.6, 1),
            text_font=self.chinese_font if self.chinese_font else None
        )
        
        # 重置按钮
        self.resetButton = DirectButton(
            text="重置",
            pos=(-1.2, 0, 0.2),
            scale=0.05,
            command=self.resetScene,
            frameColor=(0.6, 0.8, 0.2, 1),
            text_font=self.chinese_font if self.chinese_font else None
        )
        
        # 状态显示
        self.statusText = OnscreenText(
            text="状态: 就绪",
            pos=(-1.2, -0.8),
            scale=0.04,
            fg=(0, 1, 0, 1),
            align=TextNode.ALeft,
            font=self.chinese_font if self.chinese_font else None
        )
        
        # 退出按钮
        self.exitButton = DirectButton(
            text="退出",
            pos=(1.2, 0, -0.8),
            scale=0.05,
            command=self.exitDemo,
            frameColor=(0.8, 0.2, 0.2, 1),
            text_font=self.chinese_font if self.chinese_font else None
        )
    
    def create3DGUI(self):
        """创建3D空间中的GUI元素"""
        # 创建一个在3D空间中的按钮
        # 这实际上是一个2D GUI元素，但我们可以将其父级设置为3D节点
        
        # 创建3D空间中的文本
        self.text3D = TextNode('3d-text')
        self.text3D.setText("3D空间中的文本")
        self.text3D.setAlign(TextNode.ACenter)
        if self.chinese_font:
            self.text3D.setFont(self.chinese_font)
        self.textNodePath = self.render.attachNewNode(self.text3D)
        self.textNodePath.setPos(0, 5, 2)
        self.textNodePath.setScale(0.5)
        self.textNodePath.setColor(1, 1, 0, 1)
        self.textNodePath.setBillboardAxis()  # 让文本总是面向相机
        
        # 创建另一个3D文本，显示说明
        self.info3D = TextNode('info-text')
        self.info3D.setText("这是3D空间中的GUI元素\n它们可以与3D场景交互")
        self.info3D.setAlign(TextNode.ACenter)
        if self.chinese_font:
            self.info3D.setFont(self.chinese_font)
        self.infoNodePath = self.render.attachNewNode(self.info3D)
        self.infoNodePath.setPos(0, 3, -1)
        self.infoNodePath.setScale(0.3)
        self.infoNodePath.setColor(0, 1, 1, 1)
        self.infoNodePath.setBillboardAxis()
        
        # 创建一个3D平面作为"虚拟屏幕"
        self.createVirtualScreen()
    
    def createVirtualScreen(self):
        """创建一个3D空间中的虚拟屏幕"""
        # 创建一个卡片（平面）
        cm = CardMaker("virtual-screen")
        cm.setFrame(-2, 2, -1, 1)
        self.virtualScreen = self.render.attachNewNode(cm.generate())
        self.virtualScreen.setPos(3, 5, 0)
        self.virtualScreen.setColor(0.2, 0.2, 0.2, 0.8)
        self.virtualScreen.setTransparency(TransparencyAttrib.MAlpha)
        
        # 在虚拟屏幕上添加文本
        screenText = TextNode('screen-text')
        screenText.setText("虚拟3D屏幕\n\n这里可以显示\n任何信息")
        screenText.setAlign(TextNode.ACenter)
        if self.chinese_font:
            screenText.setFont(self.chinese_font)
        screenTextNP = self.virtualScreen.attachNewNode(screenText)
        screenTextNP.setPos(0, 0.01, 0)  # 稍微偏移，避免z-fighting
        screenTextNP.setScale(0.3)
        screenTextNP.setColor(0, 1, 0, 1)
    
    def createScene(self):
        """创建3D场景"""
        # 创建一个简单的立方体
        from panda3d.core import CardMaker
        
        # 创建地面
        cm = CardMaker("ground")
        cm.setFrame(-10, 10, -10, 10)
        ground = self.render.attachNewNode(cm.generate())
        ground.setP(-90)  # 旋转成水平面
        ground.setColor(0.5, 0.5, 0.5, 1)
        
        # 创建一些立方体
        self.cubes = []
        for i in range(3):
            for j in range(3):
                # 使用内置的立方体几何
                cube = self.loader.loadModel("models/environment")
                if not cube:
                    # 如果找不到模型，创建一个简单的几何体
                    cube = self.render.attachNewNode("cube")
                
                cube.reparentTo(self.render)
                cube.setPos(-2 + i*2, 2 + j*2, 0.5)
                cube.setScale(0.5)
                cube.setColor(
                    0.2 + i*0.3, 
                    0.2 + j*0.3, 
                    0.5,
                    1
                )
                self.cubes.append(cube)
        
        # 添加光照
        dlight = DirectionalLight('dlight')
        dlight.setColor((1, 1, 1, 1))
        dlnp = self.render.attachNewNode(dlight)
        dlnp.setHpr(45, -45, 0)
        self.render.setLight(dlnp)
        
        alight = AmbientLight('alight')
        alight.setColor((0.3, 0.3, 0.3, 1))
        alnp = self.render.attachNewNode(alight)
        self.render.setLight(alnp)
        
        # 初始化旋转状态
        self.rotating = False
        self.colorIndex = 0
    
    def toggleRotation(self):
        """切换场景旋转"""
        if self.rotating:
            self.taskMgr.remove("rotate-scene")
            self.rotating = False
            self.rotateButton['text'] = "旋转场景"
            self.statusText.setText("状态: 停止旋转")
        else:
            self.taskMgr.add(self.rotateSceneTask, "rotate-scene")
            self.rotating = True
            self.rotateButton['text'] = "停止旋转"
            self.statusText.setText("状态: 正在旋转")
        
        print(f"旋转状态: {'开启' if self.rotating else '关闭'}")
    
    def rotateSceneTask(self, task):
        """旋转场景的任务"""
        for cube in self.cubes:
            cube.setH(cube.getH() + 50 * globalClock.getDt())
        
        # 旋转3D文本
        self.textNodePath.setH(self.textNodePath.getH() + 30 * globalClock.getDt())
        self.virtualScreen.setH(self.virtualScreen.getH() + 20 * globalClock.getDt())
        
        return task.cont
    
    def changeColors(self):
        """改变场景颜色"""
        self.colorIndex = (self.colorIndex + 1) % 3
        
        colors = [
            [(1, 0.5, 0.5), (0.5, 1, 0.5), (0.5, 0.5, 1)],  # 红绿蓝
            [(1, 1, 0.5), (1, 0.5, 1), (0.5, 1, 1)],        # 黄洋红青
            [(0.8, 0.2, 0.8), (0.2, 0.8, 0.8), (0.8, 0.8, 0.2)]  # 紫青黄
        ]
        
        colorSet = colors[self.colorIndex]
        
        for i, cube in enumerate(self.cubes):
            color = colorSet[i % 3]
            cube.setColor(*color, 1)
        
        # 改变3D文本颜色
        textColors = [(1, 1, 0), (0, 1, 1), (1, 0, 1)]
        self.textNodePath.setColor(*textColors[self.colorIndex], 1)
        
        self.statusText.setText(f"状态: 颜色方案 {self.colorIndex + 1}")
        print(f"切换到颜色方案 {self.colorIndex + 1}")
    
    def resetScene(self):
        """重置场景"""
        # 停止旋转
        if self.rotating:
            self.toggleRotation()
        
        # 重置立方体位置和颜色
        for i, cube in enumerate(self.cubes):
            row = i // 3
            col = i % 3
            cube.setPos(-2 + col*2, 2 + row*2, 0.5)
            cube.setHpr(0, 0, 0)
            cube.setColor(0.2 + col*0.3, 0.2 + row*0.3, 0.5, 1)
        
        # 重置3D文本
        self.textNodePath.setHpr(0, 0, 0)
        self.textNodePath.setColor(1, 1, 0, 1)
        self.virtualScreen.setHpr(0, 0, 0)
        
        self.colorIndex = 0
        self.statusText.setText("状态: 场景已重置")
        print("场景已重置")
    
    def exitDemo(self):
        """退出演示"""
        print("退出3D GUI演示")
        self.userExit()

if __name__ == "__main__":
    print("启动PANDA3D 3D GUI演示...")
    demo = GUI3DDemo()
    demo.run() 