import pygame
import sys
import math

# 初始化 Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("多功能定时器")
clock = pygame.time.Clock()

# 颜色定义
BACKGROUND = (30, 30, 40)
PANEL_BG = (50, 50, 65)
PANEL_BORDER = (80, 80, 100)
TEXT_COLOR = (220, 220, 240)
PRIMARY = (0, 150, 255)
SECONDARY = (100, 200, 255)
SUCCESS = (0, 200, 100)
WARNING = (255, 180, 0)
DANGER = (255, 80, 80)
DISABLED = (100, 100, 120)
PROGRESS_BG = (60, 60, 80)
PROGRESS_FG = (0, 200, 150)

# 字体
try:
    font_large = pygame.font.SysFont('microsoftyahei', 64, bold=True)
    font_medium = pygame.font.SysFont('microsoftyahei', 36)
    font_small = pygame.font.SysFont('microsoftyahei', 24)
    font_tiny = pygame.font.SysFont('microsoftyahei', 18)
except:
    font_large = pygame.font.SysFont(None, 64, bold=True)
    font_medium = pygame.font.SysFont(None, 36)
    font_small = pygame.font.SysFont(None, 24)
    font_tiny = pygame.font.SysFont(None, 18)

class Timer:
    def __init__(self, total_minutes=1, total_seconds=0):
        self.total_seconds = total_minutes * 60 + total_seconds
        self.time_left = self.total_seconds
        self.is_running = False
        self.is_paused = False
        self.is_finished = False
        self.start_time = 0
        self.pause_time = 0
        self.elapsed_paused = 0
        self.laps = []
        self.lap_count = 0
        
    def start(self):
        if not self.is_running and not self.is_finished:
            self.is_running = True
            self.is_paused = False
            self.start_time = pygame.time.get_ticks()
            self.elapsed_paused = 0
            
    def pause(self):
        if self.is_running and not self.is_paused:
            self.is_paused = True
            self.pause_time = pygame.time.get_ticks()
            
    def resume(self):
        if self.is_running and self.is_paused:
            self.is_paused = False
            self.elapsed_paused += pygame.time.get_ticks() - self.pause_time
            
    def stop(self):
        self.is_running = False
        self.is_paused = False
        
    def reset(self, minutes=None, seconds=None):
        self.stop()
        self.is_finished = False
        if minutes is not None and seconds is not None:
            self.total_seconds = minutes * 60 + seconds
        self.time_left = self.total_seconds
        self.start_time = 0
        self.pause_time = 0
        self.elapsed_paused = 0
        self.laps = []
        self.lap_count = 0
        
    def lap(self):
        if self.is_running and not self.is_paused:
            lap_time = self.get_formatted_time()
            self.lap_count += 1
            self.laps.append({
                'number': self.lap_count,
                'time': lap_time,
                'timestamp': pygame.time.get_ticks()
            })
            return lap_time
        return None
        
    def update(self):
        if not self.is_running or self.is_paused or self.is_finished:
            return
            
        current_time = pygame.time.get_ticks()
        elapsed = (current_time - self.start_time - self.elapsed_paused) / 1000.0
        
        self.time_left = max(0, self.total_seconds - elapsed)
        
        if self.time_left <= 0:
            self.time_left = 0
            self.is_running = False
            self.is_finished = True
    
    def get_formatted_time(self):
        total_seconds = int(self.time_left)
        minutes = total_seconds // 60
        seconds = total_seconds % 60
        milliseconds = int((self.time_left - total_seconds) * 1000)
        return f"{minutes:02d}:{seconds:02d}.{milliseconds:03d}"
    
    def get_progress(self):
        if self.total_seconds == 0:
            return 0
        return 1.0 - (self.time_left / self.total_seconds)
    
    def get_time_components(self):
        total_seconds = int(self.time_left)
        minutes = total_seconds // 60
        seconds = total_seconds % 60
        milliseconds = int((self.time_left - total_seconds) * 1000)
        return minutes, seconds, milliseconds
    
    def get_status(self):
        if self.is_finished:
            return "完成", DANGER
        elif self.is_paused:
            return "暂停", WARNING
        elif self.is_running:
            return "运行中", SUCCESS
        else:
            return "已停止", DISABLED

class Button:
    def __init__(self, x, y, width, height, text, color=PRIMARY, hover_color=SECONDARY):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.hover_color = hover_color
        self.current_color = color
        self.is_hovered = False
        self.clicked = False
        
    def draw(self, screen):
        color = self.hover_color if self.is_hovered else self.color
        pygame.draw.rect(screen, color, self.rect, border_radius=8)
        pygame.draw.rect(screen, PANEL_BORDER, self.rect, 2, border_radius=8)
        
        text_surf = font_small.render(self.text, True, TEXT_COLOR)
        text_rect = text_surf.get_rect(center=self.rect.center)
        screen.blit(text_surf, text_rect)
        
    def update(self, mouse_pos, mouse_clicked):
        self.is_hovered = self.rect.collidepoint(mouse_pos)
        self.clicked = False
        
        if self.is_hovered and mouse_clicked:
            self.clicked = True
            
        return self.clicked

class NumberInput:
    def __init__(self, x, y, width, height, label, min_val=0, max_val=99, default=0):
        self.rect = pygame.Rect(x, y, width, height)
        self.label = label
        self.min_val = min_val
        self.max_val = max_val
        self.value = default
        self.is_active = False
        
    def draw(self, screen):
        # 绘制标签
        label_surf = font_tiny.render(self.label, True, TEXT_COLOR)
        screen.blit(label_surf, (self.rect.x, self.rect.y - 25))
        
        # 绘制输入框
        color = SECONDARY if self.is_active else PANEL_BORDER
        pygame.draw.rect(screen, PANEL_BG, self.rect, border_radius=6)
        pygame.draw.rect(screen, color, self.rect, 2, border_radius=6)
        
        # 绘制值
        value_surf = font_medium.render(f"{self.value:02d}", True, TEXT_COLOR)
        value_rect = value_surf.get_rect(center=self.rect.center)
        screen.blit(value_surf, value_rect)
        
        # 绘制增减按钮
        inc_rect = pygame.Rect(self.rect.right + 5, self.rect.y, 30, 20)
        dec_rect = pygame.Rect(self.rect.right + 5, self.rect.bottom - 20, 30, 20)
        
        # 增加按钮
        inc_color = PRIMARY if inc_rect.collidepoint(pygame.mouse.get_pos()) else PANEL_BORDER
        pygame.draw.rect(screen, inc_color, inc_rect, border_radius=4)
        inc_text = font_tiny.render("+", True, TEXT_COLOR)
        screen.blit(inc_text, (inc_rect.centerx - 5, inc_rect.centery - 8))
        
        # 减少按钮
        dec_color = PRIMARY if dec_rect.collidepoint(pygame.mouse.get_pos()) else PANEL_BORDER
        pygame.draw.rect(screen, dec_color, dec_rect, border_radius=4)
        dec_text = font_tiny.render("-", True, TEXT_COLOR)
        screen.blit(dec_text, (dec_rect.centerx - 5, dec_rect.centery - 8))
        
        return inc_rect, dec_rect
        
    def update(self, mouse_pos, mouse_clicked, inc_rect, dec_rect):
        if mouse_clicked:
            if inc_rect.collidepoint(mouse_pos) and self.value < self.max_val:
                self.value += 1
            elif dec_rect.collidepoint(mouse_pos) and self.value > self.min_val:
                self.value -= 1
            elif self.rect.collidepoint(mouse_pos):
                self.is_active = True
            else:
                self.is_active = False
                
        if self.is_active:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP and self.value < self.max_val:
                        self.value += 1
                    elif event.key == pygame.K_DOWN and self.value > self.min_val:
                        self.value -= 1

def draw_progress_circle(screen, center_x, center_y, radius, progress, color):
    """绘制圆形进度条"""
    if progress > 0:
        end_angle = 270 + progress * 360
        pygame.draw.arc(screen, color, 
                       (center_x - radius, center_y - radius, radius * 2, radius * 2),
                       math.radians(270), math.radians(end_angle), 8)
    
    # 绘制中心文本
    progress_text = f"{progress * 100:.1f}%"
    text_surf = font_tiny.render(progress_text, True, TEXT_COLOR)
    text_rect = text_surf.get_rect(center=(center_x, center_y))
    screen.blit(text_surf, text_rect)

def draw_analog_clock(screen, center_x, center_y, radius, minutes, seconds, milliseconds):
    """绘制模拟时钟"""
    # 绘制时钟外圈
    pygame.draw.circle(screen, PANEL_BORDER, (center_x, center_y), radius, 2)
    
    # 绘制刻度
    for i in range(60):
        angle = math.radians(i * 6 - 90)
        if i % 5 == 0:
            length = 10
            width = 3
        else:
            length = 5
            width = 1
            
        start_x = center_x + math.cos(angle) * (radius - length)
        start_y = center_y + math.sin(angle) * (radius - length)
        end_x = center_x + math.cos(angle) * radius
        end_y = center_y + math.sin(angle) * radius
        
        pygame.draw.line(screen, PANEL_BORDER, (start_x, start_y), (end_x, end_y), width)
    
    # 绘制秒针
    second_angle = math.radians(seconds * 6 - 90)
    second_x = center_x + math.cos(second_angle) * (radius - 20)
    second_y = center_y + math.sin(second_angle) * (radius - 20)
    pygame.draw.line(screen, DANGER, (center_x, center_y), (second_x, second_y), 2)
    
    # 绘制分针
    minute_angle = math.radians(minutes * 6 - 90 + seconds * 0.1)
    minute_x = center_x + math.cos(minute_angle) * (radius - 40)
    minute_y = center_y + math.sin(minute_angle) * (radius - 40)
    pygame.draw.line(screen, SECONDARY, (center_x, center_y), (minute_x, minute_y), 4)
    
    # 绘制中心点
    pygame.draw.circle(screen, PRIMARY, (center_x, center_y), 6)

def main():
    # 创建定时器
    timer = Timer(1, 0)  # 1分钟
    
    # 创建按钮
    buttons = {
        'start': Button(50, 500, 100, 50, "开始"),
        'pause': Button(170, 500, 100, 50, "暂停"),
        'reset': Button(290, 500, 100, 50, "重置"),
        'lap': Button(410, 500, 100, 50, "计次"),
        'set_5': Button(530, 500, 100, 50, "5分钟"),
        'set_10': Button(650, 500, 100, 50, "10分钟"),
    }
    
    # 创建数字输入
    minute_input = NumberInput(50, 450, 80, 50, "分钟", 0, 99, 1)
    second_input = NumberInput(150, 450, 80, 50, "秒数", 0, 59, 0)
    
    # 主循环
    running = True
    mouse_clicked = False
    
    while running:
        mouse_pos = pygame.mouse.get_pos()
        mouse_clicked = False
        
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    mouse_clicked = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if timer.is_running and not timer.is_paused:
                        timer.pause()
                    elif timer.is_running and timer.is_paused:
                        timer.resume()
                    else:
                        timer.start()
                elif event.key == pygame.K_r:
                    timer.reset()
                elif event.key == pygame.K_l:
                    timer.lap()
                elif event.key == pygame.K_ESCAPE:
                    running = False
        
        # 更新数字输入
        inc_min, dec_min = minute_input.draw(screen)
        inc_sec, dec_sec = second_input.draw(screen)
        minute_input.update(mouse_pos, mouse_clicked, inc_min, dec_min)
        second_input.update(mouse_pos, mouse_clicked, inc_sec, dec_sec)
        
        # 更新按钮状态
        for btn_name, btn in buttons.items():
            if btn.update(mouse_pos, mouse_clicked):
                if btn_name == 'start':
                    if timer.is_running and timer.is_paused:
                        timer.resume()
                    else:
                        timer.start()
                elif btn_name == 'pause':
                    timer.pause()
                elif btn_name == 'reset':
                    timer.reset(minute_input.value, second_input.value)
                elif btn_name == 'lap':
                    lap_time = timer.lap()
                elif btn_name == 'set_5':
                    timer.reset(5, 0)
                    minute_input.value = 5
                    second_input.value = 0
                elif btn_name == 'set_10':
                    timer.reset(10, 0)
                    minute_input.value = 10
                    second_input.value = 0
        
        # 更新定时器
        timer.update()
        
        # 获取时间组件
        minutes, seconds, milliseconds = timer.get_time_components()
        status_text, status_color = timer.get_status()
        
        # 绘制
        screen.fill(BACKGROUND)
        
        # 绘制标题
        title_surf = font_medium.render("多功能定时器", True, PRIMARY)
        screen.blit(title_surf, (WIDTH // 2 - title_surf.get_width() // 2, 20))
        
        # 绘制主时间显示面板
        pygame.draw.rect(screen, PANEL_BG, (50, 100, 700, 150), border_radius=12)
        pygame.draw.rect(screen, PANEL_BORDER, (50, 100, 700, 150), 2, border_radius=12)
        
        # 绘制时间
        time_text = timer.get_formatted_time()
        time_surf = font_large.render(time_text, True, TEXT_COLOR)
        screen.blit(time_surf, (WIDTH // 2 - time_surf.get_width() // 2, 150))
        
        # 绘制状态
        status_surf = font_small.render(status_text, True, status_color)
        screen.blit(status_surf, (WIDTH // 2 - status_surf.get_width() // 2, 220))
        
        # 绘制进度条区域
        pygame.draw.rect(screen, PANEL_BG, (50, 270, 700, 120), border_radius=12)
        pygame.draw.rect(screen, PANEL_BORDER, (50, 270, 700, 120), 2, border_radius=12)
        
        # 绘制进度条
        progress = timer.get_progress()
        bar_width = 660
        bar_height = 20
        bar_x = 70
        bar_y = 300
        
        # 进度条背景
        pygame.draw.rect(screen, PROGRESS_BG, (bar_x, bar_y, bar_width, bar_height), border_radius=10)
        
        # 进度条前景
        if progress > 0:
            progress_width = int(bar_width * progress)
            progress_color = (
                int(255 * (1 - progress)),
                int(255 * progress),
                100
            )
            pygame.draw.rect(screen, PROGRESS_FG, (bar_x, bar_y, progress_width, bar_height), border_radius=10)
        
        # 绘制进度文本
        progress_text = f"进度: {progress * 100:.1f}%"
        progress_surf = font_small.render(progress_text, True, TEXT_COLOR)
        screen.blit(progress_surf, (WIDTH // 2 - progress_surf.get_width() // 2, 330))
        
        # 绘制圆形进度条
        draw_progress_circle(screen, 150, 360, 40, progress, PROGRESS_FG)
        
        # 绘制模拟时钟
        draw_analog_clock(screen, 650, 360, 40, minutes, seconds, milliseconds // 100)
        
        # 绘制计次列表
        if timer.laps:
            pygame.draw.rect(screen, PANEL_BG, (400, 270, 350, 120), border_radius=12)
            pygame.draw.rect(screen, PANEL_BORDER, (400, 270, 350, 120), 2, border_radius=12)
            
            # 显示最近的3个计次
            lap_title = font_tiny.render("计次记录:", True, SECONDARY)
            screen.blit(lap_title, (420, 285))
            
            for i, lap in enumerate(timer.laps[-3:]):  # 只显示最近3个
                lap_text = f"计次{lap['number']}: {lap['time']}"
                lap_surf = font_tiny.render(lap_text, True, TEXT_COLOR)
                screen.blit(lap_surf, (420, 310 + i * 25))
        
        # 绘制控制面板
        pygame.draw.rect(screen, PANEL_BG, (50, 400, 700, 180), border_radius=12)
        pygame.draw.rect(screen, PANEL_BORDER, (50, 400, 700, 180), 2, border_radius=12)
        
        # 绘制数字输入
        inc_min, dec_min = minute_input.draw(screen)
        inc_sec, dec_sec = second_input.draw(screen)
        
        # 绘制按钮
        for btn in buttons.values():
            btn.draw(screen)
        
        # 绘制快捷键提示
        shortcuts = [
            "空格键: 开始/暂停",
            "R键: 重置",
            "L键: 计次",
            "ESC键: 退出"
        ]
        
        for i, shortcut in enumerate(shortcuts):
            shortcut_surf = font_tiny.render(shortcut, True, DISABLED)
            screen.blit(shortcut_surf, (WIDTH - 200, 20 + i * 25))
        
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()