from music21 import converter, note, chord, stream, harmony
import random

# Предварительно определенный словарь эмоций и ассоциированных сценарных элементов
emotion_to_scene = {
    'joyful': ['солнечный день', 'дети играют в парке', 'праздничный фестиваль'],
    'tense': ['погоня на автомобилях', 'затяжной дождь', 'проникновение в запретное место'],
    'sad': ['похороны', 'разбитое сердце', 'одиночество в толпе'],
    'peaceful': ['закат на берегу моря', 'медитация в тихом саду', 'утренняя прогулка']
}

def analyze_emotion(key_signature, dynamics):
    # Примерная функция для анализа эмоции на основе музыки
    if 'minor' in key_signature:
        return 'sad'
    if dynamics > 0.7:
        return 'joyful'
    # Дополнительные правила могут быть добавлены здесь
    return 'peaceful'

def extract_notes_and_chords(file_path):
    # Загружаем файл MusicXML
    score = converter.parse(file_path)
    
    elements = []
    scenes = []
    
    # Проходим по всем элементам в файле
    for part_index, part in enumerate(score.parts):
        measure_number = 1  # Начинаем с первого такта
        for measure in part.getElementsByClass(stream.Measure):  # Работаем с тактами напрямую
            # Извлекаем информацию о такте и тональности
            time_signature = measure.timeSignature
            key_signature = measure.keySignature
            
            for element in measure.notesAndRests:
                element_info = {
                    'part_index': part_index + 1,
                    'type': '',
                    'pitch': '',
                    'duration': element.duration.quarterLength,
                    'offset': element.offset,
                    'measure': measure_number,
                    'time_signature': str(time_signature) if time_signature else None,
                    'key_signature': str(key_signature) if key_signature else None,
                    'dynamics': None,
                    'articulations': None,
                    'harmony': None  # Инициализируем поле гармонии
                }
                
                # Извлекаем динамику и артикуляции, если они есть и если элемент не является паузой
                if not element.isRest:
                    dynamics = None
                    if hasattr(element, 'volume') and element.volume.velocityScalar is not None:
                        dynamics = element.volume.velocityScalar
                        element_info['dynamics'] = dynamics
                    
                    # Проверяем, является ли элемент нотой или аккордом
                    if isinstance(element, note.Note):
                        element_info['type'] = 'note'
                        element_info['pitch'] = str(element.pitch)
                    elif isinstance(element, chord.Chord):
                        element_info['type'] = 'chord'
                        element_info['pitch'] = '+'.join(str(p) for p in element.pitches)
                        element_info['harmony'] = extract_harmony(element)  # Добавляем анализ гармонии
                
                elements.append(element_info)

                # Анализируем эмоцию и добавляем сцену, соответствующую этой эмоции
                if dynamics is not None:  # Динамика определена
                    emotion = analyze_emotion(str(key_signature), dynamics)
                    possible_scenes = emotion_to_scene.get(emotion, [])
                    scene_description = random.choice(possible_scenes) if possible_scenes else 'неопределенная сцена'
                    scenes.append((measure_number, emotion, scene_description))
                
            measure_number += 1  # Переходим к следующему такту

    # Возвращаем список элементов и список сцен
    return elements, scenes

# Пример использования функции
elements, scenes = extract_notes_and_chords('C:/Users/ARTYOM/Documents/Python/Bring_it_up.musicxml')
for e in elements:
    print(e)

for measure_number, emotion, scene_description in scenes:
    print(f"Такт: {measure_number}, Эмоция: {emotion}, Предлагаемая сцена: {scene_description}")