"""
流体世界管理模块
负责流体世界的创建、配置、更新和销毁，支持高级流体效果
"""

from panda3d.core import Vec3, Point3
import math
import time
import random
import numpy as np

class FluidWorld:
    """
    流体世界管理类
    管理整个流体模拟环境，包括流体域、求解器、更新循环等，支持高级流体效果
    """
    
    # 流体类型
    FLUID_TYPE_WATER = "water"
    FLUID_TYPE_LAVA = "lava"
    FLUID_TYPE_SLIME = "slime"
    FLUID_TYPE_OIL = "oil"
    FLUID_TYPE_BLOOD = "blood"
    
    # 模拟模式
    SIM_MODE_REALISTIC = "realistic"  # 真实物理模拟
    SIM_MODE_STYLIZED = "stylized"    # 风格化模拟
    SIM_MODE_PERFORMANCE = "performance"  # 性能优先模拟
    
    def __init__(self, world):
        """
        初始化流体世界
        
        Args:
            world: 主世界对象的引用
        """
        self.world = world  # 主世界对象引用
        
        # 流体参数
        self.time_step = 1.0/60.0  # 默认60FPS
        self.simulation_time = 0.0  # 模拟时间
        self.simulation_mode = self.SIM_MODE_REALISTIC  # 模拟模式
        
        # 流体对象容器
        self.fluid_domains = []  # 流体域
        self.fluid_emitters = []  # 流体发射器
        self.fluid_obstacles = []  # 流体障碍物
        self.fluid_particles = []  # 流体粒子
        
        # 高级效果系统
        self.foam_particles = []  # 泡沫粒子
        self.splash_particles = []  # 飞溅粒子
        self.bubbles = []  # 气泡
        self.tracers = []  # 轨迹线
        
        # 特殊效果参数
        self.foam_generation_rate = 0.1  # 泡沫生成率
        self.splash_threshold = 5.0  # 飞溅速度阈值
        self.bubble_probability = 0.05  # 气泡生成概率
        
        # 环境效果
        self.wind_velocity = Vec3(0, 0, 0)  # 风速
        self.temperature = 20.0  # 温度（摄氏度）
        self.pressure = 101.325  # 大气压（kPa）
        
        # 求解器
        self.solver = None
        
        # 可视化器
        self.visualizer = None
        
        # 性能优化器
        self.performance_optimizer = None
        
        # 性能监控
        self.performance_stats = {
            'update_count': 0,
            'last_update_time': 0.0,
            'avg_update_time': 0.0,
            'particle_count': 0,
            'foam_count': 0,
            'splash_count': 0,
            'bubble_count': 0
        }
        
        # 时间累积器
        self.time_accumulator = 0.0
        
        # 流体世界状态
        self.is_paused = False
        self.time_scale = 1.0
        
        # 流体材质系统
        self.fluid_materials = {}  # 流体材质字典
        
        # 交互系统
        self.interaction_forces = []  # 外部交互力
        
        print("流体世界初始化完成")
        
    def set_time_step(self, time_step):
        """
        设置时间步长参数
        
        Args:
            time_step (float): 时间步长
        """
        self.time_step = time_step
        if self.solver:
            self.solver.time_step = time_step
            
    def set_simulation_mode(self, mode):
        """
        设置模拟模式
        
        Args:
            mode (str): 模拟模式
        """
        self.simulation_mode = mode
        
        # 根据模式调整参数
        if mode == self.SIM_MODE_PERFORMANCE:
            self.foam_generation_rate = 0.01
            self.bubble_probability = 0.01
        elif mode == self.SIM_MODE_STYLIZED:
            self.foam_generation_rate = 0.2
            self.bubble_probability = 0.1
        else:  # REALISTIC
            self.foam_generation_rate = 0.1
            self.bubble_probability = 0.05
            
    def pause(self, paused=True):
        """
        暂停或恢复流体模拟
        
        Args:
            paused (bool): 是否暂停
        """
        self.is_paused = paused
        
    def set_time_scale(self, scale):
        """
        设置时间缩放
        
        Args:
            scale (float): 时间缩放因子
        """
        self.time_scale = max(0.0, scale)
        
    def update(self, dt):
        """
        更新流体世界
        
        Args:
            dt (float): 帧时间增量
        """
        # 如果暂停，不更新流体
        if self.is_paused:
            return
            
        # 应用时间缩放
        dt *= self.time_scale
        
        try:
            # 性能监控开始
            start_time = time.time()
            
            # 更新性能优化器
            if self.performance_optimizer:
                self.performance_optimizer.update_performance_stats()
            
            # 累积时间
            self.time_accumulator += dt
            
            # 计算子步数
            num_substeps = int(self.time_accumulator / self.time_step)
            
            # 执行子步长模拟
            for i in range(num_substeps):
                # 更新流体域
                for domain in self.fluid_domains:
                    domain.update(self.time_step)
                    
                # 更新流体发射器
                for emitter in self.fluid_emitters:
                    emitter.update(self.time_step)
                    
                # 更新流体障碍物
                for obstacle in self.fluid_obstacles:
                    obstacle.update(self.time_step)
                    
                # 更新特殊效果粒子
                self._update_foam_particles()
                self._update_splash_particles()
                self._update_bubbles()
                self._update_tracers()
                    
                # 执行求解器
                if self.solver:
                    self.solver.solve(self.time_step)
                    
                # 生成特殊效果
                self._generate_foam()
                self._generate_splash()
                self._generate_bubbles()
                    
                # 应用环境效果
                self._apply_wind_effect()
                self._apply_temperature_effect()
                    
                # 更新模拟时间
                self.simulation_time += self.time_step
                
            # 减少累积时间
            if num_substeps > 0:
                self.time_accumulator -= num_substeps * self.time_step
                
            # 更新可视化
            if self.visualizer:
                self.visualizer.update_visualization(dt)
                
            # 更新性能优化器
            if self.performance_optimizer:
                self.performance_optimizer.optimize_for_performance()
                
            # 更新性能统计
            end_time = time.time()
            update_time = end_time - start_time
            self.performance_stats['last_update_time'] = update_time
            self.performance_stats['update_count'] += 1
            self.performance_stats['particle_count'] = len(self.fluid_particles)
            self.performance_stats['foam_count'] = len(self.foam_particles)
            self.performance_stats['splash_count'] = len(self.splash_particles)
            self.performance_stats['bubble_count'] = len(self.bubbles)
            
            # 计算平均更新时间
            if self.performance_stats['update_count'] > 1:
                alpha = 0.1
                self.performance_stats['avg_update_time'] = (
                    alpha * update_time + 
                    (1 - alpha) * self.performance_stats['avg_update_time']
                )
            else:
                self.performance_stats['avg_update_time'] = update_time
                
        except Exception as e:
            print(f"更新流体世界时出错: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_foam_particles(self):
        """
        更新泡沫粒子
        """
        for foam in self.foam_particles[:]:
            foam['lifetime'] -= self.time_step
            if foam['lifetime'] <= 0:
                self.foam_particles.remove(foam)
            else:
                # 泡沫随水流移动
                # 简化处理：泡沫会逐渐上升
                foam['position'] += Vec3(0, 0, 0.5) * self.time_step
                
    def _update_splash_particles(self):
        """
        更新飞溅粒子
        """
        for splash in self.splash_particles[:]:
            splash['lifetime'] -= self.time_step
            if splash['lifetime'] <= 0:
                self.splash_particles.remove(splash)
            else:
                # 应用重力和初始速度
                splash['velocity'] += Vec3(0, 0, -9.81) * self.time_step
                splash['position'] += splash['velocity'] * self.time_step
                
    def _update_bubbles(self):
        """
        更新气泡
        """
        for bubble in self.bubbles[:]:
            bubble['lifetime'] -= self.time_step
            if bubble['lifetime'] <= 0:
                self.bubbles.remove(bubble)
            else:
                # 气泡上升
                bubble['position'] += Vec3(0, 0, 1.0) * self.time_step
                # 气泡可能随水流摆动
                bubble['position'] += Vec3(
                    random.uniform(-0.1, 0.1),
                    random.uniform(-0.1, 0.1),
                    0
                ) * self.time_step
                
    def _update_tracers(self):
        """
        更新轨迹线
        """
        for tracer in self.tracers[:]:
            tracer['lifetime'] -= self.time_step
            if tracer['lifetime'] <= 0:
                self.tracers.remove(tracer)
                
    def _generate_foam(self):
        """
        生成泡沫粒子
        """
        # 在高速流动区域生成泡沫
        for particle in self.fluid_particles:
            speed = particle['velocity'].length()
            if speed > 2.0 and random.random() < self.foam_generation_rate * self.time_step:
                foam = {
                    'position': particle['position'] + Vec3(0, 0, 0.1),  # 在表面生成
                    'lifetime': random.uniform(1.0, 3.0),
                    'size': random.uniform(0.05, 0.2)
                }
                self.foam_particles.append(foam)
                
    def _generate_splash(self):
        """
        生成飞溅效果
        """
        # 在碰撞或高速区域生成飞溅
        for particle in self.fluid_particles:
            speed = particle['velocity'].length()
            if speed > self.splash_threshold and random.random() < 0.1 * self.time_step:
                # 生成多个飞溅粒子
                for _ in range(random.randint(1, 3)):
                    splash = {
                        'position': particle['position'],
                        'velocity': particle['velocity'] + Vec3(
                            random.uniform(-2, 2),
                            random.uniform(-2, 2),
                            random.uniform(1, 5)
                        ),
                        'lifetime': random.uniform(0.5, 2.0),
                        'size': random.uniform(0.02, 0.1)
                    }
                    self.splash_particles.append(splash)
                    
    def _generate_bubbles(self):
        """
        生成气泡
        """
        # 随机生成气泡
        if random.random() < self.bubble_probability * self.time_step:
            # 在流体域内随机位置生成气泡
            if self.fluid_domains:
                domain = random.choice(self.fluid_domains)
                min_bound, max_bound = domain.get_bounding_box()
                position = Point3(
                    random.uniform(min_bound.getX(), max_bound.getX()),
                    random.uniform(min_bound.getY(), max_bound.getY()),
                    random.uniform(min_bound.getZ(), max_bound.getZ())
                )
                
                bubble = {
                    'position': position,
                    'lifetime': random.uniform(2.0, 5.0),
                    'size': random.uniform(0.05, 0.3)
                }
                self.bubbles.append(bubble)
                
    def _apply_wind_effect(self):
        """
        应用风力效果
        """
        if self.wind_velocity.length() > 0:
            # 风力主要影响表面粒子
            for particle in self.fluid_particles:
                # 简化：所有粒子都受风力影响
                particle['velocity'] += self.wind_velocity * 0.1 * self.time_step
                
    def _apply_temperature_effect(self):
        """
        应用温度效果
        """
        # 温度影响流体粘度
        if self.solver and hasattr(self.solver, 'viscosity'):
            # 简化的温度-粘度关系
            base_viscosity = 0.001  # 水在20°C时的粘度
            # 温度越高，粘度越低
            temp_factor = max(0.1, 1.0 - (self.temperature - 20.0) * 0.01)
            self.solver.viscosity = base_viscosity * temp_factor
            
    def add_fluid_domain(self, domain):
        """
        添加流体域到流体世界
        
        Args:
            domain: 流体域对象
        """
        self.fluid_domains.append(domain)
        
    def remove_fluid_domain(self, domain):
        """
        从流体世界移除流体域
        
        Args:
            domain: 流体域对象
        """
        if domain in self.fluid_domains:
            self.fluid_domains.remove(domain)
            
    def add_fluid_emitter(self, emitter):
        """
        添加流体发射器到流体世界
        
        Args:
            emitter: 流体发射器对象
        """
        self.fluid_emitters.append(emitter)
        
    def remove_fluid_emitter(self, emitter):
        """
        从流体世界移除流体发射器
        
        Args:
            emitter: 流体发射器对象
        """
        if emitter in self.fluid_emitters:
            self.fluid_emitters.remove(emitter)
            
    def add_fluid_obstacle(self, obstacle):
        """
        添加流体障碍物到流体世界
        
        Args:
            obstacle: 流体障碍物对象
        """
        self.fluid_obstacles.append(obstacle)
        
    def remove_fluid_obstacle(self, obstacle):
        """
        从流体世界移除流体障碍物
        
        Args:
            obstacle: 流体障碍物对象
        """
        if obstacle in self.fluid_obstacles:
            self.fluid_obstacles.remove(obstacle)
            
    def add_fluid_particle(self, particle):
        """
        添加流体粒子到流体世界
        
        Args:
            particle: 流体粒子对象
        """
        self.fluid_particles.append(particle)
        self.performance_stats['particle_count'] = len(self.fluid_particles)
        
    def remove_fluid_particle(self, particle):
        """
        从流体世界移除流体粒子
        
        Args:
            particle: 流体粒子对象
        """
        if particle in self.fluid_particles:
            self.fluid_particles.remove(particle)
            self.performance_stats['particle_count'] = len(self.fluid_particles)
            
    def add_foam_particle(self, foam):
        """
        添加泡沫粒子
        
        Args:
            foam (dict): 泡沫粒子数据
        """
        self.foam_particles.append(foam)
        self.performance_stats['foam_count'] = len(self.foam_particles)
        
    def add_splash_particle(self, splash):
        """
        添加飞溅粒子
        
        Args:
            splash (dict): 飞溅粒子数据
        """
        self.splash_particles.append(splash)
        self.performance_stats['splash_count'] = len(self.splash_particles)
        
    def add_bubble(self, bubble):
        """
        添加气泡
        
        Args:
            bubble (dict): 气泡数据
        """
        self.bubbles.append(bubble)
        self.performance_stats['bubble_count'] = len(self.bubbles)
        
    def set_wind_velocity(self, velocity):
        """
        设置风速
        
        Args:
            velocity (Vec3): 风速向量
        """
        self.wind_velocity = velocity
        
    def set_temperature(self, temperature):
        """
        设置温度
        
        Args:
            temperature (float): 温度（摄氏度）
        """
        self.temperature = temperature
        
    def set_pressure(self, pressure):
        """
        设置大气压
        
        Args:
            pressure (float): 大气压（kPa）
        """
        self.pressure = pressure
        
    def get_performance_stats(self):
        """
        获取性能统计信息
        
        Returns:
            dict: 性能统计信息
        """
        stats = self.performance_stats.copy()
        stats['objects'] = {
            'fluid_domains': len(self.fluid_domains),
            'fluid_emitters': len(self.fluid_emitters),
            'fluid_obstacles': len(self.fluid_obstacles),
            'fluid_particles': len(self.fluid_particles),
            'foam_particles': len(self.foam_particles),
            'splash_particles': len(self.splash_particles),
            'bubbles': len(self.bubbles)
        }
        stats['environment'] = {
            'temperature': self.temperature,
            'pressure': self.pressure,
            'wind_velocity': self.wind_velocity.length()
        }
        
        return stats
        
    def clear(self):
        """
        清除流体世界中的所有对象
        """
        # 移除所有流体域
        for domain in self.fluid_domains[:]:
            self.remove_fluid_domain(domain)
            
        # 移除所有流体发射器
        for emitter in self.fluid_emitters[:]:
            self.remove_fluid_emitter(emitter)
            
        # 移除所有流体障碍物
        for obstacle in self.fluid_obstacles[:]:
            self.remove_fluid_obstacle(obstacle)
            
        # 移除所有流体粒子
        for particle in self.fluid_particles[:]:
            self.remove_fluid_particle(particle)
            
        # 清除特殊效果粒子
        self.foam_particles.clear()
        self.splash_particles.clear()
        self.bubbles.clear()
        self.tracers.clear()
            
        # 重置统计信息
        self.performance_stats['update_count'] = 0
        self.performance_stats['particle_count'] = 0
        self.performance_stats['foam_count'] = 0
        self.performance_stats['splash_count'] = 0
        self.performance_stats['bubble_count'] = 0
        
        # 重置时间相关参数
        self.time_accumulator = 0.0
        self.simulation_time = 0.0
        
        print("流体世界已清除")
        
    def reset(self):
        """
        重置流体世界到初始状态
        """
        self.clear()
        self.is_paused = False
        self.time_scale = 1.0
        self.temperature = 20.0
        self.pressure = 101.325
        self.wind_velocity = Vec3(0, 0, 0)
        
    def cleanup(self):
        """
        清理流体世界资源
        """
        self.clear()
        
        # 清理求解器
        if self.solver:
            self.solver = None
            
        # 清理可视化器
        if self.visualizer:
            self.visualizer.cleanup()
            self.visualizer = None
            
        # 清理性能优化器
        if self.performance_optimizer:
            self.performance_optimizer.cleanup()
            self.performance_optimizer = None
            
        print("流体世界资源已清理")
        
    def add_interaction_force(self, force_data):
        """
        添加交互力
        
        Args:
            force_data (dict): 力数据，包含位置、力向量等信息
        """
        self.interaction_forces.append(force_data)
        
    def remove_interaction_force(self, force_data):
        """
        移除交互力
        
        Args:
            force_data (dict): 力数据
        """
        if force_data in self.interaction_forces:
            self.interaction_forces.remove(force_data)
            
    def set_fluid_material(self, fluid_type, material):
        """
        设置流体材质
        
        Args:
            fluid_type (str): 流体类型
            material (dict): 材质数据
        """
        self.fluid_materials[fluid_type] = material
        
    def get_fluid_material(self, fluid_type):
        """
        获取流体材质
        
        Args:
            fluid_type (str): 流体类型
            
        Returns:
            dict: 材质数据
        """
        return self.fluid_materials.get(fluid_type, {})