"""
植被生成器
负责生成程序化地形的植被分布
"""

import numpy as np
import math
from typing import Dict, Any, List, Tuple
import random

class VegetationGenerator:
    """
    植被生成器
    负责生成程序化地形的植被分布，基于生物群落、湿度、温度等因素
    """
    
    def __init__(self, plugin):
        """
        初始化植被生成器
        
        Args:
            plugin: 程序化地形生成插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 植被配置
        self.seed = plugin.config.get('seed', 12345)
        
        # 植被类型定义
        self.vegetation_types = {
            0: {'name': 'none', 'density': 0.0, 'color': (0, 0, 0)},
            1: {'name': 'grass', 'density': 0.3, 'color': (144, 238, 144)},
            2: {'name': 'shrub', 'density': 0.2, 'color': (107, 142, 35)},
            3: {'name': 'flower', 'density': 0.1, 'color': (255, 105, 180)},
            4: {'name': 'tree', 'density': 0.15, 'color': (34, 139, 34)},
            5: {'name': 'pine_tree', 'density': 0.12, 'color': (0, 128, 0)},
            6: {'name': 'palm_tree', 'density': 0.08, 'color': (0, 100, 0)},
            7: {'name': 'cactus', 'density': 0.05, 'color': (0, 100, 0)},
            8: {'name': 'bush', 'density': 0.25, 'color': (107, 142, 35)},
            9: {'name': 'fern', 'density': 0.2, 'color': (34, 139, 34)},
            10: {'name': 'moss', 'density': 0.15, 'color': (144, 238, 144)},
            11: {'name': 'vine', 'density': 0.1, 'color': (0, 128, 0)},
            12: {'name': 'seaweed', 'density': 0.4, 'color': (0, 128, 0)},
            13: {'name': 'algae', 'density': 0.35, 'color': (0, 100, 0)},
            14: {'name': 'kelp', 'density': 0.3, 'color': (0, 128, 0)},
            15: {'name': 'coral', 'density': 0.25, 'color': (255, 99, 71)}
        }
        
        # 生物群落植被分布
        self.biome_vegetation = {
            0: [0, 12, 13, 14, 15],      # ocean
            1: [0, 1, 2],                # beach
            2: [0, 1, 2, 8],             # plains
            3: [0, 1, 2, 4, 9],          # forest
            4: [0, 1, 2, 4, 6, 9, 11],   # jungle
            5: [0, 1, 2, 7],             # desert
            6: [0, 1, 2, 5],             # mountain
            7: [0, 1, 2],                # snow
            8: [0, 1, 2, 5, 10],         # taiga
            9: [0, 1, 2],                # tundra
            10: [0, 1, 2, 3, 9, 10],     # swamp
            11: [0, 1, 2, 8]             # savanna
        }
        
        # 植被生成参数
        self.vegetation_params = {
            'density_scale': 10.0,
            'clumping_factor': 0.7,
            'slope_tolerance': 0.3,
            'height_min': 0.0,
            'height_max': 1.0,
            'humidity_min': 0.0,
            'humidity_max': 1.0,
            'temperature_min': 0.0,
            'temperature_max': 1.0,
            'edge_blending': 0.05
        }
        
        # 噪声生成器引用
        self.noise_generator = None
        
        # 植被分布图
        self.vegetation_map = None
        
        # 统计信息
        self.stats = {
            'vegetation_generated': 0,
            'total_generation_time': 0.0,
            'average_generation_time': 0.0,
            'vegetation_distribution': {}
        }
        
        print("✓ 植被生成器已创建")
        
    def initialize(self) -> bool:
        """
        初始化植被生成器
        
        Returns:
            是否初始化成功
        """
        try:
            # 获取噪声生成器引用
            self.noise_generator = self.plugin.noise_generator
            
            self.initialized = True
            print("✓ 植被生成器初始化完成")
            return True
            
        except Exception as e:
            print(f"✗ 植被生成器初始化失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def enable(self) -> bool:
        """
        启用植被生成器
        
        Returns:
            是否启用成功
        """
        try:
            if not self.initialized:
                print("✗ 植被生成器未初始化")
                return False
                
            self.enabled = True
            print("✓ 植被生成器已启用")
            return True
            
        except Exception as e:
            print(f"✗ 植被生成器启用失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def disable(self):
        """禁用植被生成器"""
        try:
            self.enabled = False
            print("✓ 植被生成器已禁用")
            
        except Exception as e:
            print(f"✗ 植被生成器禁用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def finalize(self):
        """清理植被生成器资源"""
        try:
            self.disable()
            self.initialized = False
            print("✓ 植被生成器资源已清理")
            
        except Exception as e:
            print(f"✗ 植被生成器资源清理失败: {e}")
            import traceback
            traceback.print_exc()
            
    def update(self, dt: float):
        """
        更新植被生成器状态
        
        Args:
            dt: 时间增量
        """
        # 处理更新逻辑
        pass
        
    def generate_vegetation(self, heightmap: np.ndarray, biome_map: np.ndarray, seed: int = None) -> np.ndarray:
        """
        生成植被分布
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成植被分布...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 生成基础植被噪声
            vegetation_noise = self._generate_vegetation_noise(width, height)
            
            # 为每个像素生成植被
            print("  → 生成植被类型...")
            for y in range(height):
                for x in range(width):
                    # 获取当前位置的属性
                    height_value = heightmap[y, x]
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    
                    # 生成植被
                    vegetation_type = self._generate_vegetation_at_position(
                        x, y, height_value, biome_type, vegetation_noise[y, x]
                    )
                    self.vegetation_map[y, x] = vegetation_type
                    
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)
            
    def _generate_vegetation_noise(self, width: int, height: int) -> np.ndarray:
        """
        生成植被噪声图
        
        Args:
            width: 宽度
            height: 高度
            
        Returns:
            植被噪声图
        """
        try:
            noise_map = np.zeros((height, width), dtype=np.float32)
            
            if self.noise_generator:
                # 生成分形噪声
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_fractal_noise(
                            x / self.vegetation_params['density_scale'],
                            y / self.vegetation_params['density_scale'],
                            self.seed,
                            octaves=3,
                            persistence=0.7,
                            lacunarity=2.0
                        )
                        noise_map[y, x] = (noise_value + 1.0) / 2.0  # 转换到0-1范围
            else:
                # 如果没有噪声生成器，使用随机噪声
                noise_map = np.random.rand(height, width).astype(np.float32)
                
            return noise_map
            
        except Exception as e:
            print(f"✗ 植被噪声生成失败: {e}")
            return np.random.rand(height, width).astype(np.float32)
            
    def _generate_vegetation_at_position(self, x: int, y: int, height: float, biome: int, noise: float) -> int:
        """
        在指定位置生成植被
        
        Args:
            x: X坐标
            y: Y坐标
            height: 高度值
            biome: 生物群落类型
            noise: 噪声值
            
        Returns:
            植被类型ID
        """
        try:
            # 检查高度限制
            if height < self.vegetation_params['height_min'] or height > self.vegetation_params['height_max']:
                return 0  # 无植被
                
            # 获取生物群落的植被类型
            biome_veg_types = self.biome_vegetation.get(biome, [0])
            
            # 根据噪声值选择植被类型
            if noise > 0.7 and len(biome_veg_types) > 1:
                # 高噪声值，选择较稀有的植被
                weights = [self.vegetation_types.get(v, {'density': 0.1})['density'] for v in biome_veg_types]
                # 反转权重以使稀有植被更容易被选中
                weights = [1.0 / (w + 0.01) for w in weights]
                vegetation_type = np.random.choice(biome_veg_types, p=np.array(weights) / sum(weights))
            elif noise > 0.4 and len(biome_veg_types) > 1:
                # 中等噪声值，随机选择
                vegetation_type = np.random.choice(biome_veg_types)
            elif len(biome_veg_types) > 0:
                # 低噪声值，选择常见的植被
                weights = [self.vegetation_types.get(v, {'density': 0.1})['density'] for v in biome_veg_types]
                vegetation_type = np.random.choice(biome_veg_types, p=np.array(weights) / sum(weights))
            else:
                vegetation_type = 0  # 无植被
                
            return vegetation_type
            
        except Exception as e:
            print(f"✗ 位置植被生成失败: {e}")
            return 0
            
    def _post_process_vegetation(self, vegetation_map: np.ndarray, heightmap: np.ndarray, biome_map: np.ndarray) -> np.ndarray:
        """
        后处理植被图
        
        Args:
            vegetation_map: 原始植被图
            heightmap: 高度图
            biome_map: 生物群落图
            
        Returns:
            处理后的植被图
        """
        try:
            processed = vegetation_map.copy()
            height, width = processed.shape
            
            # 应用聚类效果
            processed = self._apply_clumping(processed, heightmap)
            
            # 应用坡度限制
            processed = self._apply_slope_limit(processed, heightmap)
            
            # 应用边缘混合
            processed = self._apply_edge_blending(processed)
            
            return processed
            
        except Exception as e:
            print(f"✗ 植被后处理失败: {e}")
            return vegetation_map
            
    def _apply_clumping(self, vegetation_map: np.ndarray, heightmap: np.ndarray) -> np.ndarray:
        """
        应用植被聚类效果
        
        Args:
            vegetation_map: 植被图
            heightmap: 高度图
            
        Returns:
            处理后的植被图
        """
        try:
            processed = vegetation_map.copy()
            height, width = processed.shape
            clumping_factor = self.vegetation_params['clumping_factor']
            
            # 对每个植被类型应用聚类
            for y in range(height):
                for x in range(width):
                    if vegetation_map[y, x] != 0:  # 如果有植被
                        # 检查邻居是否有相同类型的植被
                        same_type_neighbors = 0
                        total_neighbors = 0
                        
                        for dy in [-1, 0, 1]:
                            for dx in [-1, 0, 1]:
                                if dy == 0 and dx == 0:
                                    continue
                                    
                                ny, nx = y + dy, x + dx
                                if 0 <= ny < height and 0 <= nx < width:
                                    total_neighbors += 1
                                    if vegetation_map[ny, nx] == vegetation_map[y, x]:
                                        same_type_neighbors += 1
                                        
                        # 根据邻居情况调整植被类型
                        if total_neighbors > 0:
                            similarity = same_type_neighbors / total_neighbors
                            if similarity < clumping_factor and np.random.random() > 0.5:
                                # 减少孤立的植被
                                processed[y, x] = 0
                                
            return processed
            
        except Exception as e:
            print(f"✗ 植被聚类应用失败: {e}")
            return vegetation_map
            
    def _apply_slope_limit(self, vegetation_map: np.ndarray, heightmap: np.ndarray) -> np.ndarray:
        """
        应用坡度限制
        
        Args:
            vegetation_map: 植被图
            heightmap: 高度图
            
        Returns:
            处理后的植被图
        """
        try:
            processed = vegetation_map.copy()
            height, width = processed.shape
            slope_tolerance = self.vegetation_params['slope_tolerance']
            
            # 计算坡度并应用限制
            for y in range(height):
                for x in range(width):
                    if vegetation_map[y, x] != 0:  # 如果有植被
                        # 计算当前位置的坡度
                        slope = self._calculate_slope(heightmap, x, y)
                        
                        # 如果坡度太大，移除植被
                        if slope > slope_tolerance:
                            processed[y, x] = 0
                            
            return processed
            
        except Exception as e:
            print(f"✗ 坡度限制应用失败: {e}")
            return vegetation_map
            
    def _calculate_slope(self, heightmap: np.ndarray, x: int, y: int) -> float:
        """
        计算指定位置的坡度
        
        Args:
            heightmap: 高度图
            x: X坐标
            y: Y坐标
            
        Returns:
            坡度值
        """
        try:
            height, width = heightmap.shape
            
            # 计算梯度
            dx = 0.0
            dy = 0.0
            
            # X方向梯度
            if x > 0 and x < width - 1:
                dx = (heightmap[y, x + 1] - heightmap[y, x - 1]) / 2.0
            elif x == 0:
                dx = heightmap[y, x + 1] - heightmap[y, x]
            else:
                dx = heightmap[y, x] - heightmap[y, x - 1]
                
            # Y方向梯度
            if y > 0 and y < height - 1:
                dy = (heightmap[y + 1, x] - heightmap[y - 1, x]) / 2.0
            elif y == 0:
                dy = heightmap[y + 1, x] - heightmap[y, x]
            else:
                dy = heightmap[y, x] - heightmap[y - 1, x]
                
            # 计算坡度（梯度的模）
            slope = math.sqrt(dx * dx + dy * dy)
            return slope
            
        except Exception as e:
            print(f"✗ 坡度计算失败: {e}")
            return 0.0
            
    def _apply_edge_blending(self, vegetation_map: np.ndarray) -> np.ndarray:
        """
        应用边缘混合
        
        Args:
            vegetation_map: 植被图
            
        Returns:
            处理后的植被图
        """
        try:
            processed = vegetation_map.copy()
            height, width = processed.shape
            blend_width = max(1, int(min(height, width) * self.vegetation_params['edge_blending']))
            
            # 简化的边缘混合
            for y in range(height):
                for x in range(width):
                    # 在边缘区域随机减少植被
                    if (x < blend_width or x > width - blend_width or 
                        y < blend_width or y > height - blend_width):
                        if np.random.random() < 0.3:  # 30%概率移除边缘植被
                            processed[y, x] = 0
                            
            return processed
            
        except Exception as e:
            print(f"✗ 边缘混合应用失败: {e}")
            return vegetation_map
            
    def _update_vegetation_distribution_stats(self, vegetation_map: np.ndarray):
        """更新植被分布统计"""
        try:
            unique, counts = np.unique(vegetation_map, return_counts=True)
            for veg_id, count in zip(unique, counts):
                veg_name = self.vegetation_types.get(veg_id, {}).get('name', f'vegetation_{veg_id}')
                self.stats['vegetation_distribution'][veg_name] = self.stats['vegetation_distribution'].get(veg_name, 0) + count
                
        except Exception as e:
            print(f"✗ 植被分布统计更新失败: {e}")
            
    def set_seed(self, seed: int):
        """
        设置随机种子
        
        Args:
            seed: 随机种子
        """
        self.seed = seed
        print(f"✓ 植被生成器随机种子设置为: {seed}")
        
    def set_vegetation_parameters(self, params: Dict[str, Any]):
        """
        设置植被生成参数
        
        Args:
            params: 参数字典
        """
        self.vegetation_params.update(params)
        print(f"✓ 植被生成参数已更新: {self.vegetation_params}")
        
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        # 更新平均生成时间
        if self.stats['vegetation_generated'] > 0:
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
        return self.stats.copy()
        
    def get_vegetation_info(self, vegetation_id: int) -> Dict[str, Any]:
        """
        获取植被信息
        
        Args:
            vegetation_id: 植被ID
            
        Returns:
            植被信息字典
        """
        return self.vegetation_types.get(vegetation_id, {
            'name': f'unknown_{vegetation_id}',
            'density': 0.1,
            'color': (128, 128, 128)
        })
        
    def get_available_vegetation(self) -> List[Dict[str, Any]]:
        """
        获取可用的植被类型列表
        
        Returns:
            植被信息列表
        """
        return [self.get_vegetation_info(veg_id) for veg_id in sorted(self.vegetation_types.keys())]
        
    def generate_vegetation_with_density(self, heightmap: np.ndarray, biome_map: np.ndarray, 
                                       density_map: np.ndarray, seed: int = None) -> np.ndarray:
        """
        根据密度图生成植被
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            density_map: 植被密度图数据
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成基于密度的植被分布...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 确保密度图尺寸匹配
            if density_map.shape != heightmap.shape:
                print("✗ 密度图尺寸与高度图不匹配")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 为每个像素生成植被
            print("  → 生成密度控制的植被...")
            for y in range(height):
                for x in range(width):
                    # 获取当前位置的属性
                    height_value = heightmap[y, x]
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    density_value = density_map[y, x]
                    
                    # 根据密度值决定是否生成植被
                    if np.random.random() < density_value:
                        # 生成植被
                        vegetation_type = self._generate_vegetation_at_position(
                            x, y, height_value, biome_type, np.random.random()
                        )
                        self.vegetation_map[y, x] = vegetation_type
                        
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 基于密度的植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 基于密度的植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)
            
    def generate_forest_vegetation(self, heightmap: np.ndarray, biome_map: np.ndarray, 
                                 tree_density: float = 0.15, seed: int = None) -> np.ndarray:
        """
        生成森林植被（专门用于森林区域）
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            tree_density: 树木密度
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成森林植被...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 专门处理森林生物群落（ID 3 和 4）
            forest_biomes = [3, 4]  # forest 和 jungle
            
            # 为每个像素生成森林植被
            print("  → 生成森林植被...")
            for y in range(height):
                for x in range(width):
                    height_value = heightmap[y, x]
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    
                    # 只在森林生物群落中生成植被
                    if biome_type in forest_biomes:
                        # 根据树木密度决定是否生成树
                        if np.random.random() < tree_density:
                            # 选择合适的树种
                            if biome_type == 4:  # jungle
                                tree_type = 6 if np.random.random() < 0.3 else 4  # 30%概率生成棕榈树
                            else:  # forest
                                tree_type = 5 if height_value > 0.8 else 4  # 高海拔生成松树
                                
                            self.vegetation_map[y, x] = tree_type
                        else:
                            # 生成地面植被
                            ground_vegetation = [1, 2, 8, 9]  # grass, shrub, bush, fern
                            self.vegetation_map[y, x] = np.random.choice(ground_vegetation)
                            
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 森林植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 森林植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)
            
    def generate_desert_vegetation(self, heightmap: np.ndarray, biome_map: np.ndarray, 
                                 cactus_density: float = 0.05, seed: int = None) -> np.ndarray:
        """
        生成沙漠植被（专门用于沙漠区域）
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            cactus_density: 仙人掌密度
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成沙漠植被...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 专门处理沙漠生物群落（ID 5）
            desert_biome = 5
            
            # 为每个像素生成沙漠植被
            print("  → 生成沙漠植被...")
            for y in range(height):
                for x in range(width):
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    
                    # 只在沙漠生物群落中生成植被
                    if biome_type == desert_biome:
                        # 根据仙人掌密度决定是否生成仙人掌
                        if np.random.random() < cactus_density:
                            self.vegetation_map[y, x] = 7  # cactus
                        else:
                            # 生成稀疏的地面植被
                            if np.random.random() < 0.1:  # 10%概率
                                ground_vegetation = [1, 2, 8]  # grass, shrub, bush
                                self.vegetation_map[y, x] = np.random.choice(ground_vegetation)
                                
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 沙漠植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 沙漠植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)
            
    def generate_water_vegetation(self, heightmap: np.ndarray, biome_map: np.ndarray, 
                                water_level: float = 0.2, seed: int = None) -> np.ndarray:
        """
        生成水下植被（专门用于水域）
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            water_level: 水位
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成水下植被...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 专门处理水域生物群落（ID 0）
            water_biome = 0
            
            # 为每个像素生成水下植被
            print("  → 生成水下植被...")
            for y in range(height):
                for x in range(width):
                    height_value = heightmap[y, x]
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    
                    # 只在水域中且低于水位的地方生成植被
                    if biome_type == water_biome and height_value < water_level:
                        # 生成水下植被
                        water_vegetation = [12, 13, 14, 15]  # seaweed, algae, kelp, coral
                        self.vegetation_map[y, x] = np.random.choice(water_vegetation)
                        
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 水下植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 水下植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)
            
    def blend_vegetation_maps(self, vegetation_maps: List[np.ndarray], weights: List[float] = None) -> np.ndarray:
        """
        混合多个植被图
        
        Args:
            vegetation_maps: 植被图列表
            weights: 权重列表（如果为None，则平均分配权重）
            
        Returns:
            混合后的植被图
        """
        try:
            if not vegetation_maps:
                return np.array([])
                
            if len(vegetation_maps) == 1:
                return vegetation_maps[0].copy()
                
            # 确保所有植被图尺寸相同
            base_shape = vegetation_maps[0].shape
            for vm in vegetation_maps:
                if vm.shape != base_shape:
                    raise ValueError("所有植被图必须具有相同的尺寸")
                    
            # 处理权重
            if weights is None:
                weights = [1.0 / len(vegetation_maps)] * len(vegetation_maps)
            elif len(weights) != len(vegetation_maps):
                raise ValueError("权重数量必须与植被图数量相同")
                
            # 归一化权重
            total_weight = sum(weights)
            if total_weight > 0:
                weights = [w / total_weight for w in weights]
                
            # 混合植被图
            height, width = base_shape
            blended = np.zeros(base_shape, dtype=np.int32)
            
            # 为每个像素计算加权植被类型
            for y in range(height):
                for x in range(width):
                    # 计算每个植被类型的加权投票
                    veg_votes = {}
                    for i, (vm, weight) in enumerate(zip(vegetation_maps, weights)):
                        veg_type = vm[y, x]
                        veg_votes[veg_type] = veg_votes.get(veg_type, 0.0) + weight
                        
                    # 选择得票最多的植被类型
                    blended[y, x] = max(veg_votes, key=veg_votes.get)
                    
            return blended
            
        except Exception as e:
            print(f"✗ 植被图混合失败: {e}")
            import traceback
            traceback.print_exc()
            # 返回第一个植被图的副本
            return vegetation_maps[0].copy() if vegetation_maps else np.array([])
            
    def smooth_vegetation_map(self, vegetation_map: np.ndarray, iterations: int = 1) -> np.ndarray:
        """
        平滑植被图
        
        Args:
            vegetation_map: 原始植被图
            iterations: 平滑迭代次数
            
        Returns:
            平滑后的植被图
        """
        try:
            smoothed = vegetation_map.copy()
            height, width = smoothed.shape
            
            for _ in range(iterations):
                new_map = smoothed.copy()
                
                # 对每个像素进行平滑处理
                for y in range(height):
                    for x in range(width):
                        # 统计邻居的植被类型
                        neighbor_types = []
                        
                        # 检查8个邻居
                        for dy in [-1, 0, 1]:
                            for dx in [-1, 0, 1]:
                                if dy == 0 and dx == 0:
                                    continue
                                    
                                ny, nx = y + dy, x + dx
                                if 0 <= ny < height and 0 <= nx < width:
                                    neighbor_types.append(smoothed[ny, nx])
                                    
                        # 如果大多数邻居是相同类型，则改变当前像素
                        if neighbor_types:
                            unique, counts = np.unique(neighbor_types, return_counts=True)
                            most_common_type = unique[np.argmax(counts)]
                            most_common_count = np.max(counts)
                            
                            # 如果超过一半的邻居是相同类型，则采用该类型
                            if most_common_count > len(neighbor_types) / 2:
                                new_map[y, x] = most_common_type
                                
                smoothed = new_map
                
            return smoothed
            
        except Exception as e:
            print(f"✗ 植被图平滑失败: {e}")
            return vegetation_map
            
    def generate_vegetation_colors(self, vegetation_map: np.ndarray) -> np.ndarray:
        """
        为植被图生成颜色表示
        
        Args:
            vegetation_map: 植被图
            
        Returns:
            颜色图 (height, width, 3)
        """
        try:
            height, width = vegetation_map.shape
            color_map = np.zeros((height, width, 3), dtype=np.uint8)
            
            # 为每个植被类型分配颜色
            for y in range(height):
                for x in range(width):
                    veg_id = vegetation_map[y, x]
                    veg_info = self.vegetation_types.get(veg_id, {'color': (128, 128, 128)})
                    color_map[y, x] = veg_info['color']
                    
            return color_map
            
        except Exception as e:
            print(f"✗ 植被颜色图生成失败: {e}")
            height, width = vegetation_map.shape
            return np.zeros((height, width, 3), dtype=np.uint8)
            
    def export_vegetation_legend(self, filename: str) -> bool:
        """
        导出植被图例
        
        Args:
            filename: 文件名
            
        Returns:
            是否导出成功
        """
        try:
            import json
            
            legend_data = {}
            for veg_id, veg_info in self.vegetation_types.items():
                legend_data[veg_id] = {
                    'name': veg_info['name'],
                    'color': veg_info['color'],
                    'density': veg_info['density']
                }
                
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(legend_data, f, ensure_ascii=False, indent=2)
                
            print(f"✓ 植被图例已导出到: {filename}")
            return True
            
        except Exception as e:
            print(f"✗ 植被图例导出失败: {e}")
            return False
            
    def import_vegetation_legend(self, filename: str) -> bool:
        """
        导入植被图例
        
        Args:
            filename: 文件名
            
        Returns:
            是否导入成功
        """
        try:
            import json
            
            with open(filename, 'r', encoding='utf-8') as f:
                legend_data = json.load(f)
                
            # 更新植被类型
            self.vegetation_types = {}
            for veg_id, veg_info in legend_data.items():
                self.vegetation_types[int(veg_id)] = {
                    'name': veg_info['name'],
                    'color': tuple(veg_info['color']),
                    'density': veg_info['density']
                }
                
            print(f"✓ 植被图例已从 {filename} 导入")
            return True
            
        except Exception as e:
            print(f"✗ 植被图例导入失败: {e}")
            return False
            
    def get_vegetation_distribution_stats(self) -> Dict[str, int]:
        """
        获取植被分布统计
        
        Returns:
            植被分布统计字典
        """
        return self.stats['vegetation_distribution'].copy()
        
    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'vegetation_generated': 0,
            'total_generation_time': 0.0,
            'average_generation_time': 0.0,
            'vegetation_distribution': {}
        }
        print("✓ 植被生成器统计信息已重置")
        
    def set_vegetation_types(self, vegetation_types: Dict[int, Dict[str, Any]]):
        """
        设置植被类型
        
        Args:
            vegetation_types: 植被类型字典
        """
        self.vegetation_types = vegetation_types
        print(f"✓ 植被类型已更新，共 {len(vegetation_types)} 种植被")
        
    def add_vegetation_type(self, vegetation_id: int, vegetation_info: Dict[str, Any]):
        """
        添加植被类型
        
        Args:
            vegetation_id: 植被ID
            vegetation_info: 植被信息
        """
        self.vegetation_types[vegetation_id] = vegetation_info
        print(f"✓ 植被类型 {vegetation_info['name']} (ID: {vegetation_id}) 已添加")
        
    def remove_vegetation_type(self, vegetation_id: int):
        """
        移除植被类型
        
        Args:
            vegetation_id: 植被ID
        """
        if vegetation_id in self.vegetation_types:
            veg_name = self.vegetation_types[vegetation_id]['name']
            del self.vegetation_types[vegetation_id]
            print(f"✓ 植被类型 {veg_name} (ID: {vegetation_id}) 已移除")
        else:
            print(f"✗ 无效的植被ID: {vegetation_id}")
            
    def modify_vegetation_type(self, vegetation_id: int, modifications: Dict[str, Any]):
        """
        修改植被类型
        
        Args:
            vegetation_id: 植被ID
            modifications: 修改内容
        """
        if vegetation_id in self.vegetation_types:
            self.vegetation_types[vegetation_id].update(modifications)
            print(f"✓ 植被类型 (ID: {vegetation_id}) 已修改")
        else:
            print(f"✗ 无效的植被ID: {vegetation_id}")
            
    def set_biome_vegetation(self, biome_id: int, vegetation_types: List[int]):
        """
        设置生物群落的植被类型
        
        Args:
            biome_id: 生物群落ID
            vegetation_types: 植被类型列表
        """
        self.biome_vegetation[biome_id] = vegetation_types
        print(f"✓ 生物群落 {biome_id} 的植被类型已设置为: {vegetation_types}")
        
    def get_biome_vegetation(self, biome_id: int) -> List[int]:
        """
        获取生物群落的植被类型
        
        Args:
            biome_id: 生物群落ID
            
        Returns:
            植被类型列表
        """
        return self.biome_vegetation.get(biome_id, []).copy()
        
    def generate_vegetation_density_map(self, heightmap: np.ndarray, biome_map: np.ndarray) -> np.ndarray:
        """
        生成植被密度图
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            
        Returns:
            植被密度图
        """
        try:
            height, width = heightmap.shape
            density_map = np.zeros((height, width), dtype=np.float32)
            
            # 为每个生物群落生成不同的密度模式
            for y in range(height):
                for x in range(width):
                    biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                    height_value = heightmap[y, x]
                    
                    # 根据生物群落类型确定基础密度
                    if biome_type == 0:  # ocean
                        density_map[y, x] = 0.0
                    elif biome_type == 1:  # beach
                        density_map[y, x] = 0.1
                    elif biome_type == 2:  # plains
                        density_map[y, x] = 0.4
                    elif biome_type in [3, 4]:  # forest, jungle
                        density_map[y, x] = 0.8
                    elif biome_type == 5:  # desert
                        density_map[y, x] = 0.05
                    elif biome_type == 6:  # mountain
                        # 山地密度随高度变化
                        density_map[y, x] = max(0.0, 0.6 - height_value)
                    elif biome_type in [7, 8, 9]:  # snow, taiga, tundra
                        density_map[y, x] = 0.3
                    elif biome_type == 10:  # swamp
                        density_map[y, x] = 0.6
                    elif biome_type == 11:  # savanna
                        density_map[y, x] = 0.3
                    else:
                        density_map[y, x] = 0.2
                        
            # 应用噪声以增加自然变化
            if self.noise_generator:
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_noise(
                            x / 20.0, y / 20.0, self.seed + 5000
                        )
                        density_map[y, x] = max(0.0, min(1.0, density_map[y, x] + noise_value * 0.1))
                        
            return density_map
            
        except Exception as e:
            print(f"✗ 植被密度图生成失败: {e}")
            return np.zeros_like(heightmap, dtype=np.float32)
            
    def apply_vegetation_mask(self, vegetation_map: np.ndarray, mask: np.ndarray) -> np.ndarray:
        """
        应用掩码到植被图
        
        Args:
            vegetation_map: 原始植被图
            mask: 掩码（0-1范围，0表示移除植被）
            
        Returns:
            处理后的植被图
        """
        try:
            if mask.shape != vegetation_map.shape:
                print("✗ 掩码尺寸与植被图不匹配")
                return vegetation_map
                
            masked = vegetation_map.copy()
            
            # 根据掩码值调整植被
            for y in range(masked.shape[0]):
                for x in range(masked.shape[1]):
                    # 掩码值越小，移除植被的概率越大
                    if np.random.random() > mask[y, x]:
                        masked[y, x] = 0  # 移除植被
                        
            return masked
            
        except Exception as e:
            print(f"✗ 植被掩码应用失败: {e}")
            return vegetation_map
            
    def generate_clustered_vegetation(self, heightmap: np.ndarray, biome_map: np.ndarray, 
                                    cluster_density: float = 0.2, seed: int = None) -> np.ndarray:
        """
        生成聚类植被
        
        Args:
            heightmap: 高度图数据
            biome_map: 生物群落图数据
            cluster_density: 聚类密度
            seed: 随机种子
            
        Returns:
            植被分布图
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 植被生成器未启用")
                return np.zeros_like(heightmap, dtype=np.int32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            print("✓ 开始生成聚类植被...")
            
            # 初始化随机数生成器
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建植被图
            height, width = heightmap.shape
            self.vegetation_map = np.zeros((height, width), dtype=np.int32)
            
            # 生成聚类中心点
            num_clusters = int(width * height * cluster_density / 100)
            clusters = []
            for _ in range(num_clusters):
                x = np.random.randint(0, width)
                y = np.random.randint(0, height)
                biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                # 获取该生物群落的植被类型
                veg_types = self.biome_vegetation.get(biome_type, [1, 2])  # 默认为草和灌木
                veg_type = np.random.choice(veg_types) if veg_types else 1
                cluster_size = np.random.randint(5, 20)  # 聚类大小
                clusters.append((x, y, veg_type, cluster_size))
                
            # 在聚类中心点周围生成植被
            print("  → 生成植被聚类...")
            for cx, cy, veg_type, cluster_size in clusters:
                for _ in range(cluster_size):
                    # 在聚类中心附近随机生成植被
                    angle = np.random.random() * 2 * np.pi
                    distance = np.random.random() * cluster_size / 2
                    x = int(cx + np.cos(angle) * distance)
                    y = int(cy + np.sin(angle) * distance)
                    
                    # 确保坐标在有效范围内
                    if 0 <= x < width and 0 <= y < height:
                        # 检查该位置是否适合该植被类型
                        height_value = heightmap[y, x]
                        biome_type = biome_map[y, x] if y < biome_map.shape[0] and x < biome_map.shape[1] else 0
                        
                        # 简单的适宜性检查
                        if height_value > 0.1 and biome_type != 0:  # 不在水中
                            self.vegetation_map[y, x] = veg_type
                            
            # 应用后处理
            print("  → 应用后处理...")
            self.vegetation_map = self._post_process_vegetation(self.vegetation_map, heightmap, biome_map)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['vegetation_generated'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['vegetation_generated']
            
            # 更新植被分布统计
            self._update_vegetation_distribution_stats(self.vegetation_map)
            
            print(f"✓ 聚类植被生成完成，耗时: {generation_time:.2f}秒")
            return self.vegetation_map
            
        except Exception as e:
            print(f"✗ 聚类植被生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros_like(heightmap, dtype=np.int32)