import os
import sys
import json
import datetime
import subprocess
import shutil

class ProjectManager:

    def __init__(self, world):
        self.world = world
        self.current_project_path = None
        self.project_config = None
        
        print("✓ 项目管理系统初始化完成")
    
    # ==================== 项目生命周期管理 ====================
    
    def createNewProject(self, project_path, project_name):
        """创建新项目
        
        Args:
            project_path: 项目路径
            project_name: 项目名称
            
        Returns:
            bool: 创建是否成功
        """
        if not project_path or not project_name:
            print("错误: 项目路径和名称不能为空")
            return False
            
        # full_project_path = os.path.join(project_path, project_name)
        full_project_path = os.path.normpath(os.path.join(project_path, project_name))
        print(f"full_project_path: {full_project_path}")
        
        try:
            # 创建项目文件夹结构
            os.makedirs(full_project_path)
            os.makedirs(os.path.join(full_project_path, "models"))  # 模型文件夹
            os.makedirs(os.path.join(full_project_path, "textures"))  # 贴图文件夹
            scenes_path = os.path.join(full_project_path, "scenes")  # 场景文件夹
            os.makedirs(scenes_path)
            
            # 创建项目配置文件
            project_config = {
                "name": project_name,
                "path": full_project_path,
                "created_at": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "last_modified": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                "version": "1.0.0",
                "engine_version": "1.0.0"
            }
            
            config_file = os.path.join(full_project_path, "project.json")
            with open(config_file, "w", encoding="utf-8") as f:
                json.dump(project_config, f, ensure_ascii=False, indent=4)
                
            print(f"项目配置文件已创建: {config_file}")

            # 清空当前场景
            self._clearCurrentScene()

            # 自动保存初始场景
            scene_file = os.path.join(scenes_path, "scene.bam")
            if self.world.scene_manager.saveScene(scene_file, project_path):
                # 更新配置文件中的场景路径
                project_config["scene_file"] = os.path.relpath(scene_file, full_project_path)
                with open(config_file, "w", encoding="utf-8") as f:
                    json.dump(project_config, f, ensure_ascii=False, indent=4)
                print(f"初始场景已保存到: {scene_file}")
            else:
                print("初始场景保存失败")
                
            # 更新项目状态
            self.current_project_path = full_project_path
            self.project_config = project_config
            
            print(f"项目 '{project_name}' 创建成功!")
            return True
            
        except Exception as e:
            print(f"创建项目失败: {str(e)}")
            return False
    
    def openProject(self, project_path):
        """打开项目
        
        Args:
            project_path: 项目路径
            
        Returns:
            bool: 打开是否成功
        """
        # print(f"\n[DEBUG] ===== 开始打开项目: {project_path} =====")
        try:
            if not project_path:
                print("错误: 项目路径不能为空")
                return False

            # 检查是否是有效的项目文件夹
            config_file = os.path.join(project_path, "project.json")
            # print(f"[DEBUG] 项目配置文件路径: {config_file}")
            # print(f"[DEBUG] 配置文件是否存在: {os.path.exists(config_file)}")
            
            if not os.path.exists(config_file):
                print("错误: 选择的不是有效的项目文件夹！")
                return False

            # 读取项目配置
            # print(f"[DEBUG] 开始读取项目配置文件...")
            with open(config_file, "r", encoding="utf-8") as f:
                project_config = json.load(f)
            # print(f"[DEBUG] 项目配置读取成功: {project_config.get('name', 'Unknown')}")

            # 检查场景文件
            scene_file = os.path.join(project_path, "scenes", "scene.bam")
            # print(f"[DEBUG] 场景文件路径: {scene_file}")
            # print(f"[DEBUG] 场景文件是否存在: {os.path.exists(scene_file)}")
            
            if os.path.exists(scene_file):
                # 加载场景前的安全检查
                # print(f"[DEBUG] 开始加载场景文件...")
                # print(f"[DEBUG] 当前world状态检查:")
                # print(f"[DEBUG] - render节点存在: {hasattr(self.world, 'render') and self.world.render is not None}")
                # print(f"[DEBUG] - loader存在: {hasattr(self.world, 'loader') and self.world.loader is not None}")
                # print(f"[DEBUG] - scene_manager存在: {hasattr(self.world, 'scene_manager') and self.world.scene_manager is not None}")
                
                # 检查world的基本状态
                if not hasattr(self.world, 'render') or self.world.render is None:
                    # print(f"[DEBUG] 错误: world.render不存在或为None")
                    return False
                    
                if not hasattr(self.world, 'loader') or self.world.loader is None:
                    # print(f"[DEBUG] 错误: world.loader不存在或为None")
                    return False
                
                # 清理可能的残留状态
                try:
                    # 清理选择状态
                    if hasattr(self.world, 'selection') and self.world.selection:
                        self.world.selection.clearSelection()
                        # print(f"[DEBUG] 选择状态已清理")
                    
                    # 清理GUI状态
                    if hasattr(self.world, 'gui_elements'):
                        for gui_elem in self.world.gui_elements:
                            if gui_elem and not gui_elem.isEmpty():
                                gui_elem.detachNode()
                        self.world.gui_elements.clear()
                        # print(f"[DEBUG] GUI元素已清理")
                    
                    # 验证BAM文件
                    # print(f"[DEBUG] 验证BAM文件完整性...")
                    if os.path.getsize(scene_file) == 0:
                        # print(f"[DEBUG] 错误: BAM文件为空")
                        return False
                    
                    # 检查文件权限
                    if not os.access(scene_file, os.R_OK):
                        # print(f"[DEBUG] 错误: BAM文件不可读")
                        return False
                        
                    # print(f"[DEBUG] BAM文件验证通过")
                        
                except Exception as e:
                    # print(f"[DEBUG] 清理状态时发生异常: {e}")
                    return False
                
                if self.world.scene_manager.loadScene(scene_file):
                    # print(f"[DEBUG] 场景加载成功")
                    # 更新项目配置
                    project_config["scene_file"] = os.path.relpath(scene_file, project_path)
                else:
                    # print(f"[DEBUG] 场景加载失败")
                    return False
            else:
                # print(f"[DEBUG] 场景文件不存在，跳过场景加载")
                pass

            project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            with open(config_file, "w", encoding="utf-8") as f:
                json.dump(project_config, f, ensure_ascii=False, indent=4)

            # 更新项目状态
            self.current_project_path = project_path
            self.project_config = project_config

            # print(f"[DEBUG] ===== 项目打开成功: {project_path} =====")
            print("项目加载成功！")
            return True

        except Exception as e:
            # print(f"[DEBUG] ===== 项目打开失败 =====")
            print(f"加载项目时发生错误：{str(e)}")
            import traceback
            traceback.print_exc()
            return False

    def openProjectForPath(self, project_path):
        """通过路径打开项目

        Args:
            project_path: 项目路径
            
        Returns:
            bool: 打开是否成功
        """
        try:
            if not project_path:
                return False
            # 检查是否是有效的项目文件夹
            config_file = os.path.join(project_path, "project.json")
            if not os.path.exists(config_file):
                print("警告: 选择的不是有效的项目文件夹！")
                return False

            # 读取项目配置
            with open(config_file, "r", encoding="utf-8") as f:
                project_config = json.load(f)

            # 检查场景文件
            scene_file = os.path.join(project_path, "scenes", "scene.bam")
            if os.path.exists(scene_file):
                # 加载场景
                if self.world.scene_manager.loadScene(scene_file):
                    # 更新项目配置
                    project_config["scene_file"] = os.path.relpath(scene_file, project_path)

            project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            with open(config_file, "w", encoding="utf-8") as f:
                json.dump(project_config, f, ensure_ascii=False, indent=4)

            # 更新项目状态
            self.current_project_path = project_path
            self.project_config = project_config

            print(f"项目 '{project_path}' 加载成功！")
            return True

        except Exception as e:
            error_msg = f"加载项目时发生错误：{str(e)}"
            print(error_msg)
            return False

    def saveProject(self):
        """保存项目
        
        Returns:
            bool: 保存是否成功
        """
        try:
            # 检查是否有当前项目路径
            if not self.current_project_path:
                print("错误: 请先创建或打开一个项目！")
                return False
                    
            project_path = self.current_project_path
            scenes_path = os.path.join(project_path, "scenes")
            
            # 固定的场景文件名
            scene_file = os.path.join(scenes_path, "scene.bam")
            
            # 如果存在旧文件，先删除
            if os.path.exists(scene_file):
                try:
                    os.remove(scene_file)
                    print(f"已删除旧场景文件: {scene_file}")
                except Exception as e:
                    print(f"删除旧场景文件失败: {str(e)}")
                    return False
            
            # 保存场景
            if self.world.scene_manager.saveScene(scene_file, project_path):
                # 更新项目配置文件
                config_file = os.path.join(project_path, "project.json")
                if os.path.exists(config_file):
                    with open(config_file, "r", encoding="utf-8") as f:
                        project_config = json.load(f)
                    
                    # 更新最后修改时间
                    project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    # 记录场景文件路径
                    project_config["scene_file"] = os.path.relpath(scene_file, project_path)
                    
                    with open(config_file, "w", encoding="utf-8") as f:
                        json.dump(project_config, f, ensure_ascii=False, indent=4)
                
                # 更新项目配置
                self.project_config = project_config
                
                print("项目保存成功！")
                return True
            else:
                print("错误: 保存场景失败！")
                return False
                
        except Exception as e:
            print(f"保存项目时发生错误：{str(e)}")
            return False
    
    # ==================== 项目打包功能 ====================
    
    def buildPackage(self, build_dir):
        """打包项目为可执行文件 - 按照Panda3D官方标准方法
        
        Args:
            build_dir: 打包输出目录
            
        Returns:
            bool: 打包是否成功
        """
        try:
            # 检查是否有当前项目路径
            if not self.current_project_path:
                print("错误: 请先创建或打开一个项目！")
                return False
                    
            project_path = self.current_project_path
            scenes_path = os.path.join(project_path, "scenes")
            scene_file = os.path.join(scenes_path, "scene.bam")
            
            # 检查场景文件是否存在
            if not os.path.exists(scene_file):
                print("错误: 请先保存场景！")
                return False

            if hasattr(self.world,'selection') and self.world.selection:
                self.world.selection.clearSelection()
                print("已取消场景中的物体选中状态")

            if self.world.scene_manager.saveScene(scene_file, project_path):
                print("场景保存成功")
                config_file = os.path.join(project_path,"project.json")
                if os.path.exists(config_file):
                    with open(config_file,"r",encoding="utf-8") as f:
                        project_config = json.load(f)

                        project_config["last_modified"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        project_config["scene_file"] = os.path.relpath(scene_file,project_path)

                        with open(config_file,"w",encoding = "utf-8") as f:
                            json.dump(project_config,f,ensure_ascii = False,indent=4)

                self.project_config = project_config

                project_name = os.path.basename(project_path)
            else:
                print("错误: 保存场景失败！")
                return False

            if not build_dir:
                print("错误: 请指定打包输出目录！")
                return False
                
            # 创建构建目录
            build_dir = os.path.join(build_dir, "build")

            if not os.path.exists(build_dir):
                os.makedirs(build_dir)
                
            # 创建标准的打包文件
            self._createStandardBuildFiles(build_dir, project_path, scene_file)
            
            # 执行打包命令
            success = self._executeStandardBuild(build_dir)
            
            if success:
                # 根据操作系统创建对应的启动脚本文件
                try:
                    import stat
                    # 检查操作系统类型
                    if os.name == 'nt':  # Windows系统
                        run_bat_path = os.path.join(build_dir, "run.bat")
                        with open(run_bat_path, "w") as f:
                            f.write("@echo off\n")
                            f.write("python main.py %*\n")
                    else:  # Unix-like系统 (Linux, macOS等)
                        run_sh_path = os.path.join(build_dir, "run.sh")
                        with open(run_sh_path, "w") as f:
                            f.write("#!/bin/bash\n")
                            f.write("python3.10 main.py \"$@\"\n")
                        
                        # 为Unix-like系统添加执行权限
                        st = os.stat(run_sh_path)
                        os.chmod(run_sh_path, st.st_mode | stat.S_IEXEC)
                except Exception as e:
                    print(f"创建启动脚本文件失败: {str(e)}")
                
                print("打包完成！可执行文件在 build 目录中。")
                return True
            else:
                return False

        except Exception as e:
            print(f"打包过程出错：{str(e)}")
            return False
    
    def _createStandardBuildFiles(self, build_dir, project_path, scene_file):
        """创建标准的Panda3D打包文件"""
        project_name = os.path.basename(project_path)
        
        # 确保构建目录存在
        if not os.path.exists(build_dir):
            os.makedirs(build_dir)
        
        # 复制场景文件到构建目录
        shutil.copy2(scene_file, os.path.join(build_dir, "scene.bam"))

        # 复制Resources文件夹到build目录
        source_resources = os.path.join(project_path, "scenes", "resources")
        self.copy_folder(source_resources, build_dir)

        self._saveGUIElementsToJSON(build_dir, project_path)

        self._copyScriptsToBuild(build_dir, project_path)

        self._copyScriptSystemToBuild(build_dir)

        source_render_pipeline = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),"RenderPipelineFile")
        dest_render_pipeline = os.path.join(build_dir,"RenderPipelineFile")

        if os.path.exists(source_render_pipeline):
            if os.path.exists(dest_render_pipeline):
                shutil.rmtree(dest_render_pipeline)

            shutil.copytree(
                source_render_pipeline,
                dest_render_pipeline,
                ignore=shutil.ignore_patterns('__pycache__','*.pyc','.git','.vscode','*.log','samples')
            )
            print("✓ RenderPipelineFile文件夹已复制到build目录")
        else:
            print("⚠️ RenderPipelineFile文件夹未找到")

        # 创建标准的应用程序入口文件
        self._createAppFile(build_dir, project_name)
        
        # 创建标准的setup.py文件
        self._createStandardSetupFile(build_dir, project_name)

        #创建requirements.txt文件
        self._createRequirementsFile(build_dir)

    def _copyScriptsToBuild(self, build_dir, project_path):
        """复制脚本文件到构建目录的scripts文件夹"""
        try:
            # 创建目标scripts目录
            scripts_dest = os.path.join(build_dir, "scripts")

            # 正确的源scripts目录路径
            scripts_src = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "scripts")

            # 如果上面的路径不存在，尝试项目路径下的scripts目录
            if not os.path.exists(scripts_src):
                scripts_src = os.path.join(project_path, "scripts")

            if os.path.exists(scripts_src):
                # 直接复制整个scripts目录
                if os.path.exists(scripts_dest):
                    shutil.rmtree(scripts_dest)

                shutil.copytree(
                    scripts_src,
                    scripts_dest,
                    ignore=shutil.ignore_patterns('__pycache__', '*.pyc', '.git', '.vscode', '*.log')
                )
                print("✓ Scripts目录已复制到build/scripts")
            else:
                # 创建空的scripts目录
                if not os.path.exists(scripts_dest):
                    os.makedirs(scripts_dest)
                print("⚠️ 项目中没有scripts目录")

        except Exception as e:
            print(f"⚠️ 复制脚本文件时出错: {str(e)}")

    def _copyScriptSystemToBuild(self,build_dir):
            core_files = [
                "script_system.py",
                "InfoPanelManager.py",
                "CustomMouseController.py"
            ]

            source_core_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),"core")

            core_dest = os.path.join(build_dir,"core")

            if not os.path.exists(core_dest):
                os.makedirs(core_dest)

            for file_name in core_files:
                source_file = os.path.join(source_core_dir,file_name)

                if os.path.exists(source_file):
                    shutil.copy2(source_file,os.path.join(core_dest,file_name))

    def _saveGUIElementsToJSON(self, build_dir, project_path):
        """保存GUI元素到JSON文件，内容与_collectGUIElementInfo保持一致"""
        try:
            # 创建目标gui目录
            gui_dest = os.path.join(build_dir, "gui")
            if not os.path.exists(gui_dest):
                os.makedirs(gui_dest)

            # 收集所有GUI元素信息
            gui_data = []

            # 获取当前场景中的GUI元素
            if hasattr(self.world, 'gui_elements'):
                for gui_node in self.world.gui_elements:
                    if gui_node and not gui_node.isEmpty():
                        # 使用_collectGUIElementInfo方法收集信息
                        gui_info = self.world.scene_manager._collectGUIElementInfo(gui_node)
                        if gui_info:
                            self._updateResourcePaths(gui_info,project_path,build_dir)
                            gui_data.append(gui_info)
                            print(f"收集GUI元素信息: {gui_info['name']}")

            # 保存GUI信息到JSON文件
            gui_file_path = os.path.join(gui_dest, "gui_elements.json")
            with open(gui_file_path, "w", encoding="utf-8") as f:
                json.dump(gui_data, f, ensure_ascii=False, indent=4)

            print(f"✓ GUI元素数据已保存到 {gui_file_path}，共 {len(gui_data)} 个元素")
            return True

        except Exception as e:
            print(f"⚠️ 保存GUI元素时出错: {str(e)}")
            import traceback
            traceback.print_exc()
            return False

    def _updateResourcePaths(self,gui_info,project_path,build_dir):
        def normalize_resource_path(old_path):
            if not old_path:
                return old_path

            if old_path.startswith(("http://","https://")):
                return old_path

            if os.path.isabs(old_path):
                try:
                    rel_path = os.path.relpath(old_path,project_path)
                    return os.path.join("resources",os.path.basename(rel_path)).replace("\\","/")
                except Exception:
                    return os.path.join("resources",os.path.basename(old_path)).replace("\\","/")
            else:
                return os.path.join("resources",os.path.basename(old_path)).replace("\\","/")
        if "image_path" in gui_info and gui_info["image_path"]:
            gui_info["image_path"] = normalize_resource_path(gui_info["image_path"])
        if "video_path" in gui_info and gui_info["video_path"]:
            gui_info["video_path"] = normalize_resource_path(gui_info["video_path"])
        if "bg_image_path" in gui_info and gui_info["bg_image_path"]:
            gui_info["bg_image_path"] = normalize_resource_path(gui_info["bg_image_path"])

    def _createRequirementsFile(self,build_dir):
        requirements_content = """panda3d>=1.10.13"""

        requirements_path = os.path.join(build_dir,"requirements.txt")
        with open(requirements_path,"w",encoding="utf-8") as f:
            f.write(requirements_content)

    def copy_folder(self, source_folder, destination_folder):
        """将一个文件夹从源路径复制到目标路径下的resources文件夹中

        Args:
            source_folder (str): 源文件夹路径
            destination_folder (str): 目标文件夹路径
        """
        try:
            # 创建resources文件夹作为目标
            resources_dest = os.path.join(destination_folder, "resources")

            # 确保目标目录存在
            if not os.path.exists(destination_folder):
                os.makedirs(destination_folder)

            # 如果目标resources文件夹已存在，先删除
            if os.path.exists(resources_dest):
                shutil.rmtree(resources_dest)

            # 检查源文件夹是否存在
            if os.path.exists(source_folder):
                # 复制整个文件夹到resources目录下
                shutil.copytree(
                    source_folder,
                    resources_dest,
                    ignore=shutil.ignore_patterns('__pycache__', '*.pyc', '.git', '.vscode', '*.log')
                )
                print(f"✓ 文件夹已从 {source_folder} 复制到 {resources_dest}")
                return True
            else:
                print(f"⚠️ 源文件夹不存在: {source_folder}")
                # 即使源文件夹不存在，也创建空的resources目录
                if not os.path.exists(resources_dest):
                    os.makedirs(resources_dest)
                return False

        except Exception as e:
            print(f"⚠️ 复制文件夹时出错: {str(e)}")
            return False

    def _copyResourcesToBuild(self, build_dir, project_path):
        """复制GUI资源到构建目录的resources文件夹"""
        try:
            # 创建目标resources目录
            resources_dest = os.path.join(build_dir, "resources")

            # 源Resources目录
            resources_src = os.path.join(project_path, "Resources")

            if os.path.exists(resources_src):
                # 直接复制整个Resources目录
                if os.path.exists(resources_dest):
                    shutil.rmtree(resources_dest)

                shutil.copytree(
                    resources_src,
                    resources_dest,
                    ignore=shutil.ignore_patterns('__pycache__', '*.pyc', '.git', '.vscode', '*.log')
                )
                print("✓ Resources目录已复制到build/resources")

                # 统计复制的文件数量
                file_count = 0
                for root, dirs, files in os.walk(resources_dest):
                    file_count += len(files)
                print(f"✓ 共复制了 {file_count} 个资源文件")
            else:
                # 创建空的resources目录
                if not os.path.exists(resources_dest):
                    os.makedirs(resources_dest)
                print("⚠️ 项目中没有Resources目录")

        except Exception as e:
            print(f"⚠️ 复制资源文件时出错: {str(e)}")

    def _collectResourceFiles(self, project_path):
        """收集项目中GUI使用的资源文件"""
        resource_files = set()

        try:
            # 收集Resources目录中的所有文件（这是最主要的资源来源）
            resources_dir = os.path.join(project_path, "Resources")
            if os.path.exists(resources_dir):
                for root, dirs, files in os.walk(resources_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        # 收集所有文件，不仅仅是媒体文件
                        resource_files.add(file_path)

            # 同时收集场景中引用的特定资源
            scene_file = os.path.join(project_path, "scenes", "scene.bam")
            if os.path.exists(scene_file):
                # 从场景文件中提取资源引用
                referenced_files = self._extractResourcesFromScene(scene_file, project_path)
                for file_path in referenced_files:
                    if os.path.isabs(file_path):
                        if os.path.exists(file_path):
                            resource_files.add(file_path)
                    else:
                        # 相对路径
                        full_path = os.path.join(project_path, file_path)
                        if os.path.exists(full_path):
                            resource_files.add(full_path)

        except Exception as e:
            print(f"收集资源文件时出错: {str(e)}")

        return list(resource_files)

    def _extractResourcesFromScene(self, scene_file, project_path):
        """从场景文件中提取资源引用"""
        referenced_files = []

        try:
            # 这里应该实现从BAM文件中提取贴图、视频等资源引用的逻辑
            # 由于直接解析BAM文件比较复杂，我们采用间接方式

            # 检查项目配置文件或其他元数据文件中可能包含的资源引用
            config_file = os.path.join(project_path, "project.json")
            if os.path.exists(config_file):
                with open(config_file, "r", encoding="utf-8") as f:
                    project_config = json.load(f)
                    # 这里可以根据实际需要提取资源引用

        except Exception as e:
            print(f"从场景文件提取资源引用时出错: {str(e)}")

        return referenced_files

    # ==================== 辅助方法 ====================
    
    def _clearCurrentScene(self):
        """清空当前场景"""
        try:
            if hasattr(self.world, 'scene_manager') and self.world.scene_manager:
                self.world.scene_manager.clearScene()
                print("✓ 当前场景已清空")
        except Exception as e:
            print(f"清空场景失败: {str(e)}")

    def updateWindowTitle(self, parent_window, project_name):
        """更新窗口标题（保留方法以兼容旧代码）"""
        # 这个方法现在不需要做任何事情，因为我们不再处理UI
        pass

    def _createAppFile(self, build_dir, project_name):
        """创建标准的应用程序入口文件"""
        try:
            app_content = f'''#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
{project_name} - Panda3D应用程序
自动生成的入口文件
"""

import sys
import os

# 添加当前目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

try:
    from panda3d.core import loadPrcFileData
    
    # 设置基本的Panda3D配置
    loadPrcFileData("", """
        window-title {project_name}
        sync-video false
        show-frame-rate-meter true
    """)
    
    # 导入主应用程序类
    # 注意：这里需要根据实际情况修改导入路径
    from main import MyWorld
    
    # 创建并运行应用程序
    app = MyWorld()
    app.run()
    
except ImportError as e:
    print(f"导入错误: {{e}}")
    print("请确保已正确安装Panda3D")
    sys.exit(1)
except Exception as e:
    print(f"运行错误: {{e}}")
    sys.exit(1)
'''
            
            app_file = os.path.join(build_dir, "main.py")
            with open(app_file, "w", encoding="utf-8") as f:
                f.write(app_content)
            print(f"✓ 应用程序入口文件已创建: {app_file}")
            
        except Exception as e:
            print(f"创建应用程序入口文件失败: {str(e)}")

    def _createStandardSetupFile(self, build_dir, project_name):
        """创建标准的setup.py文件用于打包"""
        try:
            setup_content = f'''#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
{project_name} - Panda3D项目打包配置
"""

from setuptools import setup, find_packages
import sys

# 确保Python版本兼容性
if sys.version_info < (3, 6):
    sys.exit("Python 3.6或更高版本是必需的")

setup(
    name="{project_name}",
    version="1.0.0",
    description="基于Panda3D的3D应用程序",
    author="",
    author_email="",
    url="",
    
    # 包含所有Python包
    packages=find_packages(),
    
    # 包含非Python文件
    include_package_data=True,
    package_data={{
        "": ["*.bam", "*.egg", "*.png", "*.jpg", "*.jpeg", "*.ogg", "*.wav", "*.mp3"]
    }},
    
    # 依赖项
    install_requires=[
        "panda3d>=1.10.13",
    ],
    
    # Python版本要求
    python_requires=">=3.6",
    
    # 分类信息
    classifiers=[
        "Development Status :: 4 - Beta",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: MIT License",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        "Programming Language :: Python :: 3.10",
    ],
    
    # 入口点
    entry_points={{
        "console_scripts": [
            "{project_name}=main:main",
        ],
    }},
)
'''
            
            setup_file = os.path.join(build_dir, "setup.py")
            with open(setup_file, "w", encoding="utf-8") as f:
                f.write(setup_content)
            print(f"✓ setup.py文件已创建: {setup_file}")
            
        except Exception as e:
            print(f"创建setup.py文件失败: {str(e)}")

    def _executeStandardBuild(self, build_dir):
        """执行标准的Panda3D打包命令"""
        try:
            # 这里可以实现具体的打包逻辑
            # 例如使用pdeploy或其他打包工具
            
            print(f"✓ 项目文件已准备到: {build_dir}")
            print("注意: 请使用Panda3D的pdeploy工具进行最终打包")
            return True
            
        except Exception as e:
            print(f"执行打包命令失败: {str(e)}")
            return False