import pygame
import sys
import math
import random
import colorsys
from typing import List, Tuple, Optional
import json
import os
from datetime import datetime

# 初始化 Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 1200, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT), pygame.DOUBLEBUF | pygame.HWSURFACE)
pygame.display.set_caption("🎆 动态烟花模拟 - 元宝出品")

# 帧率控制
clock = pygame.time.Clock()
FPS = 60

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 150, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 70, 200)
CYAN = (0, 255, 255)
ORANGE = (255, 150, 0)
PINK = (255, 105, 180)

# 创建背景
def create_starry_background():
    """创建星空背景"""
    stars = []
    for _ in range(200):
        x = random.randint(0, WIDTH)
        y = random.randint(0, HEIGHT)
        size = random.uniform(0.1, 2.0)
        brightness = random.randint(150, 255)
        twinkle_speed = random.uniform(0.5, 2.0)
        stars.append({
            'pos': (x, y),
            'size': size,
            'brightness': brightness,
            'twinkle': 0,
            'speed': twinkle_speed,
            'color': (brightness, brightness, brightness)
        })
    return stars

def create_cityscape():
    """创建城市天际线"""
    buildings = []
    for _ in range(30):
        x = random.randint(0, WIDTH)
        width = random.randint(20, 80)
        height = random.randint(50, 300)
        color = tuple(random.randint(20, 60) for _ in range(3))
        windows = []
        for _ in range(random.randint(3, 15)):
            wx = random.randint(x + 5, x + width - 5)
            wy = random.randint(HEIGHT - height + 5, HEIGHT - 5)
            if random.random() > 0.7:  # 30%的窗户亮着
                windows.append((wx, wy, random.randint(1, 3)))
        buildings.append({
            'rect': pygame.Rect(x, HEIGHT - height, width, height),
            'color': color,
            'windows': windows
        })
    return buildings

class Particle:
    """基础粒子类"""
    def __init__(self, x, y, vx, vy, color, size, lifetime, gravity=0.2, decay=0.98, trail=False):
        self.x = x
        self.y = y
        self.vx = vx
        self.vy = vy
        self.color = color
        self.original_color = color
        self.size = size
        self.max_lifetime = lifetime
        self.lifetime = lifetime
        self.gravity = gravity
        self.decay = decay
        self.trail = trail
        self.trail_particles = []
        self.max_trail_length = 5
        
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += self.gravity
        self.vx *= self.decay
        self.vy *= self.decay
        self.lifetime -= 1
        
        # 添加轨迹效果
        if self.trail and self.lifetime % 3 == 0:
            trail_color = (
                int(self.color[0] * 0.7),
                int(self.color[1] * 0.7),
                int(self.color[2] * 0.7)
            )
            self.trail_particles.append({
                'x': self.x,
                'y': self.y,
                'size': self.size * 0.5,
                'lifetime': 10,
                'color': trail_color
            })
        
        # 更新轨迹粒子
        for trail in self.trail_particles[:]:
            trail['lifetime'] -= 1
            if trail['lifetime'] <= 0:
                self.trail_particles.remove(trail)
        
        # 生命周期结束时颜色变暗
        if self.lifetime < self.max_lifetime * 0.3:
            fade = self.lifetime / (self.max_lifetime * 0.3)
            self.color = (
                int(self.original_color[0] * fade),
                int(self.original_color[1] * fade),
                int(self.original_color[2] * fade)
            )
        
        return self.lifetime > 0
    
    def draw(self, surface):
        # 绘制轨迹
        for trail in self.trail_particles:
            alpha = int(255 * (trail['lifetime'] / 10))
            trail_surface = pygame.Surface((int(trail['size'] * 2), int(trail['size'] * 2)), pygame.SRCALPHA)
            pygame.draw.circle(trail_surface, (*trail['color'], alpha), 
                             (int(trail['size']), int(trail['size'])), int(trail['size']))
            surface.blit(trail_surface, (int(trail['x'] - trail['size']), int(trail['y'] - trail['size'])))
        
        # 绘制主粒子
        alpha = 255
        if self.lifetime < self.max_lifetime * 0.3:
            alpha = int(255 * (self.lifetime / (self.max_lifetime * 0.3)))
        
        # 创建带透明度的表面
        particle_surface = pygame.Surface((int(self.size * 2), int(self.size * 2)), pygame.SRCALPHA)
        
        # 绘制发光效果
        for i in range(3, 0, -1):
            glow_size = self.size + i
            glow_alpha = alpha // (i + 1)
            glow_color = (*self.color[:3], glow_alpha)
            pygame.draw.circle(particle_surface, glow_color, 
                             (int(self.size), int(self.size)), int(glow_size))
        
        # 绘制核心
        pygame.draw.circle(particle_surface, (*self.color, alpha), 
                         (int(self.size), int(self.size)), int(self.size))
        
        surface.blit(particle_surface, (int(self.x - self.size), int(self.y - self.size)))

class Firework:
    """烟花类"""
    def __init__(self, x, y, firework_type="normal", color=None, size_multiplier=1.0):
        self.x = x
        self.y = y
        self.type = firework_type
        self.color = color or self.get_random_color()
        self.size_multiplier = size_multiplier
        self.particles = []
        self.exploded = False
        self.phase = 0  # 0:上升, 1:爆炸, 2:消散
        self.timer = 0
        self.max_height = random.randint(100, HEIGHT // 2)
        self.ascend_speed = random.uniform(3, 6) * size_multiplier
        
        # 创建上升轨迹粒子
        self.ascend_particles = []
        
        # 根据类型设置参数
        self.setup_firework()
        
    def setup_firework(self):
        """根据烟花类型设置参数"""
        if self.type == "normal":
            self.particle_count = random.randint(50, 120)
            self.explosion_size = random.uniform(80, 150) * self.size_multiplier
        elif self.type == "spiral":
            self.particle_count = random.randint(80, 150)
            self.explosion_size = random.uniform(100, 180) * self.size_multiplier
        elif self.type == "heart":
            self.particle_count = random.randint(100, 180)
            self.explosion_size = random.uniform(120, 200) * self.size_multiplier
        elif self.type == "ring":
            self.particle_count = random.randint(60, 100)
            self.explosion_size = random.uniform(100, 160) * self.size_multiplier
        elif self.type == "fountain":
            self.particle_count = random.randint(40, 80)
            self.explosion_size = random.uniform(60, 120) * self.size_multiplier
        elif self.type == "crackle":
            self.particle_count = random.randint(30, 60)
            self.explosion_size = random.uniform(70, 130) * self.size_multiplier
        elif self.type == "willow":
            self.particle_count = random.randint(100, 200)
            self.explosion_size = random.uniform(150, 250) * self.size_multiplier
        elif self.type == "peony":
            self.particle_count = random.randint(150, 250)
            self.explosion_size = random.uniform(180, 300) * self.size_multiplier
        elif self.type == "chrysanthemum":
            self.particle_count = random.randint(120, 200)
            self.explosion_size = random.uniform(160, 280) * self.size_multiplier
        elif self.type == "crossette":
            self.particle_count = random.randint(80, 140)
            self.explosion_size = random.uniform(120, 200) * self.size_multiplier
        else:
            self.type = "normal"
            self.particle_count = random.randint(50, 120)
            self.explosion_size = random.uniform(80, 150) * self.size_multiplier
    
    def get_random_color(self):
        """获取随机颜色"""
        colors = [
            (255, 50, 50),    # 红
            (50, 255, 50),    # 绿
            (50, 150, 255),   # 蓝
            (255, 255, 50),   # 黄
            (180, 70, 200),   # 紫
            (0, 255, 255),    # 青
            (255, 150, 0),    # 橙
            (255, 105, 180),  # 粉
            (255, 255, 255),  # 白
        ]
        return random.choice(colors)
    
    def get_color_variation(self, base_color, variation=30):
        """获取颜色的变体"""
        return (
            max(0, min(255, base_color[0] + random.randint(-variation, variation))),
            max(0, min(255, base_color[1] + random.randint(-variation, variation))),
            max(0, min(255, base_color[2] + random.randint(-variation, variation)))
        )
    
    def ascend(self):
        """上升阶段"""
        if self.y > self.max_height:
            self.y -= self.ascend_speed
            
            # 添加上升轨迹
            if random.random() < 0.3:
                trail_color = (
                    int(self.color[0] * 0.8),
                    int(self.color[1] * 0.8),
                    int(self.color[2] * 0.8)
                )
                self.ascend_particles.append(Particle(
                    self.x, self.y + 10,
                    random.uniform(-0.5, 0.5), random.uniform(-0.5, 0.5),
                    trail_color,
                    random.uniform(1, 3) * self.size_multiplier,
                    random.randint(20, 40),
                    0.1, 0.95
                ))
            
            return True
        else:
            self.explode()
            return False
    
    def explode(self):
        """爆炸阶段"""
        if not self.exploded:
            self.exploded = True
            self.phase = 1
            
            if self.type == "normal":
                self.create_normal_explosion()
            elif self.type == "spiral":
                self.create_spiral_explosion()
            elif self.type == "heart":
                self.create_heart_explosion()
            elif self.type == "ring":
                self.create_ring_explosion()
            elif self.type == "fountain":
                self.create_fountain_explosion()
            elif self.type == "crackle":
                self.create_crackle_explosion()
            elif self.type == "willow":
                self.create_willow_explosion()
            elif self.type == "peony":
                self.create_peony_explosion()
            elif self.type == "chrysanthemum":
                self.create_chrysanthemum_explosion()
            elif self.type == "crossette":
                self.create_crossette_explosion()
    
    def create_normal_explosion(self):
        """创建普通爆炸"""
        for _ in range(self.particle_count):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(2, 8) * self.size_multiplier
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            particle_color = self.get_color_variation(self.color, 50)
            size = random.uniform(1.5, 4) * self.size_multiplier
            lifetime = random.randint(60, 120)
            
            self.particles.append(Particle(
                self.x, self.y, vx, vy,
                particle_color, size, lifetime,
                0.1, 0.98, trail=True
            ))
    
    def create_spiral_explosion(self):
        """创建螺旋爆炸"""
        arms = random.randint(3, 6)
        particles_per_arm = self.particle_count // arms
        
        for arm in range(arms):
            angle_offset = (arm * 2 * math.pi) / arms
            
            for i in range(particles_per_arm):
                angle = angle_offset + (i * 0.2)
                radius = i * 0.3 * self.size_multiplier
                speed = random.uniform(1, 4) * self.size_multiplier
                
                vx = math.cos(angle) * speed
                vy = math.sin(angle) * speed
                
                # 渐变颜色
                hue = (random.random() + arm/arms) % 1.0
                rgb = colorsys.hsv_to_rgb(hue, 0.8, 1.0)
                particle_color = (int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
                
                size = random.uniform(1, 3) * self.size_multiplier
                lifetime = random.randint(80, 150)
                
                self.particles.append(Particle(
                    self.x + math.cos(angle) * radius,
                    self.y + math.sin(angle) * radius,
                    vx, vy, particle_color, size, lifetime,
                    0.05, 0.985, trail=True
                ))
    
    def create_heart_explosion(self):
        """创建心形爆炸"""
        for i in range(self.particle_count):
            t = i / self.particle_count * math.pi * 2
            # 心形参数方程
            x = 16 * math.sin(t) ** 3
            y = -(13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t))
            
            scale = self.explosion_size * 0.1
            speed = random.uniform(1.5, 4) * self.size_multiplier
            
            vx = math.cos(t) * speed
            vy = math.sin(t) * speed
            
            # 红色系渐变
            hue = 0  # 红色
            sat = random.uniform(0.7, 1.0)
            val = random.uniform(0.8, 1.0)
            rgb = colorsys.hsv_to_rgb(hue, sat, val)
            particle_color = (int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
            
            size = random.uniform(2, 4) * self.size_multiplier
            lifetime = random.randint(100, 180)
            
            self.particles.append(Particle(
                self.x + x * scale,
                self.y + y * scale,
                vx, vy, particle_color, size, lifetime,
                0.08, 0.975, trail=True
            ))
    
    def create_ring_explosion(self):
        """创建环形爆炸"""
        for i in range(self.particle_count):
            angle = (i / self.particle_count) * math.pi * 2
            radius = self.explosion_size * 0.5
            speed = random.uniform(2, 5) * self.size_multiplier
            
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            # 彩虹色
            hue = i / self.particle_count
            rgb = colorsys.hsv_to_rgb(hue, 0.9, 1.0)
            particle_color = (int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
            
            size = random.uniform(1.5, 3) * self.size_multiplier
            lifetime = random.randint(70, 130)
            
            self.particles.append(Particle(
                self.x + math.cos(angle) * radius * 0.3,
                self.y + math.sin(angle) * radius * 0.3,
                vx, vy, particle_color, size, lifetime,
                0.06, 0.98, trail=True
            ))
    
    def create_fountain_explosion(self):
        """创建喷泉效果"""
        for _ in range(self.particle_count):
            angle = random.uniform(-math.pi/3, math.pi/3)  # 向上扇形
            speed = random.uniform(3, 10) * self.size_multiplier
            
            vx = math.cos(angle) * speed + random.uniform(-1, 1)
            vy = -abs(math.sin(angle) * speed)  # 主要向上
            
            particle_color = self.get_color_variation(self.color, 40)
            size = random.uniform(1, 2.5) * self.size_multiplier
            lifetime = random.randint(50, 100)
            
            self.particles.append(Particle(
                self.x, self.y, vx, vy,
                particle_color, size, lifetime,
                0.2, 0.96, trail=False
            ))
    
    def create_crackle_explosion(self):
        """创建噼啪效果"""
        for _ in range(self.particle_count):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(4, 12) * self.size_multiplier
            
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            particle_color = self.get_color_variation(self.color, 30)
            size = random.uniform(0.5, 1.5) * self.size_multiplier
            lifetime = random.randint(30, 60)
            
            particle = Particle(
                self.x, self.y, vx, vy,
                particle_color, size, lifetime,
                0.15, 0.9, trail=False
            )
            
            # 添加二次爆炸
            if random.random() < 0.3 and lifetime > 20:
                particle.secondary_explosion = True
                particle.secondary_timer = random.randint(10, 20)
            
            self.particles.append(particle)
    
    def create_willow_explosion(self):
        """创建柳树效果（向下垂落）"""
        for _ in range(self.particle_count):
            angle = random.uniform(-math.pi/2, math.pi/2)  # 主要向下
            speed = random.uniform(1, 4) * self.size_multiplier
            
            vx = math.cos(angle) * speed * 0.5
            vy = abs(math.sin(angle) * speed)  # 主要向下
            
            particle_color = self.get_color_variation(self.color, 20)
            size = random.uniform(1, 2) * self.size_multiplier
            lifetime = random.randint(120, 200)
            
            self.particles.append(Particle(
                self.x, self.y, vx, vy,
                particle_color, size, lifetime,
                0.05, 0.99, trail=True
            ))
    
    def create_peony_explosion(self):
        """创建牡丹花效果"""
        layers = random.randint(3, 6)
        particles_per_layer = self.particle_count // layers
        
        for layer in range(layers):
            layer_radius = (layer + 1) * 0.2
            
            for i in range(particles_per_layer):
                angle = (i / particles_per_layer) * math.pi * 2
                radius = self.explosion_size * layer_radius
                speed = random.uniform(1, 3) * self.size_multiplier
                
                vx = math.cos(angle) * speed
                vy = math.sin(angle) * speed
                
                # 内层到外层颜色渐变
                hue = (random.random() + layer/layers) % 1.0
                sat = 0.9 - layer * 0.1
                rgb = colorsys.hsv_to_rgb(hue, sat, 1.0)
                particle_color = (int(rgb[0]*255), int(rgb[1]*255), int(rgb[2]*255))
                
                size = random.uniform(2, 4) * self.size_multiplier
                lifetime = random.randint(100, 180)
                
                self.particles.append(Particle(
                    self.x + math.cos(angle) * radius * 0.3,
                    self.y + math.sin(angle) * radius * 0.3,
                    vx, vy, particle_color, size, lifetime,
                    0.04, 0.985, trail=True
                ))
    
    def create_chrysanthemum_explosion(self):
        """创建菊花效果"""
        for _ in range(self.particle_count):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(2, 6) * self.size_multiplier
            
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            particle_color = self.get_color_variation(self.color, 40)
            size = random.uniform(1.5, 3) * self.size_multiplier
            lifetime = random.randint(150, 250)
            
            # 长轨迹效果
            self.particles.append(Particle(
                self.x, self.y, vx, vy,
                particle_color, size, lifetime,
                0.02, 0.995, trail=True
            ))
    
    def create_crossette_explosion(self):
        """创建十字形爆炸"""
        arms = 4
        particles_per_arm = self.particle_count // arms
        
        for arm in range(arms):
            base_angle = (arm * math.pi) / 2  # 0, 90, 180, 270度
            
            for i in range(particles_per_arm):
                angle_var = random.uniform(-0.3, 0.3)
                angle = base_angle + angle_var
                speed = random.uniform(3, 8) * self.size_multiplier
                
                vx = math.cos(angle) * speed
                vy = math.sin(angle) * speed
                
                particle_color = self.get_color_variation(self.color, 30)
                size = random.uniform(1, 2.5) * self.size_multiplier
                lifetime = random.randint(40, 80)
                
                particle = Particle(
                    self.x, self.y, vx, vy,
                    particle_color, size, lifetime,
                    0.12, 0.94, trail=False
                )
                
                # 十字形粒子有50%几率二次爆炸
                if random.random() < 0.5:
                    particle.secondary_explosion = True
                    particle.secondary_timer = random.randint(15, 30)
                    particle.secondary_color = self.get_color_variation(particle_color, 50)
                
                self.particles.append(particle)
    
    def update(self):
        """更新烟花状态"""
        self.timer += 1
        
        # 处理上升阶段
        if not self.exploded:
            if not self.ascend():
                return False
        
        # 更新上升轨迹粒子
        for particle in self.ascend_particles[:]:
            if not particle.update():
                self.ascend_particles.remove(particle)
        
        # 更新爆炸粒子
        for particle in self.particles[:]:
            if not particle.update():
                self.particles.remove(particle)
            
            # 处理二次爆炸
            if hasattr(particle, 'secondary_explosion') and particle.secondary_explosion:
                particle.secondary_timer -= 1
                if particle.secondary_timer <= 0:
                    self.create_secondary_explosion(particle)
                    particle.secondary_explosion = False
        
        # 检查是否结束
        if self.exploded and len(self.particles) == 0 and len(self.ascend_particles) == 0:
            return False
        
        return True
    
    def create_secondary_explosion(self, parent_particle):
        """创建二次爆炸"""
        for _ in range(random.randint(5, 15)):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(1, 3) * self.size_multiplier
            
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            
            color = getattr(parent_particle, 'secondary_color', 
                          self.get_color_variation(parent_particle.color, 60))
            size = parent_particle.size * 0.7
            lifetime = random.randint(20, 40)
            
            self.particles.append(Particle(
                parent_particle.x, parent_particle.y,
                vx, vy, color, size, lifetime,
                0.1, 0.9, trail=False
            ))
    
    def draw(self, surface):
        """绘制烟花"""
        # 绘制上升轨迹粒子
        for particle in self.ascend_particles:
            particle.draw(surface)
        
        # 绘制上升轨迹（如果有）
        if not self.exploded:
            pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), 
                             int(3 * self.size_multiplier))
        
        # 绘制爆炸粒子
        for particle in self.particles:
            particle.draw(surface)

class FireworksSimulation:
    """烟花模拟主类"""
    def __init__(self):
        self.fireworks = []
        self.stars = create_starry_background()
        self.buildings = create_cityscape()
        self.ground_height = HEIGHT - 50
        
        # 控制参数
        self.auto_spawn = True
        self.spawn_timer = 0
        self.spawn_delay = 30  # 自动生成延迟
        
        # 统计
        self.fireworks_launched = 0
        self.max_fireworks = 50
        self.start_time = pygame.time.get_ticks()
        
        # 烟花类型列表
        self.firework_types = [
            "normal", "spiral", "heart", "ring", "fountain",
            "crackle", "willow", "peony", "chrysanthemum", "crossette"
        ]
        
        # 颜色列表
        self.color_palette = [
            (255, 50, 50), (50, 255, 50), (50, 150, 255),
            (255, 255, 50), (180, 70, 200), (0, 255, 255),
            (255, 150, 0), (255, 105, 180), (255, 255, 255)
        ]
        
        # UI状态
        self.show_controls = True
        self.selected_type = "random"
        self.selected_color = "random"
        self.size_multiplier = 1.0
        
        # 声音效果（如果有）
        self.sound_enabled = False
        self.try_init_sound()
        
        # 保存设置
        self.settings = self.load_settings()
    
    def try_init_sound(self):
        """尝试初始化声音"""
        try:
            pygame.mixer.init()
            self.sound_enabled = True
            # 可以在这里加载音效
        except:
            self.sound_enabled = False
    
    def load_settings(self):
        """加载设置"""
        try:
            if os.path.exists('fireworks_settings.json'):
                with open('fireworks_settings.json', 'r') as f:
                    return json.load(f)
        except:
            pass
        return {}
    
    def save_settings(self):
        """保存设置"""
        try:
            with open('fireworks_settings.json', 'w') as f:
                json.dump(self.settings, f)
        except:
            pass
    
    def spawn_firework(self, x=None, y=None, firework_type=None, color=None, size=None):
        """生成烟花"""
        if len(self.fireworks) >= self.max_fireworks:
            return
        
        if x is None:
            x = random.randint(100, WIDTH - 100)
        
        if y is None:
            y = HEIGHT - 50
        
        if firework_type is None or firework_type == "random":
            firework_type = random.choice(self.firework_types)
        
        if color is None or color == "random":
            color = random.choice(self.color_palette)
        elif isinstance(color, str) and color.startswith('#'):
            # 处理十六进制颜色
            hex_color = color.lstrip('#')
            color = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
        
        if size is None:
            size = random.uniform(0.8, 1.5)
        
        firework = Firework(x, y, firework_type, color, size)
        self.fireworks.append(firework)
        self.fireworks_launched += 1
        
        # 播放声音
        if self.sound_enabled:
            self.play_explosion_sound()
    
    def play_explosion_sound(self):
        """播放爆炸声音"""
        # 这里可以添加音效
        pass
    
    def spawn_random_firework(self):
        """生成随机烟花"""
        x = random.randint(100, WIDTH - 100)
        y = HEIGHT - 50
        firework_type = random.choice(self.firework_types)
        color = random.choice(self.color_palette)
        size = random.uniform(0.7, 1.8)
        self.spawn_firework(x, y, firework_type, color, size)
    
    def update(self):
        """更新模拟"""
        # 更新星星闪烁
        for star in self.stars:
            star['twinkle'] += star['speed'] * 0.1
            brightness_var = math.sin(star['twinkle']) * 30
            new_brightness = max(150, min(255, star['brightness'] + brightness_var))
            star['color'] = (new_brightness, new_brightness, new_brightness)
        
        # 自动生成烟花
        if self.auto_spawn:
            self.spawn_timer += 1
            if self.spawn_timer >= self.spawn_delay:
                self.spawn_random_firework()
                self.spawn_timer = 0
                # 随机化下一次生成延迟
                self.spawn_delay = random.randint(20, 60)
        
        # 更新烟花
        for firework in self.fireworks[:]:
            if not firework.update():
                self.fireworks.remove(firework)
    
    def draw_background(self, surface):
        """绘制背景"""
        # 渐变夜空
        for y in range(HEIGHT):
            # 从顶部的深蓝到底部的黑色
            factor = y / HEIGHT
            r = int(10 + 15 * (1 - factor))
            g = int(20 + 35 * (1 - factor))
            b = int(40 + 60 * (1 - factor))
            pygame.draw.line(surface, (r, g, b), (0, y), (WIDTH, y))
        
        # 绘制星星
        for star in self.stars:
            pygame.draw.circle(surface, star['color'], 
                             (int(star['pos'][0]), int(star['pos'][1])), 
                             int(star['size']))
        
        # 绘制城市天际线
        for building in self.buildings:
            pygame.draw.rect(surface, building['color'], building['rect'])
            # 绘制窗户
            for wx, wy, size in building['windows']:
                if random.random() > 0.3:  # 70%的亮窗几率
                    pygame.draw.rect(surface, (255, 255, 200), 
                                   (wx, wy, size, size))
        
        # 绘制地面
        pygame.draw.rect(surface, (20, 20, 30), (0, HEIGHT - 50, WIDTH, 50))
        
        # 绘制草地纹理
        for i in range(0, WIDTH, 5):
            height = random.randint(2, 8)
            pygame.draw.line(surface, (30, 100, 30), 
                           (i, HEIGHT - 50), (i, HEIGHT - 50 + height), 2)
    
    def draw_ui(self, surface):
        """绘制用户界面"""
        if not self.show_controls:
            return
        
        # 控制面板背景
        panel_rect = pygame.Rect(10, 10, 350, 400)
        pygame.draw.rect(surface, (0, 0, 0, 180), panel_rect, border_radius=10)
        pygame.draw.rect(surface, (100, 100, 150), panel_rect, 2, border_radius=10)
        
        # 标题
        title_font = pygame.font.SysFont('microsoftyahei', 24, bold=True)
        title = title_font.render("🎆 烟花模拟器控制面板", True, WHITE)
        surface.blit(title, (20, 20))
        
        # 统计信息
        small_font = pygame.font.SysFont('microsoftyahei', 16)
        elapsed_time = (pygame.time.get_ticks() - self.start_time) // 1000
        stats_text = [
            f"已发射烟花: {self.fireworks_launched}",
            f"当前活跃: {len(self.fireworks)}",
            f"运行时间: {elapsed_time}秒",
            f"自动生成: {'开启' if self.auto_spawn else '关闭'}"
        ]
        
        for i, text in enumerate(stats_text):
            stat_surface = small_font.render(text, True, (200, 200, 255))
            surface.blit(stat_surface, (20, 60 + i * 25))
        
        # 控制按钮
        buttons_y = 170
        button_height = 30
        button_width = 150
        
        buttons = [
            ("手动发射烟花", (20, buttons_y), self.spawn_random_firework),
            ("切换自动发射", (20, buttons_y + 40), self.toggle_auto_spawn),
            ("清空所有烟花", (20, buttons_y + 80), self.clear_fireworks),
        ]
        
        for text, (x, y), action in buttons:
            button_rect = pygame.Rect(x, y, button_width, button_height)
            pygame.draw.rect(surface, (70, 130, 180), button_rect, border_radius=6)
            pygame.draw.rect(surface, (100, 100, 150), button_rect, 2, border_radius=6)
            
            text_surface = small_font.render(text, True, WHITE)
            text_rect = text_surface.get_rect(center=button_rect.center)
            surface.blit(text_surface, text_rect)
        
        # 烟花类型选择
        type_y = buttons_y + 120
        type_label = small_font.render("烟花类型:", True, WHITE)
        surface.blit(type_label, (20, type_y))
        
        # 类型选择按钮
        type_buttons = [("随机", "random")] + [(t.capitalize(), t) for t in self.firework_types[:3]]
        for i, (text, ftype) in enumerate(type_buttons):
            x = 120 + i * 70
            if i >= 3:
                x = 120 + (i-3) * 70
                y = type_y + 30
            else:
                y = type_y
            
            color = (100, 180, 100) if self.selected_type == ftype else (100, 100, 150)
            button_rect = pygame.Rect(x, y, 60, 25)
            pygame.draw.rect(surface, color, button_rect, border_radius=4)
            pygame.draw.rect(surface, WHITE, button_rect, 1, border_radius=4)
            
            btn_font = pygame.font.SysFont('microsoftyahei', 12)
            btn_text = btn_font.render(text, True, WHITE)
            btn_rect = btn_text.get_rect(center=button_rect.center)
            surface.blit(btn_text, btn_rect)
        
        # 操作说明
        help_y = type_y + 80
        help_text = [
            "操作说明:",
            "• 点击屏幕任意位置发射烟花",
            "• 鼠标滚轮调整烟花大小",
            "• 空格键: 切换控制面板",
            "• R键: 重置场景",
            "• ESC键: 退出程序"
        ]
        
        for i, text in enumerate(help_text):
            help_surface = small_font.render(text, True, (200, 200, 255))
            surface.blit(help_surface, (20, help_y + i * 20))
    
    def draw(self, surface):
        """绘制整个场景"""
        # 绘制背景
        self.draw_background(surface)
        
        # 绘制烟花
        for firework in self.fireworks:
            firework.draw(surface)
        
        # 绘制UI
        self.draw_ui(surface)
    
    def toggle_auto_spawn(self):
        """切换自动发射"""
        self.auto_spawn = not self.auto_spawn
    
    def clear_fireworks(self):
        """清空所有烟花"""
        self.fireworks.clear()
    
    def handle_click(self, pos):
        """处理鼠标点击"""
        x, y = pos
        
        # 检查是否点击了UI按钮
        if self.show_controls and 10 <= x <= 360 and 170 <= y <= 300:
            # 手动发射按钮
            if 20 <= x <= 170 and 170 <= y <= 200:
                self.spawn_random_firework()
            # 切换自动发射
            elif 20 <= x <= 170 and 210 <= y <= 240:
                self.toggle_auto_spawn()
            # 清空烟花
            elif 20 <= x <= 170 and 250 <= y <= 280:
                self.clear_fireworks()
            # 烟花类型选择
            elif 120 <= x <= 350 and 290 <= y <= 340:
                # 简化的类型选择处理
                if 120 <= x <= 180 and 290 <= y <= 315:
                    self.selected_type = "random"
                elif 190 <= x <= 250 and 290 <= y <= 315:
                    self.selected_type = "normal"
                elif 260 <= x <= 320 and 290 <= y <= 315:
                    self.selected_type = "spiral"
                elif 120 <= x <= 180 and 320 <= y <= 345:
                    self.selected_type = "heart"
        else:
            # 在点击位置发射烟花
            firework_type = self.selected_type if self.selected_type != "random" else None
            self.spawn_firework(x, HEIGHT - 50, firework_type, 
                              size=self.size_multiplier)
    
    def handle_wheel(self, delta):
        """处理鼠标滚轮"""
        self.size_multiplier = max(0.3, min(3.0, self.size_multiplier + delta * 0.1))
    
    def reset(self):
        """重置场景"""
        self.fireworks.clear()
        self.fireworks_launched = 0
        self.spawn_timer = 0
        self.size_multiplier = 1.0
        self.selected_type = "random"
        self.stars = create_starry_background()
        self.buildings = create_cityscape()

def main():
    """主函数"""
    print("=" * 60)
    print("🎆 动态烟花模拟器")
    print("=" * 60)
    print("功能说明:")
    print("1. 10种不同类型的烟花效果")
    print("2. 支持手动和自动发射模式")
    print("3. 实时控制烟花大小和类型")
    print("4. 绚丽的粒子效果和轨迹")
    print("5. 动态星空和城市背景")
    print("=" * 60)
    print("操作说明:")
    print("- 点击屏幕任意位置发射烟花")
    print("- 鼠标滚轮调整烟花大小")
    print("- 空格键: 切换控制面板显示")
    print("- R键: 重置场景")
    print("- ESC键: 退出程序")
    print("=" * 60)
    print("烟花类型包括:")
    print("• 普通型 • 螺旋型 • 心形 • 环形 • 喷泉型")
    print("• 噼啪型 • 柳树型 • 牡丹型 • 菊花型 • 十字型")
    print("=" * 60)
    
    simulation = FireworksSimulation()
    running = True
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键
                    simulation.handle_click(event.pos)
                elif event.button == 4:  # 滚轮上
                    simulation.handle_wheel(1)
                elif event.button == 5:  # 滚轮下
                    simulation.handle_wheel(-1)
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    running = False
                elif event.key == pygame.K_SPACE:
                    simulation.show_controls = not simulation.show_controls
                elif event.key == pygame.K_r:
                    simulation.reset()
                elif event.key == pygame.K_a:
                    simulation.toggle_auto_spawn()
                elif event.key == pygame.K_c:
                    simulation.clear_fireworks()
                elif event.key == pygame.K_f:
                    # 快速发射多个烟花
                    for _ in range(5):
                        simulation.spawn_random_firework()
        
        # 更新模拟
        simulation.update()
        
        # 绘制
        screen.fill(BLACK)
        simulation.draw(screen)
        
        # 更新显示
        pygame.display.flip()
        
        # 控制帧率
        clock.tick(FPS)
    
    # 保存设置并退出
    simulation.save_settings()
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()