import pygame
import sys
import time
import math
import random
from datetime import datetime, timedelta
from pygame import gfxdraw

# 初始化pygame
pygame.init()

# 时钟设置
CLOCK_SIZE = 600
HOUR_HAND_LENGTH = 150
MINUTE_HAND_LENGTH = 200
SECOND_HAND_LENGTH = 220
DOT_RADIUS = 8

# 颜色定义
BACKGROUND_COLOR = (20, 20, 40)
CLOCK_FACE_COLOR = (30, 30, 60)
CLOCK_BORDER_COLOR = (100, 100, 200)
HOUR_HAND_COLOR = (255, 255, 255)
MINUTE_HAND_COLOR = (200, 200, 255)
SECOND_HAND_COLOR = (255, 100, 100)
TEXT_COLOR = (255, 255, 255)
DATE_COLOR = (200, 200, 255)
DIGITAL_COLOR = (100, 255, 100)
HOUR_MARK_COLOR = (200, 200, 255)
MINUTE_MARK_COLOR = (150, 150, 200)
NEON_BLUE = (0, 200, 255)
NEON_PINK = (255, 0, 200)
NEON_GREEN = (0, 255, 100)
NEON_PURPLE = (180, 0, 255)

# 粒子颜色
PARTICLE_COLORS = [
    (255, 100, 100),  # 红色
    (100, 255, 100),  # 绿色
    (100, 100, 255),  # 蓝色
    (255, 255, 100),  # 黄色
    (255, 100, 255),  # 紫色
    (100, 255, 255)   # 青色
]

# 创建窗口
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("高级数字时钟")
clock = pygame.time.Clock()
FPS = 60

# 创建字体
font_small = pygame.font.Font(None, 24)
font_medium = pygame.font.Font(None, 36)
font_large = pygame.font.Font(None, 48)
font_huge = pygame.font.Font(None, 72)

# 星期几的中文名称
WEEKDAYS = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
WEEKDAYS_EN = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

# 粒子系统
class Particle:
    def __init__(self, x, y, color=None):
        self.x = x
        self.y = y
        self.color = color or random.choice(PARTICLE_COLORS)
        self.size = random.uniform(1.0, 3.0)
        self.vx = random.uniform(-1.0, 1.0)
        self.vy = random.uniform(-1.0, 1.0)
        self.life = random.randint(30, 90)
        self.max_life = self.life
        self.glow = random.uniform(0.5, 1.0)
        
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.05  # 重力
        self.life -= 1
        self.size = max(0, self.size - 0.02)
        self.vx *= 0.98
        self.vy *= 0.98
        
    def draw(self, surface):
        if self.life > 0:
            alpha = int(255 * (self.life / self.max_life))
            
            # 绘制发光效果
            for i in range(3, 0, -1):
                glow_size = self.size + i
                glow_alpha = alpha // (i + 1)
                pygame.draw.circle(surface, (*self.color[:3], glow_alpha), 
                                 (int(self.x), int(self.y)), int(glow_size))
            
            # 绘制粒子
            pygame.draw.circle(surface, (*self.color[:3], alpha), 
                             (int(self.x), int(self.y)), int(self.size))
            
    def is_alive(self):
        return self.life > 0

# 数字特效
class DigitalEffect:
    def __init__(self, x, y, number):
        self.x = x
        self.y = y
        self.number = number
        self.particles = []
        self.create_particles()
        
    def create_particles(self):
        # 为每个数字创建粒子效果
        for _ in range(20):
            angle = random.uniform(0, math.pi * 2)
            distance = random.uniform(0, 30)
            px = self.x + math.cos(angle) * distance
            py = self.y + math.sin(angle) * distance
            self.particles.append(Particle(px, py))
            
    def update(self):
        for particle in self.particles[:]:
            particle.update()
            if not particle.is_alive():
                self.particles.remove(particle)
                
    def draw(self, surface):
        for particle in self.particles:
            particle.draw(surface)

# 时钟类
class AnalogClock:
    def __init__(self, center_x, center_y, radius=250):
        self.center_x = center_x
        self.center_y = center_y
        self.radius = radius
        self.particles = []
        self.glow_alpha = 0
        self.glow_direction = 1
        
    def update(self):
        # 更新粒子
        for particle in self.particles[:]:
            particle.update()
            if not particle.is_alive():
                self.particles.remove(particle)
                
        # 更新发光效果
        self.glow_alpha += 2 * self.glow_direction
        if self.glow_alpha >= 100 or self.glow_alpha <= 0:
            self.glow_direction *= -1
            
    def create_second_particles(self, second_angle):
        # 每秒创建粒子效果
        angle = math.radians(second_angle - 90)
        end_x = self.center_x + math.cos(angle) * SECOND_HAND_LENGTH
        end_y = self.center_y + math.sin(angle) * SECOND_HAND_LENGTH
        
        for _ in range(5):
            particle_x = end_x + random.uniform(-10, 10)
            particle_y = end_y + random.uniform(-10, 10)
            self.particles.append(Particle(particle_x, particle_y, SECOND_HAND_COLOR))
            
    def draw_clock_face(self, surface):
        # 绘制时钟背景
        pygame.draw.circle(surface, CLOCK_FACE_COLOR, 
                          (self.center_x, self.center_y), self.radius)
        
        # 绘制发光边框
        for i in range(3, 0, -1):
            border_width = 5 + i * 2
            border_alpha = 50 - i * 10
            border_color = (*NEON_BLUE[:3], border_alpha)
            
            # 创建边框表面
            border_surface = pygame.Surface((self.radius*2 + border_width*2, 
                                           self.radius*2 + border_width*2), 
                                           pygame.SRCALPHA)
            pygame.draw.circle(border_surface, border_color, 
                             (self.radius + border_width, self.radius + border_width), 
                             self.radius + border_width, border_width)
            
            surface.blit(border_surface, 
                        (self.center_x - self.radius - border_width, 
                         self.center_y - self.radius - border_width))
        
        # 绘制时钟边框
        pygame.draw.circle(surface, CLOCK_BORDER_COLOR, 
                          (self.center_x, self.center_y), self.radius, 5)
        
        # 绘制中心点
        pygame.draw.circle(surface, SECOND_HAND_COLOR, 
                          (self.center_x, self.center_y), DOT_RADIUS)
        
        # 绘制小时刻度
        for hour in range(1, 13):
            angle = math.radians((hour * 30) - 90)
            start_x = self.center_x + math.cos(angle) * (self.radius - 20)
            start_y = self.center_y + math.sin(angle) * (self.radius - 20)
            end_x = self.center_x + math.cos(angle) * (self.radius - 40)
            end_y = self.center_y + math.sin(angle) * (self.radius - 40)
            
            # 小时刻度
            pygame.draw.line(surface, HOUR_MARK_COLOR, 
                           (start_x, start_y), (end_x, end_y), 6)
            
            # 小时数字
            hour_angle = math.radians((hour * 30) - 90)
            text_x = self.center_x + math.cos(hour_angle) * (self.radius - 70)
            text_y = self.center_y + math.sin(hour_angle) * (self.radius - 70)
            
            hour_text = font_large.render(str(hour), True, HOUR_MARK_COLOR)
            text_rect = hour_text.get_rect(center=(text_x, text_y))
            surface.blit(hour_text, text_rect)
            
        # 绘制分钟刻度
        for minute in range(0, 60):
            if minute % 5 != 0:  # 跳过小时位置
                angle = math.radians((minute * 6) - 90)
                start_x = self.center_x + math.cos(angle) * (self.radius - 15)
                start_y = self.center_y + math.sin(angle) * (self.radius - 15)
                end_x = self.center_x + math.cos(angle) * (self.radius - 25)
                end_y = self.center_y + math.sin(angle) * (self.radius - 25)
                
                pygame.draw.line(surface, MINUTE_MARK_COLOR, 
                               (start_x, start_y), (end_x, end_y), 2)
                
    def draw_hands(self, surface, hours, minutes, seconds):
        # 计算角度
        hour_angle = math.radians(((hours % 12) + minutes / 60) * 30 - 90)
        minute_angle = math.radians((minutes + seconds / 60) * 6 - 90)
        second_angle = math.radians(seconds * 6 - 90)
        
        # 绘制时针
        hour_x = self.center_x + math.cos(hour_angle) * HOUR_HAND_LENGTH
        hour_y = self.center_y + math.sin(hour_angle) * HOUR_HAND_LENGTH
        pygame.draw.line(surface, HOUR_HAND_COLOR, 
                        (self.center_x, self.center_y), (hour_x, hour_y), 8)
        
        # 绘制分针
        minute_x = self.center_x + math.cos(minute_angle) * MINUTE_HAND_LENGTH
        minute_y = self.center_y + math.sin(minute_angle) * MINUTE_HAND_LENGTH
        pygame.draw.line(surface, MINUTE_HAND_COLOR, 
                        (self.center_x, self.center_y), (minute_x, minute_y), 5)
        
        # 绘制秒针
        second_x = self.center_x + math.cos(second_angle) * SECOND_HAND_LENGTH
        second_y = self.center_y + math.sin(second_angle) * SECOND_HAND_LENGTH
        
        # 秒针发光效果
        for i in range(3, 0, -1):
            glow_width = 2 + i
            glow_alpha = 100 - i * 30
            pygame.draw.line(surface, (*SECOND_HAND_COLOR[:3], glow_alpha), 
                           (self.center_x, self.center_y), (second_x, second_y), 
                           glow_width)
        
        # 秒针尾端圆点
        pygame.draw.circle(surface, SECOND_HAND_COLOR, (second_x, second_y), 5)
        
        # 创建秒针粒子效果
        if seconds % 1 == 0:  # 每秒触发
            self.create_second_particles(seconds * 6)
            
    def draw_particles(self, surface):
        for particle in self.particles:
            particle.draw(surface)
            
    def draw(self, surface, hours, minutes, seconds):
        self.draw_clock_face(surface)
        self.draw_hands(surface, hours, minutes, seconds)
        self.draw_particles(surface)

# 数字时钟类
class DigitalClock:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.effects = []
        self.last_seconds = -1
        
    def update(self, hours, minutes, seconds):
        # 每秒更新数字特效
        if seconds != self.last_seconds:
            self.last_seconds = seconds
            self.effects.append(DigitalEffect(self.x + 100, self.y + 50, seconds))
            
        # 更新所有特效
        for effect in self.effects[:]:
            effect.update()
            if len(effect.particles) == 0:
                self.effects.remove(effect)
                
    def draw(self, surface, hours, minutes, seconds, milliseconds):
        # 绘制数字时钟背景
        digital_bg = pygame.Surface((300, 120), pygame.SRCALPHA)
        pygame.draw.rect(digital_bg, (*CLOCK_FACE_COLOR[:3], 200), 
                        (0, 0, 300, 120), border_radius=20)
        pygame.draw.rect(digital_bg, (*CLOCK_BORDER_COLOR[:3], 150), 
                        (0, 0, 300, 120), 3, border_radius=20)
        
        surface.blit(digital_bg, (self.x, self.y))
        
        # 格式化时间
        time_str = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
        time_text = font_huge.render(time_str, True, DIGITAL_COLOR)
        
        # 绘制时间
        surface.blit(time_text, (self.x + 150 - time_text.get_width()//2, 
                               self.y + 30))
        
        # 绘制毫秒
        ms_str = f".{milliseconds:03d}"
        ms_text = font_medium.render(ms_str, True, DIGITAL_COLOR)
        surface.blit(ms_text, (self.x + 150 + time_text.get_width()//2, 
                             self.y + 40))
        
        # 绘制数字特效
        for effect in self.effects:
            effect.draw(surface)

# 日期显示类
class DateDisplay:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def draw(self, surface, year, month, day, weekday):
        # 绘制日期背景
        date_bg = pygame.Surface((300, 100), pygame.SRCALPHA)
        pygame.draw.rect(date_bg, (*CLOCK_FACE_COLOR[:3], 200), 
                        (0, 0, 300, 100), border_radius=15)
        pygame.draw.rect(date_bg, (*CLOCK_BORDER_COLOR[:3], 150), 
                        (0, 0, 300, 100), 2, border_radius=15)
        
        surface.blit(date_bg, (self.x, self.y))
        
        # 格式化日期
        date_str = f"{year}年{month:02d}月{day:02d}日"
        date_text = font_large.render(date_str, True, DATE_COLOR)
        
        # 绘制日期
        surface.blit(date_text, (self.x + 150 - date_text.get_width()//2, 
                               self.y + 20))
        
        # 绘制星期
        weekday_str = WEEKDAYS[weekday]
        weekday_text = font_medium.render(weekday_str, True, DATE_COLOR)
        surface.blit(weekday_text, (self.x + 150 - weekday_text.get_width()//2, 
                                  self.y + 60))

# 信息面板类
class InfoPanel:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
    def draw(self, surface, seconds_since_midnight, timezone_offset=8):
        # 绘制信息面板背景
        info_bg = pygame.Surface((300, 180), pygame.SRCALPHA)
        pygame.draw.rect(info_bg, (*CLOCK_FACE_COLOR[:3], 200), 
                        (0, 0, 300, 180), border_radius=15)
        pygame.draw.rect(info_bg, (*CLOCK_BORDER_COLOR[:3], 150), 
                        (0, 0, 300, 180), 2, border_radius=15)
        
        surface.blit(info_bg, (self.x, self.y))
        
        # 计算各种时间
        total_seconds = int(seconds_since_midnight)
        hours_passed = total_seconds // 3600
        minutes_passed = (total_seconds % 3600) // 60
        seconds_remaining = 86400 - total_seconds
        
        # 绘制信息
        infos = [
            f"今日已过: {hours_passed:02d}:{minutes_passed:02d}",
            f"剩余时间: {seconds_remaining//3600:02d}:{(seconds_remaining%3600)//60:02d}",
            f"时区: UTC+{timezone_offset}",
            f"帧率: {int(clock.get_fps())} FPS"
        ]
        
        for i, info in enumerate(infos):
            info_text = font_medium.render(info, True, TEXT_COLOR)
            surface.blit(info_text, (self.x + 20, self.y + 20 + i * 35))

# 主游戏类
class ClockApp:
    def __init__(self):
        self.analog_clock = AnalogClock(400, 300, 220)
        self.digital_clock = DigitalClock(50, 450)
        self.date_display = DateDisplay(450, 450)
        self.info_panel = InfoPanel(50, 50)
        self.running = True
        self.timezone_offset = 8  # 东八区
        
    def update(self):
        # 获取当前时间
        now = datetime.now()
        hours = now.hour
        minutes = now.minute
        seconds = now.second
        milliseconds = now.microsecond // 1000
        
        # 计算从午夜开始的秒数
        seconds_since_midnight = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000
        
        # 更新时间
        self.analog_clock.update()
        self.digital_clock.update(hours, minutes, seconds)
        
        return now, seconds_since_midnight
        
    def draw(self, surface, now, seconds_since_midnight):
        # 清空屏幕
        surface.fill(BACKGROUND_COLOR)
        
        # 绘制背景网格
        self.draw_background_grid(surface)
        
        # 获取时间组件
        hours = now.hour
        minutes = now.minute
        seconds = now.second
        milliseconds = now.microsecond // 1000
        year = now.year
        month = now.month
        day = now.day
        weekday = now.weekday()  # 0=周一, 6=周日
        
        # 绘制所有组件
        self.analog_clock.draw(surface, hours, minutes, seconds)
        self.digital_clock.draw(surface, hours, minutes, seconds, milliseconds)
        self.date_display.draw(surface, year, month, day, weekday)
        self.info_panel.draw(surface, seconds_since_midnight, self.timezone_offset)
        
        # 绘制标题
        title = font_huge.render("高级数字时钟", True, NEON_BLUE)
        surface.blit(title, (400 - title.get_width()//2, 20))
        
    def draw_background_grid(self, surface):
        """绘制背景网格"""
        grid_size = 40
        grid_alpha = 30
        
        # 绘制垂直线
        for x in range(0, 800, grid_size):
            pygame.draw.line(surface, (100, 100, 200, grid_alpha), 
                           (x, 0), (x, 600), 1)
        
        # 绘制水平线
        for y in range(0, 600, grid_size):
            pygame.draw.line(surface, (100, 100, 200, grid_alpha), 
                           (0, y), (800, y), 1)
        
        # 绘制中心十字
        pygame.draw.line(surface, (150, 150, 255, 50), 
                       (400, 0), (400, 600), 2)
        pygame.draw.line(surface, (150, 150, 255, 50), 
                       (0, 300), (800, 300), 2)
        
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.running = False
                elif event.key == pygame.K_f:
                    # 切换全屏
                    pygame.display.toggle_fullscreen()
                elif event.key == pygame.K_t:
                    # 切换时区显示
                    self.timezone_offset = (self.timezone_offset + 1) % 25 - 12
                    
    def run(self):
        while self.running:
            self.handle_events()
            now, seconds_since_midnight = self.update()
            self.draw(screen, now, seconds_since_midnight)
            pygame.display.flip()
            clock.tick(FPS)
            
        pygame.quit()
        sys.exit()

# 主程序
if __name__ == "__main__":
    app = ClockApp()
    app.run()