"""
自定义行为示例
演示如何创建自定义的群体行为
"""

from panda3d.core import Vec3
import math

class CustomBehaviorExample:
    """
    自定义行为示例类
    """
    
    def __init__(self, swarm_manager):
        self.swarm_manager = swarm_manager
        
    def create_leadership_behavior(self, leader_count=3):
        """
        创建领导行为
        指定几个成员作为领导者，其他成员跟随领导者
        """
        print(f"创建领导行为，设置{leader_count}个领导者...")
        
        # 重置群体
        self.swarm_manager.reset()
        
        # 标记领导者
        for i, member in enumerate(self.swarm_manager.members):
            if i < leader_count:
                member['is_leader'] = True
                # 设置领导者颜色（实际应用中可能需要修改材质）
                if 'node' in member:
                    member['node'].setColor(0, 1, 0, 1)  # 绿色表示领导者
            else:
                member['is_leader'] = False
                if 'node' in member:
                    member['node'].setColor(1, 1, 1, 1)  # 白色表示跟随者
                    
        # 配置参数
        self.swarm_manager.config.set("cohesion_weight", 1.0)
        self.swarm_manager.config.set("separation_weight", 1.5)
        self.swarm_manager.config.set("alignment_weight", 0.8)
        
        print("领导行为创建完成")
        
    def create_flocking_with_leaders(self, member):
        """
        为跟随者成员实现跟随领导者的行为
        """
        # 查找领导者邻居
        leaders = [m for m in self.swarm_manager.members if m.get('is_leader', False)]
        
        if not leaders:
            return Vec3(0, 0, 0)
            
        # 计算到领导者的平均方向
        direction = Vec3(0, 0, 0)
        for leader in leaders:
            if leader != member:  # 排除自己
                dir_to_leader = leader['position'] - member['position']
                distance = dir_to_leader.length()
                if distance > 0:
                    # 距离越近，跟随力越小（避免碰撞）
                    direction += dir_to_leader.normalized() / (distance / 10.0)
                    
        return direction.normalized()
        
    def create_attraction_behavior(self, attractor_position, attraction_strength=1.0):
        """
        创建吸引力行为
        向指定位置吸引群体成员
        """
        print(f"创建吸引力行为，吸引点: {attractor_position}")
        
        # 设置吸引点
        self.attractor_position = attractor_position
        self.attraction_strength = attraction_strength
        
        # 启用吸引行为
        self.swarm_manager.config.set("attraction_enabled", True)
        
        print("吸引力行为创建完成")
        
    def calculate_attraction_force(self, member):
        """
        计算吸引力
        """
        if not hasattr(self, 'attractor_position'):
            return Vec3(0, 0, 0)
            
        direction = self.attractor_position - member['position']
        distance = direction.length()
        
        if distance > 0:
            # 归一化方向并应用强度
            force = direction.normalized() * self.attraction_strength
            # 距离越近，力量越小
            force *= 1.0 / (distance / 10.0)
            return force
            
        return Vec3(0, 0, 0)
        
    def create_repulsion_behavior(self, repulsor_position, repulsion_strength=1.0, radius=20.0):
        """
        创建排斥力行为
        从指定位置推开群体成员
        """
        print(f"创建排斥力行为，排斥点: {repulsor_position}")
        
        # 设置排斥点
        self.repulsor_position = repulsor_position
        self.repulsion_strength = repulsion_strength
        self.repulsion_radius = radius
        
        # 启用排斥行为
        self.swarm_manager.config.set("repulsion_enabled", True)
        
        print("排斥力行为创建完成")
        
    def calculate_repulsion_force(self, member):
        """
        计算排斥力
        """
        if not hasattr(self, 'repulsor_position'):
            return Vec3(0, 0, 0)
            
        direction = member['position'] - self.repulsor_position
        distance = direction.length()
        
        # 只在一定范围内施加排斥力
        if 0 < distance < self.repulsion_radius:
            # 归一化方向并应用强度
            force = direction.normalized() * self.repulsion_strength
            # 距离越近，力量越大
            force *= (self.repulsion_radius - distance) / self.repulsion_radius
            return force
            
        return Vec3(0, 0, 0)
        
    def create_sine_wave_behavior(self, amplitude=5.0, frequency=0.5):
        """
        创建正弦波行为
        群体成员沿正弦波路径移动
        """
        print("创建正弦波行为...")
        
        self.sine_amplitude = amplitude
        self.sine_frequency = frequency
        self.sine_offset = 0.0
        
        # 启用正弦波行为
        self.swarm_manager.config.set("sine_wave_enabled", True)
        
        print("正弦波行为创建完成")
        
    def update_sine_wave_behavior(self, dt):
        """
        更新正弦波行为
        """
        if hasattr(self, 'sine_offset'):
            self.sine_offset += dt * self.sine_frequency
            
    def calculate_sine_wave_force(self, member):
        """
        计算正弦波力
        """
        if not hasattr(self, 'sine_offset'):
            return Vec3(0, 0, 0)
            
        # 基于成员的Y坐标计算期望的Z坐标
        expected_z = math.sin(member['position'].y * 0.1 + self.sine_offset) * self.sine_amplitude
        
        # 计算向期望位置的力
        desired_z = expected_z - member['position'].z
        force = Vec3(0, 0, desired_z)
        
        return force.normalized() * 0.5  # 应用适当的力量
        
    def create_formation_behavior(self, formation_type="custom"):
        """
        创建自定义队形行为
        """
        print(f"创建自定义队形行为: {formation_type}")
        
        self.formation_type = formation_type
        
        # 启用队形行为
        self.swarm_manager.config.set("custom_formation_enabled", True)
        
        print("自定义队形行为创建完成")
        
    def calculate_formation_force(self, member):
        """
        计算队形力
        """
        if not hasattr(self, 'formation_type'):
            return Vec3(0, 0, 0)
            
        # 根据队形类型计算期望位置
        target_position = Vec3(0, 0, 0)
        
        if self.formation_type == "spiral":
            # 螺旋队形
            if 'index' in member:
                index = member['index']
                angle = index * 0.5
                radius = 5.0 + index * 0.2
                target_position = Vec3(
                    math.cos(angle) * radius,
                    math.sin(angle) * radius,
                    index * 0.5
                )
        elif self.formation_type == "grid":
            # 网格队形
            if 'index' in member:
                index = member['index']
                grid_size = int(math.sqrt(len(self.swarm_manager.members)))
                x = (index % grid_size) - grid_size/2
                y = (index // grid_size) - grid_size/2
                target_position = Vec3(x * 3, y * 3, 0)
                
        # 计算向期望位置的力
        if target_position.length() > 0:
            direction = target_position - member['position']
            return direction.normalized() * 0.8
            
        return Vec3(0, 0, 0)

def run_custom_behavior_example(swarm_manager):
    """
    运行自定义行为示例
    """
    print("=== 自定义行为示例 ===")
    
    # 创建自定义行为示例
    custom_behavior = CustomBehaviorExample(swarm_manager)
    
    # 创建领导行为
    custom_behavior.create_leadership_behavior(2)
    
    # 创建吸引力行为
    attractor_pos = Vec3(20, 20, 15)
    custom_behavior.create_attraction_behavior(attractor_pos, 1.5)
    
    # 创建排斥力行为
    repulsor_pos = Vec3(-10, -10, 10)
    custom_behavior.create_repulsion_behavior(repulsor_pos, 2.0, 15.0)
    
    print("自定义行为示例设置完成")