import warnings

from core.Command_System import CommandManager
from core.InfoPanelManager import InfoPanelManager
from core.patrol_system import PatrolSystem
from demo.video_integration import VideoManager

warnings.filterwarnings("ignore", category=DeprecationWarning)

import sys
import builtins
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction,
                            QDockWidget, QTreeWidget, QListWidget, QWidget, QVBoxLayout, QTreeWidgetItem,
                            QLabel, QLineEdit, QFormLayout, QDoubleSpinBox, QScrollArea, QTreeView, QInputDialog, QFileDialog, QMessageBox, QDialog, QGroupBox, QHBoxLayout, QPushButton, QDialogButtonBox)
from PyQt5.QtCore import Qt, QDir, QUrl
from PyQt5.QtGui import QDrag, QPainter, QPixmap
from PyQt5.QtWidgets import QFileSystemModel
from QMeta3D.QMeta3DWidget import QMeta3DWidget
from panda3d.core import loadPrcFileData
loadPrcFileData("", "assertions 0")
from core.world import CoreWorld
from core.selection import SelectionSystem
from core.event_handler import EventHandler
from core.tool_manager import ToolManager
from core.script_system import ScriptManager
from core.patrol_system import PatrolSystem
from core.Command_System import CommandManager
from gui.gui_manager import GUIManager
from core.terrain_manager import TerrainManager
from scene.scene_manager import SceneManager
from project.project_manager import ProjectManager
from ui.widgets import CustomMeta3DWidget, CustomFileView, CustomTreeWidget
from ui.property_panel import PropertyPanelManager
from ui.interface_manager import InterfaceManager
from panda3d.core import (CardMaker, Vec4, Vec3, ColorAttrib, MaterialAttrib, 
                         GeomNode, NodePath, Material, CollisionTraverser, 
                         CollisionHandlerQueue, CollisionNode, CollisionRay, 
                         Plane, Point3, Point2, BitMask32, CollisionSphere, 
                         CollisionPlane, ModelPool, Filename, ModelRoot, 
                         AmbientLight, DirectionalLight, TextureAttrib, DriveInterface, WindowProperties)
from panda3d.egg import EggData, EggVertexPool, EggPolygon
from direct.task import Task
from direct.task.TaskManagerGlobal import taskMgr
from direct.showbase.ShowBase import ShowBase
from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBaseGlobal import globalClock, aspect2d
import os
import json
import time
import datetime
from direct.actor.Actor import Actor
from PyQt5.sip import wrapinstance
#from RenderPipelineFile.toolkit.material_editor.main import MaterialEditor

class MyWorld(CoreWorld):
    def __init__(self):
        super().__init__()
        
        # 初始化选择和变换系统
        self.selection = SelectionSystem(self)

        # 绑定F键用于聚焦选中节点
        self.accept("f", self.onFocusKeyPressed)
        self.accept("F", self.onFocusKeyPressed)  # 大写F

        #初始化巡检系统
        self.patrol_system = PatrolSystem(self)
        self.accept("p",self.onPatrolKeyPressed)
        self.accept("P",self.onPatrolKeyPressed)

        # 初始化事件处理系统
        self.event_handler = EventHandler(self)
        
        # 初始化工具管理系统
        self.tool_manager = ToolManager(self)
        
        # 初始化脚本管理系统
        self.script_manager = ScriptManager(self)

        # 初始化GUI管理系统
        self.gui_manager = GUIManager(self)

        # 初始化视频管理
        self.video_manager = VideoManager(self)

        # 初始化场景管理系统
        self.scene_manager = SceneManager(self)
        
        # 初始化项目管理系统
        self.project_manager = ProjectManager(self)
        
        # 初始化属性面板管理系统
        self.property_panel = PropertyPanelManager(self)
        
        # 初始化界面管理系统
        self.interface_manager = InterfaceManager(self)
        

        # 启动脚本系统
        self.script_manager.start_system()

        #self.material_editor = None
        self.terrain_manager = TerrainManager(self)

        self.terrain_edit_radius = 3.0
        self.terrain_edit_strength=0.3
        self.terrain_edit_operation = "add"

        self.info_panel_manager = InfoPanelManager(self)

        self.command_manager = CommandManager()

        # 初始化碰撞管理器
        from core.collision_manager import CollisionManager
        self.collision_manager = CollisionManager(self)

        # 初始化VR管理器
        try:
            from core.vr import VRManager
            self.vr_manager = VRManager(self)
            print("✓ VR管理器初始化完成")
        except Exception as e:
            print(f"⚠ VR管理器初始化失败: {e}")
            self.vr_manager = None

        # 调试选项
        self.debug_collision = True  # 是否显示碰撞体

        # 默认启用模型间碰撞检测（可选）
        self.enableModelCollisionDetection(enable=True, frequency=0.1, threshold=0.5)

        try:
            self.property_panel = PropertyPanelManager(self)
            print("✓ 属性面板管理器初始化完成")
        except Exception as e:
            print(f"⚠ 属性面板管理器初始化失败: {e}")
            import traceback
            traceback.print_exc()
            self.property_panel = None

        print("✓ MyWorld 初始化完成")
        print("✅ 碰撞管理器已初始化")

    # ==================== 兼容性属性 ====================

    # 保留models属性以兼容现有代码
    @property
    def models(self):
        """模型列表的兼容性属性"""
        return self.scene_manager.models

    @models.setter
    def models(self, value):
        """模型列表的兼容性设置器"""
        self.scene_manager.models = value

    # 保留gui_elements属性以兼容现有代码
    @property
    def gui_elements(self):
        """GUI元素列表的兼容性属性"""
        return self.gui_manager.gui_elements

    @gui_elements.setter
    def gui_elements(self, value):
        """GUI元素列表的兼容性设置器"""
        self.gui_manager.gui_elements = value

    # 保留gui_elements属性以兼容现有代码
    @property
    def Spotlight(self):
        """GUI元素列表的兼容性属性"""
        return self.scene_manager.Spotlight

    @Spotlight.setter
    def Spotlight(self, value):
        """GUI元素列表的兼容性设置器"""
        self.scene_manager.Spotlight = value

    @property
    def Pointlight(self):
        return self.scene_manager.Pointlight

    @Pointlight.setter
    def Pointlight(self,value):
        self.scene_manager.Pointlight = value


    # 保留guiEditMode属性以兼容现有代码
    @property
    def guiEditMode(self):
        """GUI编辑模式的兼容性属性"""
        return self.gui_manager.guiEditMode

    @guiEditMode.setter
    def guiEditMode(self, value):
        """GUI编辑模式的兼容性设置器"""
        self.gui_manager.guiEditMode = value

    # 保留currentTool属性以兼容现有代码
    @property
    def currentTool(self):
        """当前工具的兼容性属性"""
        return self.tool_manager.currentTool

    @currentTool.setter
    def currentTool(self, value):
        """当前工具的兼容性设置器"""
        self.tool_manager.currentTool = value

    # 保留treeWidget属性以兼容现有代码
    @property
    def treeWidget(self):
        """树形控件的兼容性属性"""
        return self.interface_manager.treeWidget

    @treeWidget.setter
    def treeWidget(self, value):
        """树形控件的兼容性设置器"""
        self.interface_manager.treeWidget = value

    #保留terrains属性以兼容现有代码
    @property
    def terrains(self):
        """地形列表的兼容性属性"""
        return self.terrain_manager.terrains

    @terrains.setter
    def terrains(self,value):
        """地形列表的兼容性设置器"""
        self.terrain_manager.terrains = value

    # ==================== GUI管理功能代理 ====================

    # GUI元素创建方法 - 代理到gui_manager
    def createGUIButton(self, pos=(0, 0, 0), text="按钮", size=0.1):
        """创建2D GUI按钮"""
        return self.gui_manager.createGUIButton(pos, text, size)

    def createGUILabel(self, pos=(0, 0, 0), text="标签", size=0.08):
        """创建2D GUI标签"""
        return self.gui_manager.createGUILabel(pos, text, size)

    def createGUIEntry(self, pos=(0, 0, 0), placeholder="输入文本...", size=0.08):
        """创建2D GUI文本输入框"""
        return self.gui_manager.createGUIEntry(pos, placeholder, size)

    def createGUI3DText(self, pos=(0, 0, 0), text="3D文本", size=1):
        """创建3D空间文本"""
        return self.gui_manager.createGUI3DText(pos, text, size)

    def createGUI3DImage(self,pos=(0,0,0),text="3D图片",size=(1,1,1)):
        """创建3D图片"""
        return self.gui_manager.createGUI3DImage(pos,text,size)

    def createGUI2DImage(self, pos=(0, 0, 0), image_path=None, size=2):
        """创建2D GUI图片"""
        return self.gui_manager.createGUI2DImage(pos, image_path, size)

    def createVideoScreen(self,pos=(0,0,0),size=1,video_path=None):
        """创建视频屏幕"""
        return self.gui_manager.createVideoScreen(pos,size,video_path)

    def create2DVideoScreen(self,pos=(0,0,0),size=0.2,video_path=None):
        """创建2D视频屏幕"""
        return self.gui_manager.createGUI2DVideoScreen(pos,size,video_path)

    def createSphericalVideo(self,pos=(0,0,0),radius=5.0,video_path=None):
        """创建360度视频"""
        return self.gui_manager.createSphericalVideo(pos,radius,video_path)

    def playSphericalVideo(self,spherical_video_node):
        return self.gui_manager.playSphericalVideo(spherical_video_node)

    def pauseSphericalVideo(self,spherical_video_node):
        return self.gui_manager.pauseSphericalVideo(spherical_video_node)

    def setSphericalVideoTime(self,spherical_video_node,time_seconds):
        return self.gui_manager.setSphericalVideoTime(spherical_video_node,time_seconds)

    def createSpotLight(self,pos=(0,0,5)):
        """创建聚光灯"""
        return self.scene_manager.createSpotLight(pos)

    def createPointLight(self,pos=(0,0,5)):
        """创建点光源"""
        return self.scene_manager.createPointLight(pos)

    def createGUIVirtualScreen(self, pos=(0, 0, 0), size=(2, 1), text="虚拟屏幕"):
        """创建3D虚拟屏幕"""
        return self.gui_manager.createGUIVirtualScreen(pos, size, text)

    def createGUISlider(self, pos=(0, 0, 0), text="滑块", scale=0.3):
        """创建2D GUI滑块"""
        return self.gui_manager.createGUISlider(pos, text, scale)

    # GUI元素管理方法 - 代理到gui_manager
    def deleteGUIElement(self, gui_element):
        """删除GUI元素"""
        return self.gui_manager.deleteGUIElement(gui_element)

    def editGUIElement(self, gui_element, property_name, value):
        """编辑GUI元素属性"""
        return self.gui_manager.editGUIElement(gui_element, property_name, value)

    def duplicateGUIElement(self, gui_element):
        """复制GUI元素"""
        return self.gui_manager.duplicateGUIElement(gui_element)

    def editGUIElementDialog(self, gui_element):
        """显示GUI元素编辑对话框"""
        return self.gui_manager.editGUIElementDialog(gui_element)

    # GUI事件处理方法 - 代理到gui_manager
    def onGUIButtonClick(self, button_id):
        """GUI按钮点击事件处理"""
        return self.gui_manager.onGUIButtonClick(button_id)

    def onGUIEntrySubmit(self, text, entry_id):
        """GUI输入框提交事件处理"""
        return self.gui_manager.onGUIEntrySubmit(text, entry_id)

    # GUI编辑模式方法 - 代理到gui_manager
    def toggleGUIEditMode(self):
        """切换GUI编辑模式"""
        return self.gui_manager.toggleGUIEditMode()

    def enterGUIEditMode(self):
        """进入GUI编辑模式"""
        return self.gui_manager.enterGUIEditMode()

    def exitGUIEditMode(self):
        """退出GUI编辑模式"""
        return self.gui_manager.exitGUIEditMode()

    def createGUIEditPanel(self):
        """创建GUI编辑面板"""
        return self.gui_manager.createGUIEditPanel()

    def openGUIPreviewWindow(self):
        """打开独立的GUI预览窗口"""
        return self.gui_manager.openGUIPreviewWindow()

    def closeGUIPreviewWindow(self):
        """关闭GUI预览窗口"""
        return self.gui_manager.closeGUIPreviewWindow()

    # GUI工具和选择方法 - 代理到gui_manager
    def setGUICreateTool(self, tool_type):
        """设置GUI创建工具"""
        return self.gui_manager.setGUICreateTool(tool_type)

    def deleteSelectedGUI(self):
        """删除选中的GUI元素"""
        return self.gui_manager.deleteSelectedGUI()

    def copySelectedGUI(self):
        """复制选中的GUI元素"""
        return self.gui_manager.copySelectedGUI()

    def handleGUIEditClick(self, hitPos):
        """处理GUI编辑模式下的点击"""
        return self.gui_manager.handleGUIEditClick(hitPos)

    def createGUIAtPosition(self, world_pos, gui_type):
        """在指定位置创建GUI元素"""
        return self.gui_manager.createGUIAtPosition(world_pos, gui_type)

    def findClickedGUI(self, hitNode):
        """查找被点击的GUI元素"""
        return self.gui_manager.findClickedGUI(hitNode)

    def selectGUIInTree(self, gui_element):
        """在树形控件中选中GUI元素"""
        return self.gui_manager.selectGUIInTree(gui_element)

    def updateGUISelection(self, gui_element):
        """更新GUI元素选择状态"""
        return self.gui_manager.updateGUISelection(gui_element)

    # GUI属性面板方法 - 代理到gui_manager
    def selectGUIColor(self, gui_element):
        """选择GUI元素颜色"""
        return self.gui_manager.selectGUIColor(gui_element)

    def editGUI2DPosition(self, gui_element, axis, value):
        """编辑2D GUI元素位置"""
        return self.gui_manager.editGUI2DPosition(gui_element, axis, value)

    # ==================== 事件处理代理 ====================

    def onTreeItemClicked(self, item, column):
        """处理树形控件项目点击事件 - 代理到interface_manager"""
        return self.interface_manager.onTreeItemClicked(item, column)

    def setTreeWidget(self, treeWidget):
        """设置树形控件引用 - 代理到interface_manager"""
        return self.interface_manager.setTreeWidget(treeWidget)

    def mousePressEventLeft(self, evt):
        """处理鼠标左键按下事件 - 代理到event_handler"""
        return self.event_handler.mousePressEventLeft(evt)

    def mouseReleaseEventLeft(self, evt):
        """处理鼠标左键释放事件 - 代理到event_handler"""
        return self.event_handler.mouseReleaseEventLeft(evt)

    def wheelForward(self, data=None):
        """处理滚轮向前滚动（前进） - 代理到event_handler"""
        return self.event_handler.wheelForward(data)

    def wheelBackward(self, data=None):
        """处理滚轮向后滚动（后退） - 代理到event_handler"""
        return self.event_handler.wheelBackward(data)

    def mousePressEventMiddle(self, evt):
        """处理鼠标中键按下事件 - 代理到event_handler"""
        return self.event_handler.mousePressEventMiddle(evt)

    def mouseReleaseEventMiddle(self, evt):
        """处理鼠标中键释放事件 - 代理到event_handler"""
        return self.event_handler.mouseReleaseEventMiddle(evt)

    def mouseMoveEvent(self, evt):
        """处理鼠标移动事件 - 代理到event_handler"""
        return self.event_handler.mouseMoveEvent(evt)

    # ==================== 射线显示控制 ====================

    def toggleRayDisplay(self):
        """切换射线显示状态 - 代理到event_handler"""
        return self.event_handler.toggleRayDisplay()

    def setRayDisplay(self, show=True):
        """设置射线显示状态 - 代理到event_handler"""
        self.event_handler.showRay = show
        if not show:
            self.event_handler.clearRay()
        return show

    def getRayDisplay(self):
        """获取射线显示状态 - 代理到event_handler"""
        return self.event_handler.showRay

    def setRayLifetime(self, seconds):
        """设置射线显示时长（秒） - 代理到event_handler"""
        self.event_handler.rayLifetime = seconds
        print(f"射线显示时长设置为: {seconds}秒")

    def getRayLifetime(self):
        """获取射线显示时长 - 代理到event_handler"""
        return self.event_handler.rayLifetime

    # ==================== 属性面板代理 ====================

    def setPropertyLayout(self, layout):
        """设置属性面板布局引用 - 代理到property_panel"""
        return self.property_panel.setPropertyLayout(layout)

    def clearPropertyPanel(self):
        """清空属性面板 - 代理到property_panel"""
        return self.property_panel.clearPropertyPanel()

    def updatePropertyPanel(self, item):
        """更新属性面板显示 - 代理到property_panel"""
        return self.property_panel.updatePropertyPanel(item)

    def updateGUIPropertyPanel(self, gui_element):
        """更新GUI元素属性面板 - 代理到property_panel"""
        return self.property_panel.updateGUIPropertyPanel(gui_element)

    def removeActorForModel(self,model):
        return self.property_panel.removeActorForModel( model)

    def updateNodeVisibilityAfterDrag(self,item):
        return self.property_panel.updateNodeVisibilityAfterDrag(item)

    # ==================== 工具管理代理 ====================

    def setCurrentTool(self, tool):
        """设置当前工具 - 代理到tool_manager"""
        return self.tool_manager.setCurrentTool(tool)

    # ==================== 场景管理功能代理 ====================

    # 模型导入和处理方法 - 代理到scene_manager
    def importModel(self, filepath):
        """导入模型到场景"""
        # 自动转换FBX等格式为GLB以获得更好的动画支持（不再弹窗询问）
        # 如果你不想自动转换，可以将 auto_convert 改为 False
        auto_convert = False
        
        print(f"[模型导入] 文件: {filepath}, 自动转换GLB: {auto_convert}")
        
        return self.scene_manager.importModel(filepath, auto_convert_to_glb=auto_convert)

    def importModelAsync(self, filepath):
        """异步导入模型"""
        return self.scene_manager.importModelAsync(filepath)

    # 材质和几何体处理方法 - 代理到scene_manager
    def processMaterials(self, model):
        """处理模型材质"""
        return self.scene_manager.processMaterials(model)

    def processModelGeometry(self, model):
        """处理模型几何体"""
        return self.scene_manager.processModelGeometry(model)

    # 碰撞系统方法 - 代理到scene_manager
    def setupCollision(self, model):
        """为模型设置碰撞检测"""
        return self.scene_manager.setupCollision(model)

    # 场景树管理方法 - 代理到scene_manager
    def updateSceneTree(self):
        """更新场景树显示"""
        return self.scene_manager.updateSceneTree()

    # 场景保存和加载方法 - 代理到scene_manager
    def saveScene(self, filename):
        """保存场景到BAM文件"""
        return self.scene_manager.saveScene(filename)

    def loadScene(self, filename):
        """从BAM文件加载场景"""
        return self.scene_manager.loadScene(filename)

    # 模型管理方法 - 代理到scene_manager
    def deleteModel(self, model):
        """删除模型"""
        return self.scene_manager.deleteModel(model)

    def clearAllModels(self):
        """清除所有模型"""
        return self.scene_manager.clearAllModels()

    def getModels(self):
        """获取模型列表"""
        return self.scene_manager.getModels()

    def getModelCount(self):
        """获取模型数量"""
        return self.scene_manager.getModelCount()

    def findModelByName(self, name):
        """根据名称查找模型"""
        return self.scene_manager.findModelByName(name)

    # ==================== 脚本系统功能代理 ====================

    # 脚本系统控制方法 - 代理到script_manager
    def startScriptSystem(self):
        """启动脚本系统"""
        return self.script_manager.start_system()

    def stopScriptSystem(self):
        """停止脚本系统"""
        return self.script_manager.stop_system()

    def enableHotReload(self, enabled=True):
        """启用/禁用热重载"""
        self.script_manager.hot_reload_enabled = enabled
        if enabled:
            self.script_manager.start_hot_reload()
        else:
            self.script_manager.stop_hot_reload()

    # 脚本创建和加载方法 - 代理到script_manager
    def createScript(self, script_name, template="basic"):
        """创建新脚本文件"""
        return self.script_manager.create_script_file(script_name, template)

    def loadScript(self, script_path):
        """从文件加载脚本"""
        return self.script_manager.load_script_from_file(script_path)

    def loadAllScripts(self, directory=None):
        """从目录加载所有脚本"""
        return self.script_manager.load_all_scripts_from_directory(directory)

    def reloadScript(self, script_name):
        """重新加载脚本"""
        return self.script_manager.reload_script(script_name)

    # 脚本挂载和管理方法 - 代理到script_manager
    def addScript(self, game_object, script_name):
        """为游戏对象添加脚本"""
        return self.script_manager.add_script_to_object(game_object, script_name)

    def removeScript(self, game_object, script_name):
        """从游戏对象移除脚本"""
        return self.script_manager.remove_script_from_object(game_object, script_name)

    def getScripts(self, game_object):
        """获取对象上的所有脚本"""
        return self.script_manager.get_scripts_on_object(game_object)

    def getScript(self, game_object, script_name):
        """获取对象上的特定脚本"""
        return self.script_manager.get_script_on_object(game_object, script_name)

    # 脚本信息查询方法 - 代理到script_manager
    def getAvailableScripts(self):
        """获取所有可用的脚本名称"""
        return self.script_manager.get_available_scripts()

    def getScriptInfo(self, script_name):
        """获取脚本信息"""
        return self.script_manager.get_script_info(script_name)

    def listAllScripts(self):
        """列出所有脚本信息"""
        return self.script_manager.list_all_scripts()

    def loadCesiumTileset(self,tileset_url,position=(0,0,0)):
        return self.scene_manager.load_cesium_tileset(tileset_url,position)

    def addCesiumTileset(self,name,url,position=(0,0,0)):
        if hasattr(self,'gui_manager') and self.gui_manager:
            return self.gui_manager.addCesiumTilesetToScene(name,url,position)
        else:
            return self.scene_manager.load_cesium_tileset(url,position)

    # ==================== 地形管理功能代理 ====================
    # 地形创建方法 - 代理到terrain_manager
    def createTerrainFromHeightMap(self, heightmap_path, scale=(1, 1, 1)):
        """从高度图创建地形"""
        return self.terrain_manager.createTerrainFromHeightMap(heightmap_path, scale)

    def createFlatTerrain(self, size=(0.3, 0.3), resolution=256):
        """创建平面地形"""
        return self.terrain_manager.createFlatTerrain(size, resolution)

    def updateTerrain(self):
        """更新所有地形的LOD"""
        return self.terrain_manager.updateTerrain()

    def getTerrainHeight(self, terrain_info, x, y):
        """获取地形上指定点的高度"""
        return self.terrain_manager.getTerrainHeight(terrain_info, x, y)

    def setTerrainEditParameters(self,radius=None,strength=None,operation=None):
        if radius is not None:
            self.terrain_edit_radius = float(radius)
        if strength is not None:
            self.terrain_edit_strenght = float(strength)
        if operation is not None:
            self.terrain_edit_operation = operation
        print(f"地形编辑参数已更新: 半径={self.terrain_edit_radius}, 强度={self.terrain_edit_strength}, 操作={self.terrain_edit_operation}")
    def getTerrainEditParameters(self):
        """获取当前地形编辑参数"""
        return {
            'radius': self.terrain_edit_radius,
            'strength': self.terrain_edit_strength,
            'operation': self.terrain_edit_operation
        }

    def modifyTerrainHeight(self, terrain_info, x, y, radius, strength, operation="add"):
        """修改地形高度的便捷方法"""
        if hasattr(self, 'terrain_manager'):
            return self.terrain_manager.modifyTerrainHeight(terrain_info, x, y, radius, strength, operation)
        return False

    # ==================== 信息面板管理功能代理 ====================
    
    def create2DSamplePanel(self):
        """创建2D示例面板"""
        try:
            from core.InfoPanelManager import createSampleInfoPanel
            result = createSampleInfoPanel(self.render)
            return result
        except Exception as e:
            print(f"创建2D示例面板失败: {e}")
            return None
    
    def create3DSamplePanel(self):
        """创建3D实例面板"""
        try:
            if hasattr(self, 'info_panel_manager') and self.info_panel_manager:
                # 创建3D信息面板
                panel_id = f"3d_sample_{int(time.time())}"
                result = self.info_panel_manager.create3DInfoPanel(
                    panel_id=panel_id,
                    position=(0, 0, 2),
                    size=(1.0, 0.6),
                    bg_color=(0.15, 0.25, 0.35, 0.95),
                    border_color=(0.3, 0.5, 0.7, 1.0),
                    title_color=(0.7, 0.9, 1.0, 1.0),
                    content_color=(0.95, 0.95, 0.95, 1.0)
                )
                
                # 添加示例内容
                if result:
                    sample_data = {
                        "标题": "3D信息面板",
                        "状态": "运行中",
                        "创建时间": time.strftime("%Y-%m-%d %H:%M:%S"),
                        "位置": f"X:0, Y:0, Z:2"
                    }
                    self.info_panel_manager.updatePanelContent(panel_id, content=sample_data)
                
                return result
            return None
        except Exception as e:
            print(f"创建3D示例面板失败: {e}")
            return None
    
    def createWebPanel(self, url="https://www.example.com"):
        """创建Web面板"""
        try:
            if hasattr(self, 'info_panel_manager') and self.info_panel_manager:
                panel_id = f"web_panel_{int(time.time())}"
                result = self.info_panel_manager.createHTTPInfoPanel(
                    panel_id=panel_id,
                    url=url,
                    position=(0.8, 0.0),
                    size=(0.35, 0.4),
                    update_interval=5.0  # 每5秒更新一次
                )
                return result
            return None
        except Exception as e:
            print(f"创建Web面板失败: {e}")
            return None

    # ==================== 3D对象和GUI创建功能代理 ====================
    
    def createEmptyObject(self):
        """创建空对象"""
        try:
            from panda3d.core import NodePath
            # 创建一个空节点
            empty_node = NodePath("EmptyObject")
            empty_node.reparentTo(self.render)
            empty_node.setPos(0, 0, 0)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(empty_node)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print("✓ 空对象创建成功")
            return empty_node
        except Exception as e:
            print(f"✗ 创建空对象失败: {e}")
            return None
    
    def create3DText(self, pos=(0, 0, 0), text="3D Text", scale=1.0):
        """创建3D文本"""
        try:
            from panda3d.core import TextNode, NodePath
            
            # 创建文本节点
            text_node = TextNode("3DText")
            text_node.setText(text)
            text_node.setAlign(TextNode.ACenter)
            text_node.setTextColor(1, 1, 1, 1)  # 白色
            
            # 创建节点路径并设置位置
            text_np = NodePath(text_node)
            text_np.reparentTo(self.render)
            text_np.setPos(pos)
            text_np.setScale(scale)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(text_np)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print(f"✓ 3D文本创建成功: {text}")
            return text_np
        except Exception as e:
            print(f"✗ 创建3D文本失败: {e}")
            return None
    
    def create3DImage(self, pos=(0, 0, 0), image_path="", size=(1, 1)):
        """创建3D图片"""
        try:
            from panda3d.core import CardMaker, NodePath
            
            if not image_path or not os.path.exists(image_path):
                print("✗ 图片文件不存在")
                return None
            
            # 创建卡片几何体
            card_maker = CardMaker("3DImage")
            card_maker.setFrame(-size[0]/2, size[0]/2, -size[1]/2, size[1]/2)
            card = card_maker.generate()
            
            # 创建节点路径
            image_np = NodePath(card)
            image_np.reparentTo(self.render)
            image_np.setPos(pos)
            
            # 加载纹理
            from panda3d.core import Texture, Filename
            tex = self.loader.loadTexture(Filename.fromOsSpecific(image_path))
            if tex:
                image_np.setTexture(tex, 1)
            else:
                print("✗ 加载纹理失败")
                image_np.removeNode()
                return None
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(image_np)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print(f"✓ 3D图片创建成功: {os.path.basename(image_path)}")
            return image_np
        except Exception as e:
            print(f"✗ 创建3D图片失败: {e}")
            return None
    
    def createCube(self, pos=(0, 0, 0), size=1.0):
        """创建立方体"""
        try:
            from panda3d.core import NodePath
            
            # 创建立方体模型
            cube = self.loader.loadModel("models/environment")
            if not cube:
                # 如果没有默认模型，创建一个简单的立方体
                from panda3d.core import CardMaker
                card_maker = CardMaker("Cube")
                card_maker.setFrame(-size/2, size/2, -size/2, size/2)
                cube = NodePath(card_maker.generate())
            
            cube.reparentTo(self.render)
            cube.setPos(pos)
            cube.setScale(size)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(cube)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print("✓ 立方体创建成功")
            return cube
        except Exception as e:
            print(f"✗ 创建立方体失败: {e}")
            return None
    
    def createSphere(self, pos=(0, 0, 0), radius=1.0):
        """创建球体"""
        try:
            from panda3d.core import NodePath
            
            # 创建球体模型
            sphere = self.loader.loadModel("models/environment")
            if not sphere:
                # 如果没有默认模型，创建一个简单的球体
                from panda3d.core import CardMaker
                card_maker = CardMaker("Sphere")
                card_maker.setFrame(-radius, radius, -radius, radius)
                sphere = NodePath(card_maker.generate())
            
            sphere.reparentTo(self.render)
            sphere.setPos(pos)
            sphere.setScale(radius)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(sphere)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print("✓ 球体创建成功")
            return sphere
        except Exception as e:
            print(f"✗ 创建球体失败: {e}")
            return None
    
    def createCylinder(self, pos=(0, 0, 0), radius=1.0, height=2.0):
        """创建圆柱体"""
        try:
            from panda3d.core import NodePath
            
            # 创建圆柱体模型
            cylinder = self.loader.loadModel("models/environment")
            if not cylinder:
                # 如果没有默认模型，创建一个简单的圆柱体
                from panda3d.core import CardMaker
                card_maker = CardMaker("Cylinder")
                card_maker.setFrame(-radius, radius, -height/2, height/2)
                cylinder = NodePath(card_maker.generate())
            
            cylinder.reparentTo(self.render)
            cylinder.setPos(pos)
            cylinder.setScale(radius, radius, height)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(cylinder)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print("✓ 圆柱体创建成功")
            return cylinder
        except Exception as e:
            print(f"✗ 创建圆柱体失败: {e}")
            return None
    
    def createPlane(self, pos=(0, 0, 0), size=(1, 1)):
        """创建平面"""
        try:
            from panda3d.core import CardMaker, NodePath
            
            # 创建平面
            card_maker = CardMaker("Plane")
            card_maker.setFrame(-size[0]/2, size[0]/2, -size[1]/2, size[1]/2)
            plane = NodePath(card_maker.generate())
            
            plane.reparentTo(self.render)
            plane.setPos(pos)
            
            # 添加到场景管理器
            if hasattr(self, 'scene_manager') and self.scene_manager:
                self.scene_manager.models.append(plane)
            
            # 更新场景树
            if hasattr(self, 'updateSceneTree'):
                self.updateSceneTree()
            
            print("✓ 平面创建成功")
            return plane
        except Exception as e:
            print(f"✗ 创建平面失败: {e}")
            return None

    # 添加碰撞管理相关的代理方法
    def enableModelCollisionDetection(self, enable=True, frequency=0.1, threshold=0.5):
        """启用模型间碰撞检测"""
        return self.collision_manager.enableModelCollisionDetection(enable, frequency, threshold)

    def detectModelCollisions(self, specific_models=None, log_results=True):
        """检测模型间碰撞"""
        return self.collision_manager.detectModelCollisions(specific_models, log_results)

    def getCollisionHistory(self, limit=None):
        """获取碰撞历史"""
        return self.collision_manager.getCollisionHistory(limit)

    def getCollisionStatistics(self):
        """获取碰撞统计"""
        return self.collision_manager.getCollisionStatistics()

    def setupKeyboardEvents(self):
        """设置键盘事件"""
        try:
            # 绑定 F 键用于聚焦选中节点
            self.accept("f", self.onFocusKeyPressed)
            self.accept("F", self.onFocusKeyPressed)  # 大写F

            print("✓ 键盘事件绑定完成")

        except Exception as e:
            print(f"设置键盘事件失败: {e}")

    def onFocusKeyPressed(self):
        """处理 F 键按下事件"""
        try:
            #print("检测到 F 键按下")

            # 检查是否有选中的节点
            if hasattr(self, 'selection') and self.selection.selectedNode:
                #print(f"当前选中节点: {self.selection.selectedNode.getName()}")
                # 调用选择系统的聚焦功能（可以选择带动画或不带动画的版本）
                # self.selection.focusCameraOnSelectedNode()  # 无动画版本
                self.selection.focusCameraOnSelectedNodeAdvanced()  # 带动画版本
            else:
                print("当前没有选中任何节点")

        except Exception as e:
            print(f"处理 F 键事件失败: {e}")

    def onPatrolKeyPressed(self):
        """处理 P 键按下事件 - 控制巡检系统"""
        try:
            print("检测到 P 键按下")

            if not self.patrol_system.is_patrolling:
                # 如果巡检系统没有点，创建默认巡检路线
                if not self.patrol_system.patrol_points:
                    self.createDefaultPatrolRoute()

                # 开始巡检
                if self.patrol_system.start_patrol():
                    print("✓ 巡检已开始")
                else:
                    print("✗ 巡检启动失败")
            else:
                # 停止巡检
                if self.patrol_system.stop_patrol():
                    print("✓ 巡检已停止")
                else:
                    print("✗ 巡检停止失败")

        except Exception as e:
            print(f"处理 P 键事件失败: {e}")

    def createDefaultPatrolRoute(self):
        """创建默认巡检路线（使用自动朝向）"""
        try:
            # 清空现有巡检点
            self.patrol_system.clear_patrol_points()

            # 添加巡检点，使用None表示朝向下一个点
            self.patrol_system.add_patrol_point((0, -10, 2), (0,0,0), 1.5)
            self.patrol_system.add_patrol_point((10, -10, 2), (0,0,0), 1.5)
            self.patrol_system.add_patrol_point((10, 5, 2), (0,0,0), 1.5)
            self.patrol_system.add_patrol_point((10, 0, 5), (0,0,0), 1.5)

            # 最后一个点可以指定特定的朝向，或者也设为None继续循环
            self.patrol_system.add_patrol_point((0, -10, 2), None, 2.5)

            print("✓ 默认自动朝向巡检路线已创建")
            self.patrol_system.list_patrol_points()

        except Exception as e:
            print(f"创建默认自动朝向巡检路线失败: {e}")

    def _serializeNode(self, node):
        """序列化节点数据"""
        try:
            return self.world.scene_manager.serializeNode(node)
        except Exception as e:
            print(f"序列化节点失败: {e}")
            return None

    def _deserializeNode(self, node_data, parent_node):
        """反序列化节点数据"""
        try:
            return self.world.scene_manager.deserializeNode(node_data, parent_node)
        except Exception as e:
            print(f"反序列化节点失败: {e}")
            return None


# ==================== 项目管理功能代理 ====================
# 以下函数代理到project_manager模块的对应功能

def updateWindowTitle(window, project_name=None):
    """更新窗口标题 - 代理到project_manager"""
    from project.project_manager import updateWindowTitle as pm_updateWindowTitle
    return pm_updateWindowTitle(window, project_name)

def createNewProject(parent_window):
    """创建新项目 - 代理到project_manager"""
    world = parent_window.centralWidget().world
    return world.project_manager.createNewProject(parent_window)

def saveProject(appw):
    """保存项目 - 代理到project_manager"""

    world = appw.centralWidget().world
    return world.project_manager.saveProject(appw)

def openProject(appw):
    """打开项目 - 代理到project_manager"""
    world = appw.centralWidget().world
    return world.project_manager.openProject(appw)

def openProjectForPath(project_path, appw):
    """打开项目 - 代理到project_manager"""
    world = appw.centralWidget().world
    return world.project_manager.openProjectForPath(project_path, appw)

def buildPackage(appw):
    """打包项目 - 代理到project_manager"""
    world = appw.centralWidget().world
    return world.project_manager.buildPackage(appw)

def run(args = None):
    print(f'Path is {args}')
    print("引擎已启动（使用Panda3D原生窗口）")
    
    # 创建世界实例并运行
    world = MyWorld()
    world.run()

if __name__ == "__main__":
    run()