"""
粒子编辑器
提供可视化的粒子效果编辑功能
"""

import json
from typing import Dict, Optional, Any
from panda3d.core import Vec3, Point3

class ParticleEditor:
    """
    粒子编辑器
    提供实时编辑粒子效果的功能
    """
    
    def __init__(self, world, particle_manager):
        """
        初始化粒子编辑器
        
        Args:
            world: 3D世界对象
            particle_manager: 粒子管理器
        """
        self.world = world
        self.particle_manager = particle_manager
        self.visible = False
        
        # 当前编辑的发射器
        self.current_emitter_id = None
        self.current_emitter = None
        
        # 编辑器GUI元素
        self.gui_elements = []
        self.parameter_controls = {}
        self.effect_type_buttons = {}
        
        # 预览模式
        self.preview_mode = True
        self.auto_update = True
        
        # 编辑器状态
        self.editor_position = Point3(0, 0, 0)
        self.editor_enabled = False
        
        # 编辑参数
        self.edit_parameters = {
            'emitter_type': 'fire',
            'emission_rate': 50,
            'particle_lifetime': 2.0,
            'start_color': Vec3(1.0, 0.3, 0.0),
            'end_color': Vec3(1.0, 0.0, 0.0),
            'start_size': 0.2,
            'end_size': 0.8,
            'velocity': Vec3(0, 0, 2),
            'velocity_variation': 0.5,
            'gravity_scale': -0.2,
            'air_resistance': 0.02,
            'bounce_factor': 0.5,
            'emitter_shape': 'circle',
            'emitter_radius': 0.3,
            'rotation_enabled': False,
            'rotation_speed': 0.0
        }
        
        print("✓ 粒子编辑器初始化完成")
        
    def toggle_visibility(self):
        """切换编辑器可见性"""
        if self.visible:
            self.hide()
        else:
            self.show()
            
    def show(self):
        """显示编辑器"""
        if self.visible:
            return
            
        self.visible = True
        self._create_editor_gui()
        
        # 如果没有当前发射器，创建一个默认的
        if not self.current_emitter_id:
            self.create_new_effect()
            
        print("✓ 粒子编辑器已显示")
        
    def hide(self):
        """隐藏编辑器"""
        if not self.visible:
            return
            
        self.visible = False
        self._cleanup_editor_gui()
        
        print("✓ 粒子编辑器已隐藏")
        
    def _create_editor_gui(self):
        """创建编辑器GUI"""
        try:
            if not hasattr(self.world, 'gui_manager') or not self.world.gui_manager:
                print("⚠ GUI管理器不可用，无法创建编辑器界面")
                return
                
            gui_manager = self.world.gui_manager
            
            # 创建编辑器面板标题
            panel = gui_manager.createGUIButton(
                pos=(0.7, 0, 0.95), 
                text="粒子编辑器", 
                size=0.06
            )
            self.gui_elements.append(panel)
            
            # 创建效果类型选择按钮
            effect_types = ["火焰", "烟雾", "爆炸", "水花", "魔法", "雪花", "自定义"]
            for i, effect_type in enumerate(effect_types):
                button = gui_manager.createGUIButton(
                    pos=(0.7, 0, 0.88 - i * 0.06), 
                    text=effect_type, 
                    size=0.04
                )
                self.gui_elements.append(button)
                self.effect_type_buttons[effect_type] = button
                self.world.accept(f"editor_effect_{effect_type}", 
                                lambda t=effect_type: self.set_effect_type(t))
                
            # 创建参数控制面板
            self._create_parameter_controls()
            
            # 创建操作按钮
            self._create_action_buttons()
            
        except Exception as e:
            print(f"⚠ 编辑器GUI创建失败: {e}")
            
    def _create_parameter_controls(self):
        """创建参数控制界面"""
        if not hasattr(self.world, 'gui_manager') or not self.world.gui_manager:
            return
            
        gui_manager = self.world.gui_manager
        
        # 基础参数控制
        parameters = [
            ("发射率", "emission_rate", 0, 500, 1),
            ("生命周期", "particle_lifetime", 0.1, 10.0, 0.1),
            ("起始尺寸", "start_size", 0.01, 5.0, 0.01),
            ("结束尺寸", "end_size", 0.01, 5.0, 0.01),
            ("速度变化", "velocity_variation", 0.0, 5.0, 0.1),
            ("重力缩放", "gravity_scale", -5.0, 5.0, 0.1),
            ("空气阻力", "air_resistance", 0.0, 1.0, 0.01),
            ("反弹系数", "bounce_factor", 0.0, 1.0, 0.1),
            ("发射器半径", "emitter_radius", 0.0, 5.0, 0.1),
            ("旋转速度", "rotation_speed", -10.0, 10.0, 0.1)
        ]
        
        for i, (name, param, min_val, max_val, step) in enumerate(parameters):
            y_pos = 0.8 - i * 0.055
            
            # 参数标签
            label = gui_manager.createGUIButton(
                pos=(0.75, 0, y_pos), 
                text=f"{name}:", 
                size=0.03
            )
            self.gui_elements.append(label)
            
            # 参数值显示
            value_label = gui_manager.createGUIButton(
                pos=(0.88, 0, y_pos), 
                text=f"{self.edit_parameters[param]:.2f}", 
                size=0.03
            )
            self.gui_elements.append(value_label)
            
            # 减少按钮
            dec_button = gui_manager.createGUIButton(
                pos=(0.83, 0, y_pos), 
                text="-", 
                size=0.03
            )
            self.gui_elements.append(dec_button)
            
            # 增加按钮
            inc_button = gui_manager.createGUIButton(
                pos=(0.93, 0, y_pos), 
                text="+", 
                size=0.03
            )
            self.gui_elements.append(inc_button)
            
            # 注册事件
            self.world.accept(f"dec_{param}", lambda p=param, s=step: self._decrease_parameter(p, s))
            self.world.accept(f"inc_{param}", lambda p=param, s=step: self._increase_parameter(p, s))
            
            # 存储控制信息
            self.parameter_controls[param] = {
                'name': name,
                'min': min_val,
                'max': max_val,
                'step': step,
                'value_label': value_label,
                'dec_button': dec_button,
                'inc_button': inc_button
            }
            
        # 布尔型参数
        bool_params = [
            ("启用旋转", "rotation_enabled"),
            ("自动更新", "auto_update"),
            ("预览模式", "preview_mode")
        ]
        
        for i, (name, param) in enumerate(bool_params):
            y_pos = 0.25 - i * 0.055
            
            # 参数标签
            label = gui_manager.createGUIButton(
                pos=(0.75, 0, y_pos), 
                text=f"{name}:", 
                size=0.03
            )
            self.gui_elements.append(label)
            
            # 开关按钮
            switch_button = gui_manager.createGUIButton(
                pos=(0.88, 0, y_pos), 
                text="开" if self.edit_parameters.get(param, False) else "关", 
                size=0.03
            )
            self.gui_elements.append(switch_button)
            
            # 注册事件
            self.world.accept(f"toggle_{param}", lambda p=param: self._toggle_boolean_parameter(p))
            
            self.parameter_controls[param] = {
                'name': name,
                'value_label': switch_button,
                'type': 'boolean'
            }
            
    def _create_action_buttons(self):
        """创建操作按钮"""
        if not hasattr(self.world, 'gui_manager') or not self.world.gui_manager:
            return
            
        gui_manager = self.world.gui_manager
        
        actions = [
            ("应用更改", 0.15, self.apply_changes),
            ("重置参数", 0.09, self.reset_parameters),
            ("创建新效果", 0.03, self.create_new_effect),
            ("删除当前", -0.03, self.delete_current_effect),
            ("保存预设", -0.09, self.save_preset),
            ("加载预设", -0.15, self.load_preset)
        ]
        
        for name, y_offset, callback in actions:
            button = gui_manager.createGUIButton(
                pos=(0.82, 0, y_offset), 
                text=name, 
                size=0.035
            )
            self.gui_elements.append(button)
            self.world.accept(f"action_{name}", callback)
            
    def _cleanup_editor_gui(self):
        """清理编辑器GUI"""
        try:
            if hasattr(self.world, 'gui_manager') and self.world.gui_manager:
                gui_manager = self.world.gui_manager
                
                for element in self.gui_elements:
                    gui_manager.deleteGUIElement(element)
                    
            # 清理事件监听
            for param in self.parameter_controls:
                self.world.ignore(f"dec_{param}")
                self.world.ignore(f"inc_{param}")
                
            for param in ['rotation_enabled', 'auto_update', 'preview_mode']:
                self.world.ignore(f"toggle_{param}")
                
            self.world.ignore("action_应用更改")
            self.world.ignore("action_重置参数")
            self.world.ignore("action_创建新效果")
            self.world.ignore("action_删除当前")
            self.world.ignore("action_保存预设")
            self.world.ignore("action_加载预设")
                    
            self.gui_elements.clear()
            self.parameter_controls.clear()
            self.effect_type_buttons.clear()
            
        except Exception as e:
            print(f"⚠ 编辑器GUI清理失败: {e}")
            
    def _decrease_parameter(self, param_name: str, step: float):
        """减少参数值"""
        if param_name in self.edit_parameters:
            control = self.parameter_controls[param_name]
            current_value = self.edit_parameters[param_name]
            new_value = max(control['min'], current_value - step)
            self.edit_parameters[param_name] = new_value
            
            # 更新显示
            if 'value_label' in control:
                control['value_label'].setText(f"{new_value:.2f}")
                
            # 自动应用更改
            if self.auto_update:
                self.apply_changes()
                
    def _increase_parameter(self, param_name: str, step: float):
        """增加参数值"""
        if param_name in self.edit_parameters:
            control = self.parameter_controls[param_name]
            current_value = self.edit_parameters[param_name]
            new_value = min(control['max'], current_value + step)
            self.edit_parameters[param_name] = new_value
            
            # 更新显示
            if 'value_label' in control:
                control['value_label'].setText(f"{new_value:.2f}")
                
            # 自动应用更改
            if self.auto_update:
                self.apply_changes()
                
    def _toggle_boolean_parameter(self, param_name: str):
        """切换布尔参数"""
        if param_name in self.edit_parameters:
            current_value = self.edit_parameters[param_name]
            new_value = not current_value
            self.edit_parameters[param_name] = new_value
            
            # 更新显示
            control = self.parameter_controls[param_name]
            if 'value_label' in control:
                control['value_label'].setText("开" if new_value else "关")
                
            # 特殊处理某些参数
            if param_name == 'auto_update':
                self.auto_update = new_value
            elif param_name == 'preview_mode':
                self.preview_mode = new_value
                
            # 自动应用更改
            if self.auto_update:
                self.apply_changes()
                
    def create_new_effect(self, effect_type: str = "火焰"):
        """创建新的粒子效果"""
        # 删除当前效果
        if self.current_emitter_id:
            self.particle_manager.remove_emitter(self.current_emitter_id)
            
        # 在摄像机前方创建
        camera_pos = self.world.camera.getPos()
        camera_forward = self.world.camera.getNetTransform().getMat().getRow3(1)
        position = camera_pos + camera_forward * 5
        
        # 根据类型设置参数
        self.set_effect_type(effect_type)
        
        # 创建发射器
        config = self.edit_parameters.copy()
        config['emitter_type'] = effect_type.lower()
        
        self.current_emitter_id = self.particle_manager.create_emitter(
            effect_type.lower(), 
            position, 
            config
        )
        
        self.current_emitter = self.particle_manager.get_emitter(self.current_emitter_id)
        self.editor_position = position
        
        print(f"✓ 创建新粒子效果: {effect_type}")
        
    def set_effect_type(self, effect_type: str):
        """设置效果类型"""
        self.edit_parameters['emitter_type'] = effect_type.lower()
        
        # 根据类型预设参数
        if effect_type == "火焰":
            self.edit_parameters.update({
                'emission_rate': 50,
                'particle_lifetime': 2.0,
                'start_color': Vec3(1.0, 0.3, 0.0),
                'end_color': Vec3(1.0, 0.0, 0.0),
                'start_size': 0.2,
                'end_size': 0.8,
                'velocity': Vec3(0, 0, 2),
                'velocity_variation': 0.5,
                'gravity_scale': -0.2,
                'emitter_shape': 'circle',
                'emitter_radius': 0.3
            })
        elif effect_type == "烟雾":
            self.edit_parameters.update({
                'emission_rate': 30,
                'particle_lifetime': 4.0,
                'start_color': Vec3(0.8, 0.8, 0.8),
                'end_color': Vec3(0.3, 0.3, 0.3),
                'start_size': 0.3,
                'end_size': 1.5,
                'velocity': Vec3(0, 0, 1),
                'velocity_variation': 0.3,
                'gravity_scale': -0.1,
                'emitter_shape': 'circle',
                'emitter_radius': 0.5
            })
        elif effect_type == "爆炸":
            self.edit_parameters.update({
                'emission_rate': 200,
                'burst_count': 100,
                'particle_lifetime': 1.5,
                'start_color': Vec3(1.0, 0.8, 0.0),
                'end_color': Vec3(1.0, 0.2, 0.0),
                'start_size': 0.1,
                'end_size': 0.5,
                'velocity': Vec3(0, 0, 0),
                'velocity_variation': 2.0,
                'gravity_scale': 0.5,
                'duration': 0.2,
                'emitter_shape': 'sphere',
                'emitter_radius': 0.1
            })
        elif effect_type == "水花":
            self.edit_parameters.update({
                'emission_rate': 80,
                'particle_lifetime': 3.0,
                'start_color': Vec3(0.2, 0.6, 1.0),
                'end_color': Vec3(0.1, 0.3, 0.8),
                'start_size': 0.1,
                'end_size': 0.05,
                'velocity': Vec3(0, 0, 3),
                'velocity_variation': 1.0,
                'gravity_scale': 2.0,
                'bounce_factor': 0.3,
                'emitter_shape': 'circle',
                'emitter_radius': 0.2
            })
        elif effect_type == "魔法":
            self.edit_parameters.update({
                'emission_rate': 40,
                'particle_lifetime': 3.0,
                'start_color': Vec3(0.5, 0.2, 1.0),
                'end_color': Vec3(0.8, 0.6, 1.0),
                'start_size': 0.15,
                'end_size': 0.05,
                'velocity': Vec3(0, 0, 0.5),
                'velocity_variation': 0.8,
                'gravity_scale': -0.5,
                'rotation_enabled': True,
                'rotation_speed': 2.0,
                'emitter_shape': 'sphere',
                'emitter_radius': 0.8
            })
        elif effect_type == "雪花":
            self.edit_parameters.update({
                'emission_rate': 60,
                'particle_lifetime': 8.0,
                'start_color': Vec3(0.9, 0.9, 1.0),
                'end_color': Vec3(0.9, 0.9, 1.0),
                'start_size': 0.05,
                'end_size': 0.05,
                'velocity': Vec3(0, 0, -1),
                'velocity_variation': 0.5,
                'gravity_scale': 0.8,
                'air_resistance': 0.1,
                'bounce_factor': 0.2,
                'emitter_shape': 'box',
                'emitter_dimensions': Vec3(20, 20, 1)
            })
            
        # 更新GUI显示
        self._update_parameter_display()
        
    def _update_parameter_display(self):
        """更新参数显示"""
        for param_name, control in self.parameter_controls.items():
            if param_name in self.edit_parameters:
                value = self.edit_parameters[param_name]
                if control.get('type') == 'boolean':
                    if 'value_label' in control:
                        control['value_label'].setText("开" if value else "关")
                else:
                    if 'value_label' in control:
                        if isinstance(value, (int, float)):
                            control['value_label'].setText(f"{value:.2f}")
                        else:
                            control['value_label'].setText(str(value))
                            
    def apply_changes(self):
        """应用更改到当前效果"""
        if not self.current_emitter_id or not self.current_emitter:
            print("⚠ 没有选中的效果")
            return
            
        # 更新发射器参数
        try:
            # 更新发射器配置
            for param_name, value in self.edit_parameters.items():
                if hasattr(self.current_emitter, param_name):
                    setattr(self.current_emitter, param_name, value)
                    
            print("✓ 参数已应用")
            
        except Exception as e:
            print(f"⚠ 参数应用失败: {e}")
            
    def reset_parameters(self):
        """重置参数为默认值"""
        # 重新设置当前类型参数
        current_type = self.edit_parameters.get('emitter_type', 'fire')
        self.set_effect_type(current_type.capitalize())
        print("✓ 参数已重置")
        
    def delete_current_effect(self):
        """删除当前效果"""
        if self.current_emitter_id:
            self.particle_manager.remove_emitter(self.current_emitter_id)
            self.current_emitter_id = None
            self.current_emitter = None
            print("✓ 当前效果已删除")
            
    def update_parameter(self, param_name: str, value: float):
        """更新参数值"""
        if not self.current_emitter or param_name not in self.parameter_controls:
            return
            
        # 更新控制信息
        control = self.parameter_controls[param_name]
        
        # 更新GUI显示
        if 'value_label' in control:
            try:
                control['value_label'].setText(f"{value:.2f}")
            except:
                pass
                
        # 应用到发射器
        self._apply_parameter_to_emitter(param_name, value)
        
        if self.auto_update:
            print(f"✓ 更新参数 {param_name}: {value}")
            
    def _apply_parameter_to_emitter(self, param_name: str, value: float):
        """将参数应用到发射器"""
        if not self.current_emitter:
            return
            
        try:
            if param_name == "emission_rate":
                self.current_emitter.emission_rate = value
            elif param_name == "particle_lifetime":
                self.current_emitter.particle_lifetime = value
            elif param_name == "start_size":
                self.current_emitter.start_size = value
            elif param_name == "end_size":
                self.current_emitter.end_size = value
            elif param_name == "velocity_variation":
                self.current_emitter.velocity_variation = value
                
        except Exception as e:
            print(f"⚠ 参数应用失败 {param_name}: {e}")
            
    def set_emitter_position(self, position: Point3):
        """设置发射器位置"""
        self.editor_position = position
        if self.current_emitter:
            self.current_emitter.set_position(position)
            
    def get_current_config(self) -> Dict[str, Any]:
        """获取当前配置"""
        config = self.edit_parameters.copy()
        config['emitter_type'] = self.edit_parameters.get('emitter_type', 'fire')
        config['position'] = [
            self.editor_position.x,
            self.editor_position.y,
            self.editor_position.z
        ]
        return config
        
    def load_config(self, config: Dict[str, Any]):
        """加载配置"""
        try:
            # 设置位置
            if 'position' in config:
                pos = config['position']
                position = Point3(pos[0], pos[1], pos[2])
                self.set_emitter_position(position)
                
            # 更新编辑参数
            for param_name, value in config.items():
                if param_name in self.edit_parameters:
                    self.edit_parameters[param_name] = value
                    
            # 更新GUI显示
            self._update_parameter_display()
            
            # 应用到当前效果
            if self.auto_update:
                self.apply_changes()
                
            print("✓ 配置加载完成")
            
        except Exception as e:
            print(f"⚠ 配置加载失败: {e}")
            
    def save_preset(self, name: str = "自定义预设") -> bool:
        """保存预设"""
        try:
            config = self.get_current_config()
            
            # 这里应该调用预设管理器保存
            print(f"✓ 保存预设 '{name}':")
            print(json.dumps(config, indent=2, default=str))
            
            return True
            
        except Exception as e:
            print(f"⚠ 预设保存失败: {e}")
            return False
            
    def load_preset(self, name: str = "经典火焰") -> bool:
        """加载预设"""
        try:
            # 这里应该调用预设管理器加载
            # 简化实现：使用默认配置
            default_configs = {
                "经典火焰": {
                    'emitter_type': 'fire',
                    'emission_rate': 50,
                    'particle_lifetime': 2.0,
                    'start_color': [1.0, 0.3, 0.0],
                    'end_color': [1.0, 0.0, 0.0],
                    'start_size': 0.2,
                    'end_size': 0.8,
                    'velocity': [0, 0, 2],
                    'velocity_variation': 0.5,
                    'gravity_scale': -0.2,
                    'emitter_shape': 'circle',
                    'emitter_radius': 0.3
                },
                "浓密烟雾": {
                    'emitter_type': 'smoke',
                    'emission_rate': 30,
                    'particle_lifetime': 4.0,
                    'start_color': [0.8, 0.8, 0.8],
                    'end_color': [0.3, 0.3, 0.3],
                    'start_size': 0.3,
                    'end_size': 1.5,
                    'velocity': [0, 0, 1],
                    'velocity_variation': 0.3,
                    'gravity_scale': -0.1,
                    'emitter_shape': 'circle',
                    'emitter_radius': 0.5
                }
            }
            
            if name in default_configs:
                self.load_config(default_configs[name])
                print(f"✓ 加载预设 '{name}'")
                return True
            else:
                print(f"⚠ 预设 '{name}' 不存在")
                return False
                
        except Exception as e:
            print(f"⚠ 预设加载失败: {e}")
            return False
            
    def reset_to_defaults(self):
        """重置为默认值"""
        if self.current_emitter:
            # 重新创建当前类型的发射器
            effect_type = self.current_emitter.emitter_type
            self.create_new_effect(effect_type.capitalize())
            
    def cleanup(self):
        """清理编辑器资源"""
        self.hide()
        
        if self.current_emitter_id:
            self.particle_manager.remove_emitter(self.current_emitter_id)
            
        self.current_emitter_id = None
        self.current_emitter = None