import pygame
import sys
import math
import json
import os
from datetime import datetime

# 初始化Pygame
pygame.init()
pygame.mixer.init(frequency=44100, size=-16, channels=1, buffer=512)

# 屏幕设置
WINDOW_WIDTH = 1200
WINDOW_HEIGHT = 520
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("🎹 电子钢琴 - 全键位")

# 颜色
COLORS = {
    'background': (30, 35, 50),
    'panel_bg': (45, 50, 75),
    'panel_border': (70, 80, 120),
    'text_light': (230, 235, 245),
    'text_gold': (255, 215, 0),
    'white_key': (255, 255, 255),
    'white_key_pressed': (200, 220, 255),
    'white_key_border': (180, 180, 180),
    'black_key': (40, 40, 50),
    'black_key_pressed': (100, 100, 130),
    'button_bg': (60, 100, 180),
    'button_hover': (80, 130, 210),
    'button_pressed': (40, 70, 140),
    'button_green': (60, 180, 80),
    'button_green_hover': (80, 210, 100),
    'button_red': (200, 60, 60),
    'button_red_hover': (230, 80, 80),
    'button_orange': (200, 140, 40),
    'button_orange_hover': (230, 170, 60),
}

# ========== 中文字体 ==========
def get_chinese_font(size):
    font_paths = [
        "C:/Windows/Fonts/simsun.ttc",
        "C:/Windows/Fonts/simhei.ttf",
        "C:/Windows/Fonts/msyh.ttc",
        "/System/Library/Fonts/PingFang.ttc",
        "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
    ]
    for path in font_paths:
        try:
            if os.path.exists(path):
                return pygame.font.Font(path, size)
        except:
            continue
    return pygame.font.Font(None, size)

FONT_TITLE = get_chinese_font(32)
FONT_LARGE = get_chinese_font(26)
FONT_MEDIUM = get_chinese_font(20)
FONT_SMALL = get_chinese_font(16)
FONT_TINY = get_chinese_font(12)

# ========== 音符频率 ==========
NOTE_FREQUENCIES = {
    'C': 261.63, 'D': 293.66, 'E': 329.63, 'F': 349.23, 
    'G': 392.00, 'A': 440.00, 'B': 493.88,
    'C#': 277.18, 'D#': 311.13, 'F#': 369.99, 'G#': 415.30, 'A#': 466.16,
}

# 完整键盘布局 (一个八度)
KEY_LAYOUT = [
    ('C', True), ('C#', False), ('D', True), ('D#', False), ('E', True),
    ('F', True), ('F#', False), ('G', True), ('G#', False), ('A', True),
    ('A#', False), ('B', True)
]

# 键盘映射 - 覆盖所有白键和黑键
KEY_MAP = {
    # 白键 (从左到右)
    pygame.K_a: ('C', 3),   # A -> C3
    pygame.K_s: ('D', 3),   # S -> D3
    pygame.K_d: ('E', 3),   # D -> E3
    pygame.K_f: ('F', 3),   # F -> F3
    pygame.K_g: ('G', 3),   # G -> G3
    pygame.K_h: ('A', 3),   # H -> A3
    pygame.K_j: ('B', 3),   # J -> B3
    pygame.K_k: ('C', 4),   # K -> C4
    pygame.K_l: ('D', 4),   # L -> D4
    pygame.K_SEMICOLON: ('E', 4),  # ; -> E4
    pygame.K_QUOTE: ('F', 4),      # ' -> F4
    # 黑键 (上行)
    pygame.K_w: ('C#', 3),  # W -> C#3
    pygame.K_e: ('D#', 3),  # E -> D#3
    pygame.K_t: ('F#', 3),  # T -> F#3
    pygame.K_y: ('G#', 3),  # Y -> G#3
    pygame.K_u: ('A#', 3),  # U -> A#3
    pygame.K_o: ('C#', 4),  # O -> C#4
    pygame.K_p: ('D#', 4),  # P -> D#4
    pygame.K_LEFTBRACKET: ('F#', 4),  # [ -> F#4
    pygame.K_RIGHTBRACKET: ('G#', 4), # ] -> G#4
    # 额外黑键
    pygame.K_1: ('C#', 3),  # 1 -> C#3
    pygame.K_2: ('D#', 3),  # 2 -> D#3
    pygame.K_3: ('F#', 3),  # 3 -> F#3
    pygame.K_4: ('G#', 3),  # 4 -> G#3
    pygame.K_5: ('A#', 3),  # 5 -> A#3
    pygame.K_6: ('C#', 4),  # 6 -> C#4
    pygame.K_7: ('D#', 4),  # 7 -> D#4
    pygame.K_8: ('F#', 4),  # 8 -> F#4
    pygame.K_9: ('G#', 4),  # 9 -> G#4
    pygame.K_0: ('A#', 4),  # 0 -> A#4
}

# 八度切换
OCTAVE_OFFSET = 0

class Button:
    def __init__(self, x, y, width, height, text, color, text_color=None):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.text_color = text_color if text_color else COLORS['text_light']
        self.hover = False
        self.pressed = False
        self.visible = True
    
    def draw(self, surface):
        if not self.visible:
            return
        color = self.color
        if self.pressed:
            color = COLORS['button_pressed']
        elif self.hover:
            if self.color == COLORS['button_green']:
                color = COLORS['button_green_hover']
            elif self.color == COLORS['button_red']:
                color = COLORS['button_red_hover']
            elif self.color == COLORS['button_orange']:
                color = COLORS['button_orange_hover']
            else:
                color = COLORS['button_hover']
        
        pygame.draw.rect(surface, color, self.rect, border_radius=8)
        pygame.draw.rect(surface, COLORS['panel_border'], self.rect, 2, border_radius=8)
        
        text_surf = FONT_MEDIUM.render(self.text, True, self.text_color)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)
    
    def handle_event(self, event):
        if not self.visible:
            return False
        if event.type == pygame.MOUSEMOTION:
            self.hover = self.rect.collidepoint(event.pos)
            if not self.hover:
                self.pressed = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1 and self.rect.collidepoint(event.pos):
                self.pressed = True
                return True
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1 and self.pressed:
                self.pressed = False
                if self.rect.collidepoint(event.pos):
                    return True
        return False

class PianoKey:
    """钢琴键"""
    def __init__(self, note, is_white, x, y, width, height, octave=4):
        self.note = note
        self.is_white = is_white
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.octave = octave
        self.pressed = False
        self.frequency = NOTE_FREQUENCIES[note] * (2 ** (octave - 4))
        self.key_label = ""  # 键盘快捷键标签
    
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)
    
    def set_key_label(self, label):
        self.key_label = label
    
    def draw(self, surface):
        if self.is_white:
            color = COLORS['white_key_pressed'] if self.pressed else COLORS['white_key']
            pygame.draw.rect(surface, color, self.get_rect())
            pygame.draw.rect(surface, COLORS['white_key_border'], self.get_rect(), 1)
            if self.width > 30:
                # 音符名
                label = FONT_TINY.render(self.note, True, (100, 100, 120))
                surface.blit(label, (self.x + 6, self.y + self.height - 25))
                # 八度
                oct_label = FONT_TINY.render(str(self.octave), True, (150, 150, 170))
                surface.blit(oct_label, (self.x + self.width - 18, self.y + self.height - 25))
                # 键盘快捷键
                if self.key_label:
                    key_label = FONT_TINY.render(self.key_label, True, (80, 80, 180))
                    surface.blit(key_label, (self.x + self.width//2 - 6, self.y + 5))
        else:
            color = COLORS['black_key_pressed'] if self.pressed else COLORS['black_key']
            pygame.draw.rect(surface, color, self.get_rect())
            pygame.draw.rect(surface, (60, 60, 70), self.get_rect(), 1)
            if self.width > 20:
                label = FONT_TINY.render(self.note, True, (180, 180, 200))
                surface.blit(label, (self.x + 3, self.y + self.height - 18))
                if self.key_label:
                    key_label = FONT_TINY.render(self.key_label, True, (150, 150, 100))
                    surface.blit(key_label, (self.x + self.width//2 - 5, self.y + 3))

class SoundGenerator:
    """声音生成器"""
    def __init__(self):
        self.sample_rate = 44100
        self.playing_notes = {}
        self.volume = 0.5
        self.waveform = 'sine'
        self.channels = 1
    
    def generate_tone(self, frequency, duration=0.5):
        """生成音调"""
        if frequency <= 0:
            return None
        
        samples = int(self.sample_rate * duration)
        sound_bytes = bytearray(samples * 2)
        
        for i in range(samples):
            t = i / self.sample_rate
            
            if self.waveform == 'sine':
                value = math.sin(2 * math.pi * frequency * t)
            elif self.waveform == 'square':
                value = 1 if math.sin(2 * math.pi * frequency * t) > 0 else -1
            elif self.waveform == 'sawtooth':
                value = 2 * (t * frequency % 1) - 1
            elif self.waveform == 'triangle':
                value = 2 * abs(2 * (t * frequency % 1) - 1) - 1
            else:
                value = math.sin(2 * math.pi * frequency * t)
            
            # 包络
            attack = 0.01
            decay = 0.05
            sustain_level = 0.7
            release = 0.1
            
            if t < attack:
                env = t / attack
            elif t < attack + decay:
                env = 1 - (1 - sustain_level) * (t - attack) / decay
            elif t < duration - release:
                env = sustain_level
            else:
                env = sustain_level * (1 - (t - (duration - release)) / release)
            
            value *= env * self.volume
            value = max(-1, min(1, value))
            
            int_val = int(value * 32767)
            sound_bytes[i * 2] = int_val & 0xFF
            sound_bytes[i * 2 + 1] = (int_val >> 8) & 0xFF
        
        return pygame.mixer.Sound(buffer=bytes(sound_bytes))
    
    def play_note(self, note, octave=4, duration=0.5):
        """播放音符"""
        frequency = NOTE_FREQUENCIES[note] * (2 ** (octave - 4))
        key = f"{note}{octave}"
        
        if key in self.playing_notes:
            self.playing_notes[key].stop()
        
        sound = self.generate_tone(frequency, duration)
        if sound:
            sound.play()
            self.playing_notes[key] = sound
    
    def stop_note(self, note, octave=4):
        """停止音符"""
        key = f"{note}{octave}"
        if key in self.playing_notes:
            self.playing_notes[key].fadeout(100)
            del self.playing_notes[key]
    
    def stop_all(self):
        """停止所有音符"""
        for key in list(self.playing_notes.keys()):
            self.playing_notes[key].fadeout(100)
        self.playing_notes.clear()

class ElectronicPiano:
    """电子钢琴主类"""
    def __init__(self):
        self.sound = SoundGenerator()
        
        self.waveform = 'sine'
        self.volume = 0.5
        self.current_octave = 4
        self.octave_offset = 0  # -2 到 2
        
        self.is_recording = False
        self.recording = []
        self.recording_start = 0
        self.is_playing = False
        self.playback_index = 0
        self.playback_timer = 0
        
        self.pressed_keys = set()
        self.keys = []
        self.init_keys()
        
        self.messages = []
        
        # ========== 按钮 ==========
        self.record_button = Button(20, 435, 120, 40, "🔴 录音", COLORS['button_red'])
        self.stop_record_button = Button(150, 435, 120, 40, "⏹️ 停止", COLORS['button_red'])
        self.stop_record_button.visible = False
        self.play_button = Button(280, 435, 120, 40, "▶️ 播放", COLORS['button_green'])
        self.clear_button = Button(410, 435, 120, 40, "🗑️ 清空", COLORS['button_red'])
        
        self.waveform_buttons = {}
        waveforms = [
            ('sine', '🎵 正弦', COLORS['button_bg']),
            ('square', '🎶 方波', COLORS['button_bg']),
            ('sawtooth', '🎵 锯齿', COLORS['button_bg']),
            ('triangle', '🎵 三角', COLORS['button_bg']),
        ]
        x = 540
        for wf, label, color in waveforms:
            self.waveform_buttons[wf] = Button(x, 435, 100, 40, label, color)
            x += 110
        
        # 八度控制
        self.octave_down = Button(20, 390, 80, 35, "⬇️ 降", COLORS['button_bg'])
        self.octave_up = Button(110, 390, 80, 35, "⬆️ 升", COLORS['button_bg'])
        self.vol_down = Button(200, 390, 60, 35, "🔉", COLORS['button_bg'])
        self.vol_up = Button(270, 390, 60, 35, "🔊", COLORS['button_bg'])
        
        # 建立键盘映射
        self.build_key_mapping()
    
    def init_keys(self):
        """初始化钢琴键 - 4个八度"""
        self.keys = []
        key_width = 48
        key_height = 280
        start_x = 30
        y = 80
        
        # 4个八度 C3 到 C6
        for octave in range(3, 7):
            white_count = 0
            for note, is_white in KEY_LAYOUT:
                if is_white:
                    x = start_x + white_count * key_width
                    white_count += 1
                else:
                    x = start_x + (white_count - 1) * key_width + key_width * 0.75
                
                key = PianoKey(note, is_white, x, y,
                              key_width if is_white else key_width * 0.5,
                              key_height if is_white else key_height * 0.6,
                              octave)
                self.keys.append(key)
            
            start_x += key_width * 7 + 15
    
    def build_key_mapping(self):
        """建立键位映射，为每个键分配键盘快捷键"""
        # 为白键分配快捷键
        white_keys = [k for k in self.keys if k.is_white]
        white_labels = ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', "'"]
        
        for i, key in enumerate(white_keys):
            if i < len(white_labels):
                key.set_key_label(white_labels[i])
        
        # 为黑键分配快捷键
        black_keys = [k for k in self.keys if not k.is_white]
        black_labels = ['W', 'E', 'T', 'Y', 'U', 'O', 'P', '[', ']', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
        
        for i, key in enumerate(black_keys):
            if i < len(black_labels):
                key.set_key_label(black_labels[i])
    
    def get_key_at_pos(self, pos):
        """获取位置对应的键"""
        # 先检查黑键（在上层）
        for key in self.keys:
            if not key.is_white and key.get_rect().collidepoint(pos):
                return key
        # 再检查白键
        for key in self.keys:
            if key.is_white and key.get_rect().collidepoint(pos):
                return key
        return None
    
    def get_key_by_note(self, note, octave):
        """根据音符和八度获取键"""
        for key in self.keys:
            if key.note == note and key.octave == octave:
                return key
        return None
    
    def play_key(self, key):
        """播放键"""
        if not key:
            return
        
        key.pressed = True
        self.sound.play_note(key.note, key.octave, 0.8)
        
        if self.is_recording:
            current_time = pygame.time.get_ticks() - self.recording_start
            self.recording.append({
                'type': 'note_on',
                'note': key.note,
                'octave': key.octave,
                'time': current_time
            })
    
    def release_key(self, key):
        """释放键"""
        if not key:
            return
        
        key.pressed = False
        self.sound.stop_note(key.note, key.octave)
        
        if self.is_recording:
            current_time = pygame.time.get_ticks() - self.recording_start
            self.recording.append({
                'type': 'note_off',
                'note': key.note,
                'octave': key.octave,
                'time': current_time
            })
    
    def start_recording(self):
        """开始录音"""
        if self.is_playing:
            self.stop_playback()
        
        self.recording = []
        self.is_recording = True
        self.recording_start = pygame.time.get_ticks()
        self.record_button.visible = False
        self.stop_record_button.visible = True
        self.add_message("🔴 开始录音...", COLORS['text_red'])
    
    def stop_recording(self):
        """停止录音"""
        self.is_recording = False
        self.record_button.visible = True
        self.stop_record_button.visible = False
        
        if self.recording:
            self.add_message(f"⏹️ 录音结束，共 {len(self.recording)} 个事件", COLORS['text_light'])
        else:
            self.add_message("⏹️ 录音已取消", COLORS['text_light'])
    
    def play_recording(self):
        """播放录音"""
        if not self.recording:
            self.add_message("⚠️ 没有录音可播放!", COLORS['text_red'])
            return
        
        if self.is_playing:
            self.stop_playback()
            return
        
        self.is_playing = True
        self.playback_index = 0
        self.playback_timer = pygame.time.get_ticks()
        self.add_message("▶️ 播放录音中...", COLORS['text_green'])
    
    def stop_playback(self):
        """停止播放"""
        self.is_playing = False
        self.playback_index = 0
        for key in self.keys:
            if key.pressed:
                self.release_key(key)
        self.add_message("⏹️ 播放停止", COLORS['text_light'])
    
    def update_playback(self):
        """更新播放"""
        if not self.is_playing or self.playback_index >= len(self.recording):
            if self.is_playing:
                self.stop_playback()
                if self.recording:
                    self.add_message("✅ 播放完成!", COLORS['text_green'])
            return
        
        current_time = pygame.time.get_ticks()
        elapsed = current_time - self.playback_timer
        
        while (self.playback_index < len(self.recording) and 
               self.recording[self.playback_index]['time'] <= elapsed):
            event = self.recording[self.playback_index]
            key = self.get_key_by_note(event['note'], event['octave'])
            
            if key:
                if event['type'] == 'note_on':
                    key.pressed = True
                    self.sound.play_note(key.note, key.octave, 0.8)
                elif event['type'] == 'note_off':
                    key.pressed = False
                    self.sound.stop_note(key.note, key.octave)
            
            self.playback_index += 1
    
    def add_message(self, text, color=COLORS['text_light']):
        self.messages.append({'text': text, 'color': color, 'time': 180})
        if len(self.messages) > 8:
            self.messages.pop(0)
    
    def update(self):
        """更新状态"""
        self.update_playback()
        
        for msg in self.messages:
            msg['time'] -= 1
        self.messages = [m for m in self.messages if m['time'] > 0]
    
    def draw(self, surface):
        surface.fill(COLORS['background'])
        
        # 标题
        title = FONT_TITLE.render("🎹 电子钢琴 - 全键位", True, COLORS['text_gold'])
        surface.blit(title, (20, 12))
        
        info_text = FONT_SMALL.render(
            f"音色: {self.waveform} | 八度: {self.current_octave} | 音量: {int(self.volume * 100)}%",
            True, COLORS['text_light']
        )
        surface.blit(info_text, (380, 22))
        
        # 绘制钢琴键
        for key in self.keys:
            key.draw(surface)
        
        # 键盘提示
        self.draw_key_hints(surface)
        
        # 按钮
        self.record_button.draw(surface)
        self.stop_record_button.draw(surface)
        self.play_button.draw(surface)
        self.clear_button.draw(surface)
        
        for wf, button in self.waveform_buttons.items():
            if wf == self.waveform:
                button.color = COLORS['button_green']
            else:
                button.color = COLORS['button_bg']
            button.draw(surface)
        
        self.octave_down.draw(surface)
        self.octave_up.draw(surface)
        self.vol_down.draw(surface)
        self.vol_up.draw(surface)
        
        self.draw_messages(surface)
        
        # 录音指示灯
        if self.is_recording:
            if pygame.time.get_ticks() % 1000 < 500:
                pygame.draw.circle(surface, COLORS['button_red'], (180, 50), 10)
    
    def draw_key_hints(self, surface):
        """绘制键盘快捷键提示"""
        hints = [
            "🎹 键盘映射:",
            "白键: A S D F G H J K L ; ' ",
            "黑键: W E T Y U O P [ ]  |  1-0 也支持黑键",
            "Z/X = 升降八度 | 空格 = 播放/停止"
        ]
        y = 475
        for hint in hints:
            text = FONT_TINY.render(hint, True, (150, 150, 180))
            surface.blit(text, (20, y))
            y += 16
    
    def draw_messages(self, surface):
        """绘制消息"""
        y = 395
        for msg in reversed(self.messages[-4:]):
            alpha = min(255, msg['time'] * 1.5)
            text = FONT_SMALL.render(msg['text'], True, msg['color'])
            text.set_alpha(alpha)
            surface.blit(text, (400, y))
            y -= 22

def main():
    clock = pygame.time.Clock()
    piano = ElectronicPiano()
    running = True
    
    mouse_pressed_keys = set()
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                piano.sound.stop_all()
                running = False
            
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    key = piano.get_key_at_pos(event.pos)
                    if key:
                        piano.play_key(key)
                        mouse_pressed_keys.add(key)
            
            elif event.type == pygame.MOUSEMOTION:
                if event.buttons[0]:
                    key = piano.get_key_at_pos(event.pos)
                    if key and key not in mouse_pressed_keys:
                        piano.play_key(key)
                        mouse_pressed_keys.add(key)
                    for k in list(mouse_pressed_keys):
                        if k != key:
                            piano.release_key(k)
                            mouse_pressed_keys.remove(k)
            
            elif event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    for key in list(mouse_pressed_keys):
                        piano.release_key(key)
                    mouse_pressed_keys.clear()
            
            elif event.type == pygame.KEYDOWN:
                # 处理键盘弹奏
                if event.key in KEY_MAP:
                    note, octave = KEY_MAP[event.key]
                    # 应用八度偏移
                    actual_octave = octave + piano.octave_offset
                    actual_octave = max(2, min(7, actual_octave))
                    key = piano.get_key_by_note(note, actual_octave)
                    if key and key not in piano.pressed_keys:
                        piano.play_key(key)
                        piano.pressed_keys.add(key)
                
                # 八度控制
                elif event.key == pygame.K_z:
                    piano.octave_offset = max(-2, piano.octave_offset - 1)
                    piano.add_message(f"八度偏移: {piano.octave_offset:+d}", COLORS['text_light'])
                elif event.key == pygame.K_x:
                    piano.octave_offset = min(2, piano.octave_offset + 1)
                    piano.add_message(f"八度偏移: {piano.octave_offset:+d}", COLORS['text_light'])
                
                # 空格控制播放
                elif event.key == pygame.K_SPACE:
                    if piano.is_playing:
                        piano.stop_playback()
                    else:
                        piano.play_recording()
            
            elif event.type == pygame.KEYUP:
                if event.key in KEY_MAP:
                    note, octave = KEY_MAP[event.key]
                    actual_octave = octave + piano.octave_offset
                    actual_octave = max(2, min(7, actual_octave))
                    key = piano.get_key_by_note(note, actual_octave)
                    if key:
                        piano.release_key(key)
                    piano.pressed_keys.discard(key)
            
            # ========== 按钮事件 ==========
            if piano.record_button.handle_event(event) and piano.record_button.visible:
                piano.start_recording()
            
            if piano.stop_record_button.handle_event(event) and piano.stop_record_button.visible:
                piano.stop_recording()
            
            if piano.play_button.handle_event(event):
                piano.play_recording()
            
            if piano.clear_button.handle_event(event):
                if piano.is_playing:
                    piano.stop_playback()
                piano.recording = []
                piano.add_message("🗑️ 录音已清空", COLORS['text_light'])
            
            for wf, button in piano.waveform_buttons.items():
                if button.handle_event(event):
                    piano.waveform = wf
                    piano.sound.waveform = wf
                    piano.add_message(f"切换音色: {wf}", COLORS['text_gold'])
            
            if piano.octave_down.handle_event(event):
                piano.octave_offset = max(-2, piano.octave_offset - 1)
                piano.add_message(f"八度偏移: {piano.octave_offset:+d}", COLORS['text_light'])
            
            if piano.octave_up.handle_event(event):
                piano.octave_offset = min(2, piano.octave_offset + 1)
                piano.add_message(f"八度偏移: {piano.octave_offset:+d}", COLORS['text_light'])
            
            if piano.vol_down.handle_event(event):
                piano.volume = max(0.1, piano.volume - 0.1)
                piano.sound.volume = piano.volume
                piano.add_message(f"音量: {int(piano.volume * 100)}%", COLORS['text_light'])
            
            if piano.vol_up.handle_event(event):
                piano.volume = min(1.0, piano.volume + 0.1)
                piano.sound.volume = piano.volume
                piano.add_message(f"音量: {int(piano.volume * 100)}%", COLORS['text_light'])
        
        piano.update()
        piano.draw(screen)
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()