"""
地形编辑器
提供可视化界面用于编辑和调整程序化生成的地形
"""

import numpy as np
import math
from typing import Dict, Any, List, Tuple, Optional
import json
import time

class TerrainEditor:
    """
    地形编辑器
    提供可视化界面用于编辑和调整程序化生成的地形，包括参数调整、实时预览、笔刷工具等功能
    """
    
    def __init__(self, plugin):
        """
        初始化地形编辑器
        
        Args:
            plugin: 程序化地形生成插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 编辑器配置
        self.editor_params = {
            'brush_size': 10,
            'brush_strength': 0.5,
            'brush_type': 'raise',  # 'raise', 'lower', 'smooth', 'flatten', 'noise'
            'edit_mode': 'terrain',  # 'terrain', 'biome', 'vegetation', 'water'
            'preview_enabled': True,
            'realtime_update': True,
            'history_limit': 50
        }
        
        # 笔刷类型定义
        self.brush_types = {
            'raise': {'name': '抬高', 'description': '抬高地形'},
            'lower': {'name': '降低', 'description': '降低地形'},
            'smooth': {'name': '平滑', 'description': '平滑地形'},
            'flatten': {'name': '平整', 'description': '将地形平整到指定高度'},
            'noise': {'name': '噪声', 'description': '添加噪声效果'},
            'erode': {'name': '侵蚀', 'description': '模拟侵蚀效果'},
            'paint': {'name': '绘制', 'description': '绘制生物群落或植被'}
        }
        
        # 编辑历史
        self.edit_history = []
        self.history_position = -1
        
        # 当前选择
        self.selected_area = None
        self.selected_brush_position = None
        
        # 预览数据
        self.preview_data = None
        self.preview_dirty = False
        
        # 工具状态
        self.is_painting = False
        self.last_paint_position = None
        
        # 统计信息
        self.stats = {
            'edits_made': 0,
            'undos_performed': 0,
            'redos_performed': 0,
            'total_edit_time': 0.0,
            'average_edit_time': 0.0
        }
        
        # UI组件引用（在实际实现中会连接到GUI）
        self.ui_components = {
            'toolbar': None,
            'properties_panel': None,
            'preview_window': None,
            'brush_settings': None,
            'history_panel': None
        }
        
        print("✓ 地形编辑器已创建")
        
    def initialize(self) -> bool:
        """
        初始化地形编辑器
        
        Returns:
            是否初始化成功
        """
        try:
            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: 时间增量
        """
        try:
            if not self.enabled:
                return
                
            # 更新预览
            if self.preview_dirty and self.editor_params['preview_enabled']:
                self._update_preview()
                
            # 处理实时更新
            if self.editor_params['realtime_update']:
                self._handle_realtime_updates()
                
        except Exception as e:
            print(f"✗ 地形编辑器更新失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _update_preview(self):
        """更新预览显示"""
        try:
            # 在实际实现中，这里会更新预览窗口
            self.preview_dirty = False
        except Exception as e:
            print(f"✗ 预览更新失败: {e}")
            
    def _handle_realtime_updates(self):
        """处理实时更新"""
        try:
            # 在实际实现中，这里会处理实时编辑更新
            pass
        except Exception as e:
            print(f"✗ 实时更新处理失败: {e}")
            
    def set_brush_size(self, size: int):
        """
        设置笔刷大小
        
        Args:
            size: 笔刷大小（像素）
        """
        self.editor_params['brush_size'] = max(1, size)
        print(f"✓ 笔刷大小设置为: {size}")
        
    def set_brush_strength(self, strength: float):
        """
        设置笔刷强度
        
        Args:
            strength: 笔刷强度 (0.0-1.0)
        """
        self.editor_params['brush_strength'] = max(0.0, min(1.0, strength))
        print(f"✓ 笔刷强度设置为: {strength}")
        
    def set_brush_type(self, brush_type: str):
        """
        设置笔刷类型
        
        Args:
            brush_type: 笔刷类型
        """
        if brush_type in self.brush_types:
            self.editor_params['brush_type'] = brush_type
            print(f"✓ 笔刷类型设置为: {self.brush_types[brush_type]['name']}")
        else:
            print(f"✗ 无效的笔刷类型: {brush_type}")
            
    def set_edit_mode(self, mode: str):
        """
        设置编辑模式
        
        Args:
            mode: 编辑模式 ('terrain', 'biome', 'vegetation', 'water')
        """
        valid_modes = ['terrain', 'biome', 'vegetation', 'water']
        if mode in valid_modes:
            self.editor_params['edit_mode'] = mode
            print(f"✓ 编辑模式设置为: {mode}")
        else:
            print(f"✗ 无效的编辑模式: {mode}")
            
    def set_preview_enabled(self, enabled: bool):
        """
        设置预览是否启用
        
        Args:
            enabled: 是否启用预览
        """
        self.editor_params['preview_enabled'] = enabled
        print(f"✓ 预览{'已启用' if enabled else '已禁用'}")
        
    def set_realtime_update(self, enabled: bool):
        """
        设置实时更新是否启用
        
        Args:
            enabled: 是否启用实时更新
        """
        self.editor_params['realtime_update'] = enabled
        print(f"✓ 实时更新{'已启用' if enabled else '已禁用'}")
        
    def begin_paint(self, x: int, y: int):
        """
        开始绘制操作
        
        Args:
            x: X坐标
            y: Y坐标
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            self.is_painting = True
            self.last_paint_position = (x, y)
            
            # 保存当前状态到历史记录
            self._save_state_to_history()
            
            # 执行绘制操作
            self._apply_brush(x, y)
            
        except Exception as e:
            print(f"✗ 开始绘制失败: {e}")
            import traceback
            traceback.print_exc()
            
    def continue_paint(self, x: int, y: int):
        """
        继续绘制操作
        
        Args:
            x: X坐标
            y: Y坐标
        """
        try:
            if not self.enabled or not self.is_painting:
                return
                
            # 如果位置发生变化，执行绘制
            if self.last_paint_position != (x, y):
                self._apply_brush_stroke(self.last_paint_position, (x, y))
                self.last_paint_position = (x, y)
                
        except Exception as e:
            print(f"✗ 绘制过程失败: {e}")
            import traceback
            traceback.print_exc()
            
    def end_paint(self):
        """结束绘制操作"""
        try:
            self.is_painting = False
            self.last_paint_position = None
            
            # 更新统计信息
            self.stats['edits_made'] += 1
            
        except Exception as e:
            print(f"✗ 结束绘制失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_brush(self, x: int, y: int):
        """
        应用笔刷效果
        
        Args:
            x: X坐标
            y: Y坐标
        """
        try:
            brush_type = self.editor_params['brush_type']
            brush_size = self.editor_params['brush_size']
            brush_strength = self.editor_params['brush_strength']
            edit_mode = self.editor_params['edit_mode']
            
            # 获取当前地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                
                if edit_mode == 'terrain':
                    self._apply_terrain_brush(terrain_data, x, y, brush_type, brush_size, brush_strength)
                elif edit_mode == 'biome':
                    self._apply_biome_brush(terrain_data, x, y, brush_type, brush_size, brush_strength)
                elif edit_mode == 'vegetation':
                    self._apply_vegetation_brush(terrain_data, x, y, brush_type, brush_size, brush_strength)
                elif edit_mode == 'water':
                    self._apply_water_brush(terrain_data, x, y, brush_type, brush_size, brush_strength)
                    
                # 标记预览需要更新
                self.preview_dirty = True
                
        except Exception as e:
            print(f"✗ 笔刷应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_brush_stroke(self, start_pos: Tuple[int, int], end_pos: Tuple[int, int]):
        """
        应用笔刷笔触（在两点之间绘制）
        
        Args:
            start_pos: 起始位置 (x, y)
            end_pos: 结束位置 (x, y)
        """
        try:
            # 使用直线算法在两点之间插值
            x0, y0 = start_pos
            x1, y1 = end_pos
            
            # 计算距离
            distance = math.sqrt((x1 - x0)**2 + (y1 - y0)**2)
            
            # 如果距离很小，只应用一次
            if distance <= 1:
                self._apply_brush(x1, y1)
                return
                
            # 在两点之间插值
            steps = int(distance)
            for i in range(steps + 1):
                t = i / steps if steps > 0 else 0
                x = int(x0 + (x1 - x0) * t)
                y = int(y0 + (y1 - y0) * t)
                self._apply_brush(x, y)
                
        except Exception as e:
            print(f"✗ 笔触应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_terrain_brush(self, terrain_data: Dict[str, Any], x: int, y: int, 
                           brush_type: str, brush_size: int, brush_strength: float):
        """
        应用地形笔刷
        
        Args:
            terrain_data: 地形数据
            x: X坐标
            y: Y坐标
            brush_type: 笔刷类型
            brush_size: 笔刷大小
            brush_strength: 笔刷强度
        """
        try:
            heightmap = terrain_data.get('heightmap')
            if heightmap is None:
                return
                
            height, width = heightmap.shape
            
            # 计算笔刷影响区域
            min_x = max(0, x - brush_size)
            max_x = min(width - 1, x + brush_size)
            min_y = max(0, y - brush_size)
            max_y = min(height - 1, y + brush_size)
            
            # 创建笔刷形状（圆形）
            brush_radius = brush_size
            brush_radius_sq = brush_radius * brush_radius
            
            # 应用笔刷效果
            for by in range(min_y, max_y + 1):
                for bx in range(min_x, max_x + 1):
                    # 计算到笔刷中心的距离
                    dx = bx - x
                    dy = by - y
                    distance_sq = dx * dx + dy * dy
                    
                    # 如果在笔刷范围内
                    if distance_sq <= brush_radius_sq:
                        # 计算笔刷影响强度（边缘递减）
                        distance = math.sqrt(distance_sq)
                        influence = max(0.0, 1.0 - distance / brush_radius)
                        effective_strength = brush_strength * influence
                        
                        # 根据笔刷类型应用不同效果
                        if brush_type == 'raise':
                            heightmap[by, bx] = min(1.0, heightmap[by, bx] + effective_strength * 0.1)
                        elif brush_type == 'lower':
                            heightmap[by, bx] = max(0.0, heightmap[by, bx] - effective_strength * 0.1)
                        elif brush_type == 'smooth':
                            # 简单的平滑处理
                            neighbors = []
                            for ny in range(max(0, by - 1), min(height, by + 2)):
                                for nx in range(max(0, bx - 1), min(width, bx + 2)):
                                    neighbors.append(heightmap[ny, nx])
                            if neighbors:
                                avg_height = sum(neighbors) / len(neighbors)
                                heightmap[by, bx] = heightmap[by, bx] * (1 - effective_strength) + avg_height * effective_strength
                        elif brush_type == 'flatten':
                            # 平整到固定高度（这里使用0.5作为示例）
                            target_height = 0.5
                            heightmap[by, bx] = heightmap[by, bx] * (1 - effective_strength) + target_height * effective_strength
                        elif brush_type == 'noise':
                            # 添加噪声
                            noise = (np.random.random() - 0.5) * effective_strength * 0.2
                            heightmap[by, bx] = max(0.0, min(1.0, heightmap[by, bx] + noise))
                        elif brush_type == 'erode':
                            # 简单的侵蚀效果
                            heightmap[by, bx] = max(0.0, heightmap[by, bx] - effective_strength * 0.05)
                            
        except Exception as e:
            print(f"✗ 地形笔刷应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_biome_brush(self, terrain_data: Dict[str, Any], x: int, y: int, 
                          brush_type: str, brush_size: int, brush_strength: float):
        """
        应用生物群落笔刷
        
        Args:
            terrain_data: 地形数据
            x: X坐标
            y: Y坐标
            brush_type: 笔刷类型
            brush_size: 笔刷大小
            brush_strength: 笔刷强度
        """
        try:
            biome_map = terrain_data.get('biome_map')
            if biome_map is None:
                return
                
            height, width = biome_map.shape
            
            # 计算笔刷影响区域
            min_x = max(0, x - brush_size)
            max_x = min(width - 1, x + brush_size)
            min_y = max(0, y - brush_size)
            max_y = min(height - 1, y + brush_size)
            
            # 创建笔刷形状（圆形）
            brush_radius = brush_size
            brush_radius_sq = brush_radius * brush_radius
            
            # 应用笔刷效果
            for by in range(min_y, max_y + 1):
                for bx in range(min_x, max_x + 1):
                    # 计算到笔刷中心的距离
                    dx = bx - x
                    dy = by - y
                    distance_sq = dx * dx + dy * dy
                    
                    # 如果在笔刷范围内
                    if distance_sq <= brush_radius_sq:
                        # 计算笔刷影响强度（边缘递减）
                        distance = math.sqrt(distance_sq)
                        influence = max(0.0, 1.0 - distance / brush_radius)
                        effective_strength = brush_strength * influence
                        
                        # 根据笔刷类型应用不同效果
                        if brush_type == 'paint':
                            # 绘制生物群落（这里简单地设置为生物群落类型1）
                            if effective_strength > 0.5:  # 只有强度足够时才改变
                                biome_map[by, bx] = 1  # 设置为草原生物群落
                                
        except Exception as e:
            print(f"✗ 生物群落笔刷应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_vegetation_brush(self, terrain_data: Dict[str, Any], x: int, y: int, 
                               brush_type: str, brush_size: int, brush_strength: float):
        """
        应用植被笔刷
        
        Args:
            terrain_data: 地形数据
            x: X坐标
            y: Y坐标
            brush_type: 笔刷类型
            brush_size: 笔刷大小
            brush_strength: 笔刷强度
        """
        try:
            vegetation_map = terrain_data.get('vegetation_map')
            if vegetation_map is None:
                return
                
            height, width = vegetation_map.shape
            
            # 计算笔刷影响区域
            min_x = max(0, x - brush_size)
            max_x = min(width - 1, x + brush_size)
            min_y = max(0, y - brush_size)
            max_y = min(height - 1, y + brush_size)
            
            # 创建笔刷形状（圆形）
            brush_radius = brush_size
            brush_radius_sq = brush_radius * brush_radius
            
            # 应用笔刷效果
            for by in range(min_y, max_y + 1):
                for bx in range(min_x, max_x + 1):
                    # 计算到笔刷中心的距离
                    dx = bx - x
                    dy = by - y
                    distance_sq = dx * dx + dy * dy
                    
                    # 如果在笔刷范围内
                    if distance_sq <= brush_radius_sq:
                        # 计算笔刷影响强度（边缘递减）
                        distance = math.sqrt(distance_sq)
                        influence = max(0.0, 1.0 - distance / brush_radius)
                        effective_strength = brush_strength * influence
                        
                        # 根据笔刷类型应用不同效果
                        if brush_type == 'paint':
                            # 绘制植被（这里简单地设置为植被类型1）
                            if effective_strength > 0.3:  # 只有强度足够时才改变
                                vegetation_map[by, bx] = 1  # 设置为草
                                
        except Exception as e:
            print(f"✗ 植被笔刷应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_water_brush(self, terrain_data: Dict[str, Any], x: int, y: int, 
                          brush_type: str, brush_size: int, brush_strength: float):
        """
        应用水笔刷
        
        Args:
            terrain_data: 地形数据
            x: X坐标
            y: Y坐标
            brush_type: 笔刷类型
            brush_size: 笔刷大小
            brush_strength: 笔刷强度
        """
        try:
            water_map = terrain_data.get('water_map')
            if water_map is None:
                return
                
            height, width = water_map.shape
            
            # 计算笔刷影响区域
            min_x = max(0, x - brush_size)
            max_x = min(width - 1, x + brush_size)
            min_y = max(0, y - brush_size)
            max_y = min(height - 1, y + brush_size)
            
            # 创建笔刷形状（圆形）
            brush_radius = brush_size
            brush_radius_sq = brush_radius * brush_radius
            
            # 应用笔刷效果
            for by in range(min_y, max_y + 1):
                for bx in range(min_x, max_x + 1):
                    # 计算到笔刷中心的距离
                    dx = bx - x
                    dy = by - y
                    distance_sq = dx * dx + dy * dy
                    
                    # 如果在笔刷范围内
                    if distance_sq <= brush_radius_sq:
                        # 计算笔刷影响强度（边缘递减）
                        distance = math.sqrt(distance_sq)
                        influence = max(0.0, 1.0 - distance / brush_radius)
                        effective_strength = brush_strength * influence
                        
                        # 根据笔刷类型应用不同效果
                        if brush_type == 'raise':
                            water_map[by, bx] = min(1.0, water_map[by, bx] + effective_strength * 0.1)
                        elif brush_type == 'lower':
                            water_map[by, bx] = max(0.0, water_map[by, bx] - effective_strength * 0.1)
                        elif brush_type == 'paint':
                            # 设置固定水位
                            water_map[by, bx] = 0.3  # 设置为中等水位
                            
        except Exception as e:
            print(f"✗ 水笔刷应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _save_state_to_history(self):
        """保存当前状态到历史记录"""
        try:
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                
                # 创建状态快照
                state_snapshot = {
                    'timestamp': time.time(),
                    'heightmap': terrain_data.get('heightmap', np.array([])).copy() if terrain_data.get('heightmap') is not None else np.array([]),
                    'biome_map': terrain_data.get('biome_map', np.array([])).copy() if terrain_data.get('biome_map') is not None else np.array([]),
                    'vegetation_map': terrain_data.get('vegetation_map', np.array([])).copy() if terrain_data.get('vegetation_map') is not None else np.array([]),
                    'water_map': terrain_data.get('water_map', np.array([])).copy() if terrain_data.get('water_map') is not None else np.array([])
                }
                
                # 添加到历史记录
                if self.history_position < len(self.edit_history) - 1:
                    # 如果当前不在历史记录末尾，截断后续记录
                    self.edit_history = self.edit_history[:self.history_position + 1]
                    
                self.edit_history.append(state_snapshot)
                self.history_position += 1
                
                # 限制历史记录数量
                if len(self.edit_history) > self.editor_params['history_limit']:
                    self.edit_history.pop(0)
                    self.history_position -= 1
                    
        except Exception as e:
            print(f"✗ 状态保存失败: {e}")
            import traceback
            traceback.print_exc()
            
    def undo(self) -> bool:
        """
        撤销操作
        
        Returns:
            是否撤销成功
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return False
                
            if self.history_position <= 0:
                print("✗ 没有可撤销的操作")
                return False
                
            # 移动到前一个历史状态
            self.history_position -= 1
            
            # 恢复状态
            self._restore_state_from_history()
            
            # 更新统计信息
            self.stats['undos_performed'] += 1
            
            print("✓ 撤销操作完成")
            return True
            
        except Exception as e:
            print(f"✗ 撤销操作失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def redo(self) -> bool:
        """
        重做操作
        
        Returns:
            是否重做成功
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return False
                
            if self.history_position >= len(self.edit_history) - 1:
                print("✗ 没有可重做的操作")
                return False
                
            # 移动到下一个历史状态
            self.history_position += 1
            
            # 恢复状态
            self._restore_state_from_history()
            
            # 更新统计信息
            self.stats['redos_performed'] += 1
            
            print("✓ 重做操作完成")
            return True
            
        except Exception as e:
            print(f"✗ 重做操作失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def _restore_state_from_history(self):
        """从历史记录恢复状态"""
        try:
            if not self.plugin.terrain_manager or self.history_position < 0:
                return
                
            # 获取历史状态
            state = self.edit_history[self.history_position]
            
            # 恢复地形数据
            terrain_data = self.plugin.terrain_manager.get_terrain_data()
            
            if 'heightmap' in state and state['heightmap'].size > 0:
                terrain_data['heightmap'] = state['heightmap']
                
            if 'biome_map' in state and state['biome_map'].size > 0:
                terrain_data['biome_map'] = state['biome_map']
                
            if 'vegetation_map' in state and state['vegetation_map'].size > 0:
                terrain_data['vegetation_map'] = state['vegetation_map']
                
            if 'water_map' in state and state['water_map'].size > 0:
                terrain_data['water_map'] = state['water_map']
                
            # 标记预览需要更新
            self.preview_dirty = True
            
        except Exception as e:
            print(f"✗ 状态恢复失败: {e}")
            import traceback
            traceback.print_exc()
            
    def clear_history(self):
        """清空历史记录"""
        try:
            self.edit_history.clear()
            self.history_position = -1
            print("✓ 历史记录已清空")
        except Exception as e:
            print(f"✗ 历史记录清空失败: {e}")
            import traceback
            traceback.print_exc()
            
    def select_area(self, x1: int, y1: int, x2: int, y2: int):
        """
        选择区域
        
        Args:
            x1: 起始X坐标
            y1: 起始Y坐标
            x2: 结束X坐标
            y2: 结束Y坐标
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            # 标准化坐标
            min_x = min(x1, x2)
            max_x = max(x1, x2)
            min_y = min(y1, y2)
            max_y = max(y1, y2)
            
            self.selected_area = (min_x, min_y, max_x, max_y)
            print(f"✓ 区域已选择: ({min_x}, {min_y}) to ({max_x}, {max_y})")
            
        except Exception as e:
            print(f"✗ 区域选择失败: {e}")
            import traceback
            traceback.print_exc()
            
    def clear_selection(self):
        """清除选择"""
        try:
            self.selected_area = None
            print("✓ 选择已清除")
        except Exception as e:
            print(f"✗ 选择清除失败: {e}")
            import traceback
            traceback.print_exc()
            
    def fill_selection(self, fill_type: str = 'flatten', fill_value: float = 0.5):
        """
        填充选择区域
        
        Args:
            fill_type: 填充类型 ('flatten', 'noise', 'smooth')
            fill_value: 填充值（用于flatten）
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            if self.selected_area is None:
                print("✗ 没有选择区域")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 获取选择区域
            min_x, min_y, max_x, max_y = self.selected_area
            
            # 获取地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                heightmap = terrain_data.get('heightmap')
                
                if heightmap is not None:
                    # 填充区域
                    for y in range(min_y, max_y + 1):
                        for x in range(min_x, max_x + 1):
                            if fill_type == 'flatten':
                                heightmap[y, x] = fill_value
                            elif fill_type == 'noise':
                                heightmap[y, x] = np.random.random()
                            elif fill_type == 'smooth':
                                # 简单平滑处理
                                neighbors = []
                                h, w = heightmap.shape
                                for ny in range(max(0, y - 1), min(h, y + 2)):
                                    for nx in range(max(0, x - 1), min(w, x + 2)):
                                        neighbors.append(heightmap[ny, nx])
                                if neighbors:
                                    heightmap[y, x] = sum(neighbors) / len(neighbors)
                                    
                    # 标记预览需要更新
                    self.preview_dirty = True
                    
                    # 更新统计信息
                    self.stats['edits_made'] += 1
                    
                    print(f"✓ 区域填充完成: {fill_type}")
                    
        except Exception as e:
            print(f"✗ 区域填充失败: {e}")
            import traceback
            traceback.print_exc()
            
    def apply_filter_to_selection(self, filter_type: str = 'smooth', filter_strength: float = 1.0):
        """
        对选择区域应用滤镜
        
        Args:
            filter_type: 滤镜类型 ('smooth', 'sharpen', 'erode', 'dilate')
            filter_strength: 滤镜强度
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            if self.selected_area is None:
                print("✗ 没有选择区域")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 获取选择区域
            min_x, min_y, max_x, max_y = self.selected_area
            
            # 获取地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                heightmap = terrain_data.get('heightmap')
                
                if heightmap is not None:
                    # 创建处理后的副本
                    processed_heightmap = heightmap.copy()
                    
                    # 应用滤镜
                    if filter_type == 'smooth':
                        self._apply_smoothing_filter(heightmap, processed_heightmap, min_x, min_y, max_x, max_y, filter_strength)
                    elif filter_type == 'sharpen':
                        self._apply_sharpening_filter(heightmap, processed_heightmap, min_x, min_y, max_x, max_y, filter_strength)
                    elif filter_type == 'erode':
                        self._apply_erosion_filter(heightmap, processed_heightmap, min_x, min_y, max_x, max_y, filter_strength)
                    elif filter_type == 'dilate':
                        self._apply_dilation_filter(heightmap, processed_heightmap, min_x, min_y, max_x, max_y, filter_strength)
                        
                    # 更新原高度图
                    heightmap[min_y:max_y+1, min_x:max_x+1] = processed_heightmap[min_y:max_y+1, min_x:max_x+1]
                    
                    # 标记预览需要更新
                    self.preview_dirty = True
                    
                    # 更新统计信息
                    self.stats['edits_made'] += 1
                    
                    print(f"✓ 滤镜应用完成: {filter_type}")
                    
        except Exception as e:
            print(f"✗ 滤镜应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def _apply_smoothing_filter(self, original: np.ndarray, processed: np.ndarray, 
                               min_x: int, min_y: int, max_x: int, max_y: int, strength: float):
        """应用平滑滤镜"""
        try:
            height, width = original.shape
            
            for y in range(min_y, max_y + 1):
                for x in range(min_x, max_x + 1):
                    # 计算邻域平均值
                    neighbors = []
                    for dy in [-1, 0, 1]:
                        for dx in [-1, 0, 1]:
                            ny, nx = y + dy, x + dx
                            if 0 <= ny < height and 0 <= nx < width:
                                neighbors.append(original[ny, nx])
                                
                    if neighbors:
                        avg_value = sum(neighbors) / len(neighbors)
                        processed[y, x] = original[y, x] * (1 - strength) + avg_value * strength
                        
        except Exception as e:
            print(f"✗ 平滑滤镜应用失败: {e}")
            
    def _apply_sharpening_filter(self, original: np.ndarray, processed: np.ndarray, 
                                min_x: int, min_y: int, max_x: int, max_y: int, strength: float):
        """应用锐化滤镜"""
        try:
            height, width = original.shape
            
            # 简单的锐化核
            kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
            
            for y in range(max(min_y, 1), min(max_y + 1, height - 1)):
                for x in range(max(min_x, 1), min(max_x + 1, width - 1)):
                    # 应用卷积
                    value = 0.0
                    for ky in [-1, 0, 1]:
                        for kx in [-1, 0, 1]:
                            value += original[y + ky, x + kx] * kernel[ky + 1, kx + 1]
                            
                    # 限制值范围并应用强度
                    value = max(0.0, min(1.0, value))
                    processed[y, x] = original[y, x] * (1 - strength) + value * strength
                    
        except Exception as e:
            print(f"✗ 锐化滤镜应用失败: {e}")
            
    def _apply_erosion_filter(self, original: np.ndarray, processed: np.ndarray, 
                             min_x: int, min_y: int, max_x: int, max_y: int, strength: float):
        """应用侵蚀滤镜"""
        try:
            height, width = original.shape
            
            for y in range(min_y, max_y + 1):
                for x in range(min_x, max_x + 1):
                    # 简单的侵蚀：降低高度
                    processed[y, x] = max(0.0, original[y, x] - 0.1 * strength)
                    
        except Exception as e:
            print(f"✗ 侵蚀滤镜应用失败: {e}")
            
    def _apply_dilation_filter(self, original: np.ndarray, processed: np.ndarray, 
                              min_x: int, min_y: int, max_x: int, max_y: int, strength: float):
        """应用膨胀滤镜"""
        try:
            height, width = original.shape
            
            for y in range(min_y, max_y + 1):
                for x in range(min_x, max_x + 1):
                    # 简单的膨胀：增加高度
                    processed[y, x] = min(1.0, original[y, x] + 0.1 * strength)
                    
        except Exception as e:
            print(f"✗ 膨胀滤镜应用失败: {e}")
            
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        # 更新平均编辑时间
        total_edits = self.stats['edits_made'] + self.stats['undos_performed'] + self.stats['redos_performed']
        if total_edits > 0:
            self.stats['average_edit_time'] = self.stats['total_edit_time'] / total_edits
        return self.stats.copy()
        
    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'edits_made': 0,
            'undos_performed': 0,
            'redos_performed': 0,
            'total_edit_time': 0.0,
            'average_edit_time': 0.0
        }
        print("✓ 地形编辑器统计信息已重置")
        
    def set_editor_parameters(self, params: Dict[str, Any]):
        """
        设置编辑器参数
        
        Args:
            params: 参数字典
        """
        self.editor_params.update(params)
        print(f"✓ 编辑器参数已更新: {self.editor_params}")
        
    def get_brush_types(self) -> Dict[str, Dict[str, str]]:
        """
        获取可用的笔刷类型
        
        Returns:
            笔刷类型字典
        """
        return self.brush_types.copy()
        
    def get_edit_modes(self) -> List[str]:
        """
        获取可用的编辑模式
        
        Returns:
            编辑模式列表
        """
        return ['terrain', 'biome', 'vegetation', 'water']
        
    def export_brush_preset(self, preset_name: str, filename: str) -> bool:
        """
        导出笔刷预设
        
        Args:
            preset_name: 预设名称
            filename: 文件名
            
        Returns:
            是否导出成功
        """
        try:
            # 创建预设数据
            preset_data = {
                'name': preset_name,
                'brush_size': self.editor_params['brush_size'],
                'brush_strength': self.editor_params['brush_strength'],
                'brush_type': self.editor_params['brush_type'],
                'edit_mode': self.editor_params['edit_mode'],
                'timestamp': time.time()
            }
            
            # 保存为JSON文件
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(preset_data, f, ensure_ascii=False, indent=2)
                
            print(f"✓ 笔刷预设已导出到: {filename}")
            return True
            
        except Exception as e:
            print(f"✗ 笔刷预设导出失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def import_brush_preset(self, filename: str) -> bool:
        """
        导入笔刷预设
        
        Args:
            filename: 文件名
            
        Returns:
            是否导入成功
        """
        try:
            # 读取JSON文件
            with open(filename, 'r', encoding='utf-8') as f:
                preset_data = json.load(f)
                
            # 应用预设
            if 'brush_size' in preset_data:
                self.set_brush_size(preset_data['brush_size'])
            if 'brush_strength' in preset_data:
                self.set_brush_strength(preset_data['brush_strength'])
            if 'brush_type' in preset_data:
                self.set_brush_type(preset_data['brush_type'])
            if 'edit_mode' in preset_data:
                self.set_edit_mode(preset_data['edit_mode'])
                
            print(f"✓ 笔刷预设已从 {filename} 导入")
            return True
            
        except Exception as e:
            print(f"✗ 笔刷预设导入失败: {e}")
            import traceback
            traceback.print_exc()
            return False
            
    def create_custom_brush(self, brush_name: str, brush_function: callable) -> bool:
        """
        创建自定义笔刷
        
        Args:
            brush_name: 笔刷名称
            brush_function: 笔刷函数
            
        Returns:
            是否创建成功
        """
        try:
            # 在实际实现中，这里会注册自定义笔刷函数
            self.brush_types[brush_name] = {
                'name': brush_name,
                'description': '自定义笔刷',
                'function': brush_function
            }
            
            print(f"✓ 自定义笔刷 '{brush_name}' 已创建")
            return True
            
        except Exception as e:
            print(f"✗ 自定义笔刷创建失败: {e}")
            return False
            
    def set_ui_component(self, component_name: str, component: Any):
        """
        设置UI组件引用
        
        Args:
            component_name: 组件名称
            component: 组件引用
        """
        if component_name in self.ui_components:
            self.ui_components[component_name] = component
            print(f"✓ UI组件 '{component_name}' 已设置")
        else:
            print(f"✗ 无效的UI组件名称: {component_name}")
            
    def refresh_ui(self):
        """刷新UI显示"""
        try:
            # 在实际实现中，这里会更新所有UI组件的显示
            print("✓ UI刷新完成")
        except Exception as e:
            print(f"✗ UI刷新失败: {e}")
            
    def show_preview_window(self):
        """显示预览窗口"""
        try:
            # 在实际实现中，这里会创建并显示预览窗口
            print("✓ 预览窗口已显示")
        except Exception as e:
            print(f"✗ 预览窗口显示失败: {e}")
            
    def hide_preview_window(self):
        """隐藏预览窗口"""
        try:
            # 在实际实现中，这里会隐藏预览窗口
            print("✓ 预览窗口已隐藏")
        except Exception as e:
            print(f"✗ 预览窗口隐藏失败: {e}")
            
    def update_preview_window(self):
        """更新预览窗口内容"""
        try:
            # 在实际实现中，这里会更新预览窗口的内容
            print("✓ 预览窗口已更新")
        except Exception as e:
            print(f"✗ 预览窗口更新失败: {e}")
            
    def set_brush_position(self, x: int, y: int):
        """
        设置笔刷位置（用于预览显示）
        
        Args:
            x: X坐标
            y: Y坐标
        """
        try:
            self.selected_brush_position = (x, y)
            # 在实际实现中，这里会更新UI上的笔刷预览位置
        except Exception as e:
            print(f"✗ 笔刷位置设置失败: {e}")
            
    def clear_brush_position(self):
        """清除笔刷位置"""
        try:
            self.selected_brush_position = None
            # 在实际实现中，这里会清除UI上的笔刷预览位置
        except Exception as e:
            print(f"✗ 笔刷位置清除失败: {e}")
            
    def apply_generator_to_selection(self, generator_type: str = 'mountain', generator_params: Dict[str, Any] = None):
        """
        对选择区域应用生成器
        
        Args:
            generator_type: 生成器类型 ('mountain', 'valley', 'plateau', 'crater', 'island')
            generator_params: 生成器参数
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            if self.selected_area is None:
                print("✗ 没有选择区域")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 获取选择区域
            min_x, min_y, max_x, max_y = self.selected_area
            width = max_x - min_x + 1
            height = max_y - min_y + 1
            
            # 获取地形数据
            if self.plugin.terrain_manager and self.plugin.heightmap_generator:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                heightmap = terrain_data.get('heightmap')
                
                if heightmap is not None:
                    # 生成新的地形片段
                    if generator_type == 'mountain':
                        new_heightmap = self.plugin.heightmap_generator.generate_mountain_heightmap(width, height)
                    elif generator_type == 'valley':
                        new_heightmap = self.plugin.heightmap_generator.generate_valley_heightmap(width, height)
                    elif generator_type == 'plateau':
                        new_heightmap = self.plugin.heightmap_generator.generate_plateau_heightmap(width, height)
                    elif generator_type == 'crater':
                        new_heightmap = self.plugin.heightmap_generator.generate_crater_heightmap(width, height)
                    elif generator_type == 'island':
                        new_heightmap = self.plugin.heightmap_generator.generate_island_heightmap(width, height)
                    else:
                        # 默认使用基础噪声生成
                        new_heightmap = self.plugin.heightmap_generator.generate_heightmap(width, height)
                        
                    # 应用到选择区域
                    heightmap[min_y:max_y+1, min_x:max_x+1] = new_heightmap
                    
                    # 标记预览需要更新
                    self.preview_dirty = True
                    
                    # 更新统计信息
                    self.stats['edits_made'] += 1
                    
                    print(f"✓ 生成器应用完成: {generator_type}")
                    
        except Exception as e:
            print(f"✗ 生成器应用失败: {e}")
            import traceback
            traceback.print_exc()
            
    def clone_area(self, source_x1: int, source_y1: int, source_x2: int, source_y2: int,
                   target_x: int, target_y: int):
        """
        克隆区域
        
        Args:
            source_x1: 源区域起始X坐标
            source_y1: 源区域起始Y坐标
            source_x2: 源区域结束X坐标
            source_y2: 源区域结束Y坐标
            target_x: 目标位置X坐标
            target_y: 目标位置Y坐标
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 标准化源区域坐标
            source_min_x = min(source_x1, source_x2)
            source_max_x = max(source_x1, source_x2)
            source_min_y = min(source_y1, source_y2)
            source_max_y = max(source_y1, source_y2)
            
            # 计算区域尺寸
            region_width = source_max_x - source_min_x + 1
            region_height = source_max_y - source_min_y + 1
            
            # 获取地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                
                # 克隆高度图
                heightmap = terrain_data.get('heightmap')
                if heightmap is not None:
                    # 确保源区域有效
                    if (0 <= source_min_x < heightmap.shape[1] and 
                        0 <= source_max_x < heightmap.shape[1] and
                        0 <= source_min_y < heightmap.shape[0] and 
                        0 <= source_max_y < heightmap.shape[0]):
                        
                        # 提取源区域
                        source_region = heightmap[source_min_y:source_max_y+1, source_min_x:source_max_x+1].copy()
                        
                        # 计算目标区域边界
                        target_min_x = target_x
                        target_max_x = target_x + region_width - 1
                        target_min_y = target_y
                        target_max_y = target_y + region_height - 1
                        
                        # 确保目标区域在地图范围内
                        if (0 <= target_min_x < heightmap.shape[1] and 
                            0 <= target_max_x < heightmap.shape[1] and
                            0 <= target_min_y < heightmap.shape[0] and 
                            0 <= target_max_y < heightmap.shape[0]):
                            
                            # 应用到目标区域
                            heightmap[target_min_y:target_max_y+1, target_min_x:target_max_x+1] = source_region
                            
                            # 标记预览需要更新
                            self.preview_dirty = True
                            
                            # 更新统计信息
                            self.stats['edits_made'] += 1
                            
                            print("✓ 区域克隆完成")
                            return
                            
                print("✗ 无法克隆区域：源区域或目标区域超出边界")
                
        except Exception as e:
            print(f"✗ 区域克隆失败: {e}")
            import traceback
            traceback.print_exc()
            
    def flip_area(self, horizontal: bool = True, vertical: bool = False):
        """
        翻转选择区域
        
        Args:
            horizontal: 是否水平翻转
            vertical: 是否垂直翻转
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            if self.selected_area is None:
                print("✗ 没有选择区域")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 获取选择区域
            min_x, min_y, max_x, max_y = self.selected_area
            
            # 获取地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                
                # 翻转高度图
                heightmap = terrain_data.get('heightmap')
                if heightmap is not None:
                    region = heightmap[min_y:max_y+1, min_x:max_x+1]
                    if horizontal:
                        region = np.fliplr(region)
                    if vertical:
                        region = np.flipud(region)
                    heightmap[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 翻转生物群落图
                biome_map = terrain_data.get('biome_map')
                if biome_map is not None:
                    region = biome_map[min_y:max_y+1, min_x:max_x+1]
                    if horizontal:
                        region = np.fliplr(region)
                    if vertical:
                        region = np.flipud(region)
                    biome_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 翻转植被图
                vegetation_map = terrain_data.get('vegetation_map')
                if vegetation_map is not None:
                    region = vegetation_map[min_y:max_y+1, min_x:max_x+1]
                    if horizontal:
                        region = np.fliplr(region)
                    if vertical:
                        region = np.flipud(region)
                    vegetation_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 翻转水图
                water_map = terrain_data.get('water_map')
                if water_map is not None:
                    region = water_map[min_y:max_y+1, min_x:max_x+1]
                    if horizontal:
                        region = np.fliplr(region)
                    if vertical:
                        region = np.flipud(region)
                    water_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 标记预览需要更新
                self.preview_dirty = True
                
                # 更新统计信息
                self.stats['edits_made'] += 1
                
                print("✓ 区域翻转完成")
                
        except Exception as e:
            print(f"✗ 区域翻转失败: {e}")
            import traceback
            traceback.print_exc()
            
    def rotate_area(self, angle: int = 90):
        """
        旋转选择区域
        
        Args:
            angle: 旋转角度 (90, 180, 270)
        """
        try:
            if not self.enabled:
                print("✗ 地形编辑器未启用")
                return
                
            if self.selected_area is None:
                print("✗ 没有选择区域")
                return
                
            # 保存状态到历史记录
            self._save_state_to_history()
            
            # 获取选择区域
            min_x, min_y, max_x, max_y = self.selected_area
            region_width = max_x - min_x + 1
            region_height = max_y - min_y + 1
            
            # 只支持正方形区域的旋转
            if region_width != region_height:
                print("✗ 只支持正方形区域的旋转")
                return
                
            # 获取地形数据
            if self.plugin.terrain_manager:
                terrain_data = self.plugin.terrain_manager.get_terrain_data()
                
                # 旋转高度图
                heightmap = terrain_data.get('heightmap')
                if heightmap is not None:
                    region = heightmap[min_y:max_y+1, min_x:max_x+1]
                    if angle == 90:
                        region = np.rot90(region, k=1)
                    elif angle == 180:
                        region = np.rot90(region, k=2)
                    elif angle == 270:
                        region = np.rot90(region, k=3)
                    heightmap[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 旋转生物群落图
                biome_map = terrain_data.get('biome_map')
                if biome_map is not None:
                    region = biome_map[min_y:max_y+1, min_x:max_x+1]
                    if angle == 90:
                        region = np.rot90(region, k=1)
                    elif angle == 180:
                        region = np.rot90(region, k=2)
                    elif angle == 270:
                        region = np.rot90(region, k=3)
                    biome_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 旋转植被图
                vegetation_map = terrain_data.get('vegetation_map')
                if vegetation_map is not None:
                    region = vegetation_map[min_y:max_y+1, min_x:max_x+1]
                    if angle == 90:
                        region = np.rot90(region, k=1)
                    elif angle == 180:
                        region = np.rot90(region, k=2)
                    elif angle == 270:
                        region = np.rot90(region, k=3)
                    vegetation_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 旋转水图
                water_map = terrain_data.get('water_map')
                if water_map is not None:
                    region = water_map[min_y:max_y+1, min_x:max_x+1]
                    if angle == 90:
                        region = np.rot90(region, k=1)
                    elif angle == 180:
                        region = np.rot90(region, k=2)
                    elif angle == 270:
                        region = np.rot90(region, k=3)
                    water_map[min_y:max_y+1, min_x:max_x+1] = region
                    
                # 标记预览需要更新
                self.preview_dirty = True
                
                # 更新统计信息
                self.stats['edits_made'] += 1
                
                print(f"✓ 区域旋转完成 ({angle}度)")
                
        except Exception as e:
            print(f"✗ 区域旋转失败: {e}")
            import traceback
            traceback.print_exc()