# Path: simfile/sm.py
# class SMSimfile(BaseSimfile):
#     """
#     SM implementation of :class:`~simfile.base.BaseSimfile`.
#     """
#     _charts: SMCharts
# 
#     # "FREEZES" alias only supported by SM files
#     stops = item_property('STOPS', alias='FREEZES')
# 
#     def _parse(self, parser: MSD_ITERATOR):
#         self._charts = SMCharts()
#         for (key, value) in parser:
#             key = key.upper()
#             if key == 'NOTES':
#                 self._charts.append(SMChart.from_str(value))
#             else:                
#                 self[key] = value
#     
#     @classmethod
#     def blank(cls: Type['SMSimfile']) -> 'SMSimfile':
#         return SMSimfile(string=dedent_and_trim("""
#             #TITLE:;
#             #SUBTITLE:;
#             #ARTIST:;
#             #TITLETRANSLIT:;
#             #SUBTITLETRANSLIT:;
#             #ARTISTTRANSLIT:;
#             #GENRE:;
#             #CREDIT:;
#             #BANNER:;
#             #BACKGROUND:;
#             #LYRICSPATH:;
#             #CDTITLE:;
#             #MUSIC:;
#             #OFFSET:0.000000;
#             #SAMPLESTART:100.000000;
#             #SAMPLELENGTH:12.000000;
#             #SELECTABLE:YES;
#             #BPMS:0.000000=60.000000;
#             #STOPS:;
#             #BGCHANGES:;
#             #KEYSOUNDS:;
#             #ATTACKS:;
#         """))
#     
#     @property
#     def charts(self) -> SMCharts:
#         return self._charts
# 
# Path: simfile/ssc.py
# class SSCSimfile(BaseSimfile):
#     """
#     SSC implementation of :class:`~simfile.base.BaseSimfile`.
# 
#     Adds the following known properties:
#     
#     * SSC version: `version`
#     * Metadata: `origin`, `labels`, `musiclength`, `lastsecondhint`
#     * File paths: `previewvid`, `jacket`, `cdimage`, `discimage`,
#       `preview`
#     * Gameplay events: `combos`, `speeds`, `scrolls`, `fakes`
#     * Timing data: `warps`
#     """
#     _charts: SSCCharts
#     
#     version = item_property('VERSION')
#     origin = item_property('ORIGIN')
#     previewvid = item_property('PREVIEWVID')
#     jacket = item_property('JACKET')
#     cdimage = item_property('CDIMAGE')
#     discimage = item_property('DISCIMAGE')
#     preview = item_property('PREVIEW')
#     musiclength = item_property('MUSICLENGTH')
#     lastsecondhint = item_property('LASTSECONDHINT')
#     warps = item_property('WARPS')
#     labels = item_property('LABELS')
#     combos = item_property('COMBOS')
#     speeds = item_property('SPEEDS')
#     scrolls = item_property('SCROLLS')
#     fakes = item_property('FAKES')
# 
#     @classmethod
#     def blank(cls: Type['SSCSimfile']) -> 'SSCSimfile':
#         return SSCSimfile(string=dedent_and_trim("""
#             #VERSION:0.83;
#             #TITLE:;
#             #SUBTITLE:;
#             #ARTIST:;
#             #TITLETRANSLIT:;
#             #SUBTITLETRANSLIT:;
#             #ARTISTTRANSLIT:;
#             #GENRE:;
#             #ORIGIN:;
#             #CREDIT:;
#             #BANNER:;
#             #BACKGROUND:;
#             #PREVIEWVID:;
#             #JACKET:;
#             #CDIMAGE:;
#             #DISCIMAGE:;
#             #LYRICSPATH:;
#             #CDTITLE:;
#             #MUSIC:;
#             #OFFSET:0.000000;
#             #SAMPLESTART:100.000000;
#             #SAMPLELENGTH:12.000000;
#             #SELECTABLE:YES;
#             #BPMS:0.000=60.000;
#             #STOPS:;
#             #DELAYS:;
#             #WARPS:;
#             #TIMESIGNATURES:0.000=4=4;
#             #TICKCOUNTS:0.000=4;
#             #COMBOS:0.000=1;
#             #SPEEDS:0.000=1.000=0.000=0;
#             #SCROLLS:0.000=1.000;
#             #FAKES:;
#             #LABELS:0.000=Song Start;
#             #BGCHANGES:;
#             #KEYSOUNDS:;
#             #ATTACKS:;
#         """))
# 
#     def _parse(self, parser):
#         self._charts = SSCCharts()
#         partial_chart: Optional[SSCChart] = None
#         for key, value in parser:
#             key = key.upper()            
#             if key == 'NOTEDATA':
#                 if partial_chart is not None:
#                     self._charts.append(partial_chart)
#                 partial_chart = SSCChart()
#             elif partial_chart is not None:
#                 partial_chart[key] = value
#             else:
#                 self[key] = value
#         if partial_chart is not None:
#             self._charts.append(partial_chart)
#     
#     @property
#     def charts(self) -> SSCCharts:
#         return self._charts


import unittest
import simfile
from ..sm import SMSimfile
from ..ssc import SSCSimfile
from ..convert import *



class TestConvert(unittest.TestCase):
    def test_sm_to_ssc(self):
        sm: SMSimfile = simfile.open('testdata/Kryptix.sm')
        
        ssc = sm_to_ssc(sm)

        for property, value in sm.items():
            self.assertEqual(value, ssc[property])
        self.assertEqual('0.83', ssc.version)
        self.assertEqual(len(sm.charts), len(ssc.charts))
        for sm_chart, ssc_chart in zip(sm.charts, ssc.charts):
            for property, value in sm_chart.items():
                self.assertEqual(value, ssc_chart[property])
    
    def test_ssc_to_sm_raises_by_default(self):
        ssc: SSCSimfile = simfile.open('testdata/Springtime.ssc')
        
        self.assertRaises(InvalidPropertyException, ssc_to_sm, ssc)

    def test_ssc_to_sm_with_lenient_invalid_property_behaviors(self):

# Path: simfile/sm.py
# class SMSimfile(BaseSimfile):
#     """
#     SM implementation of :class:`~simfile.base.BaseSimfile`.
#     """
#     _charts: SMCharts
# 
#     # "FREEZES" alias only supported by SM files
#     stops = item_property('STOPS', alias='FREEZES')
# 
#     def _parse(self, parser: MSD_ITERATOR):
#         self._charts = SMCharts()
#         for (key, value) in parser:
#             key = key.upper()
#             if key == 'NOTES':
#                 self._charts.append(SMChart.from_str(value))
#             else:                
#                 self[key] = value
#     
#     @classmethod
#     def blank(cls: Type['SMSimfile']) -> 'SMSimfile':
#         return SMSimfile(string=dedent_and_trim("""
#             #TITLE:;
#             #SUBTITLE:;
#             #ARTIST:;
#             #TITLETRANSLIT:;
#             #SUBTITLETRANSLIT:;
#             #ARTISTTRANSLIT:;
#             #GENRE:;
#             #CREDIT:;
#             #BANNER:;
#             #BACKGROUND:;
#             #LYRICSPATH:;
#             #CDTITLE:;
#             #MUSIC:;
#             #OFFSET:0.000000;
#             #SAMPLESTART:100.000000;
#             #SAMPLELENGTH:12.000000;
#             #SELECTABLE:YES;
#             #BPMS:0.000000=60.000000;
#             #STOPS:;
#             #BGCHANGES:;
#             #KEYSOUNDS:;
#             #ATTACKS:;
#         """))
#     
#     @property
#     def charts(self) -> SMCharts:
#         return self._charts
# 
# Path: simfile/ssc.py
# class SSCSimfile(BaseSimfile):
#     """
#     SSC implementation of :class:`~simfile.base.BaseSimfile`.
# 
#     Adds the following known properties:
#     
#     * SSC version: `version`
#     * Metadata: `origin`, `labels`, `musiclength`, `lastsecondhint`
#     * File paths: `previewvid`, `jacket`, `cdimage`, `discimage`,
#       `preview`
#     * Gameplay events: `combos`, `speeds`, `scrolls`, `fakes`
#     * Timing data: `warps`
#     """
#     _charts: SSCCharts
#     
#     version = item_property('VERSION')
#     origin = item_property('ORIGIN')
#     previewvid = item_property('PREVIEWVID')
#     jacket = item_property('JACKET')
#     cdimage = item_property('CDIMAGE')
#     discimage = item_property('DISCIMAGE')
#     preview = item_property('PREVIEW')
#     musiclength = item_property('MUSICLENGTH')
#     lastsecondhint = item_property('LASTSECONDHINT')
#     warps = item_property('WARPS')
#     labels = item_property('LABELS')
#     combos = item_property('COMBOS')
#     speeds = item_property('SPEEDS')
#     scrolls = item_property('SCROLLS')
#     fakes = item_property('FAKES')
# 
#     @classmethod
#     def blank(cls: Type['SSCSimfile']) -> 'SSCSimfile':
#         return SSCSimfile(string=dedent_and_trim("""
#             #VERSION:0.83;
#             #TITLE:;
#             #SUBTITLE:;
#             #ARTIST:;
#             #TITLETRANSLIT:;
#             #SUBTITLETRANSLIT:;
#             #ARTISTTRANSLIT:;
#             #GENRE:;
#             #ORIGIN:;
#             #CREDIT:;
#             #BANNER:;
#             #BACKGROUND:;
#             #PREVIEWVID:;
#             #JACKET:;
#             #CDIMAGE:;
#             #DISCIMAGE:;
#             #LYRICSPATH:;
#             #CDTITLE:;
#             #MUSIC:;
#             #OFFSET:0.000000;
#             #SAMPLESTART:100.000000;
#             #SAMPLELENGTH:12.000000;
#             #SELECTABLE:YES;
#             #BPMS:0.000=60.000;
#             #STOPS:;
#             #DELAYS:;
#             #WARPS:;
#             #TIMESIGNATURES:0.000=4=4;
#             #TICKCOUNTS:0.000=4;
#             #COMBOS:0.000=1;
#             #SPEEDS:0.000=1.000=0.000=0;
#             #SCROLLS:0.000=1.000;
#             #FAKES:;
#             #LABELS:0.000=Song Start;
#             #BGCHANGES:;
#             #KEYSOUNDS:;
#             #ATTACKS:;
#         """))
# 
#     def _parse(self, parser):
#         self._charts = SSCCharts()
#         partial_chart: Optional[SSCChart] = None
#         for key, value in parser:
#             key = key.upper()            
#             if key == 'NOTEDATA':
#                 if partial_chart is not None:
#                     self._charts.append(partial_chart)
#                 partial_chart = SSCChart()
#             elif partial_chart is not None:
#                 partial_chart[key] = value
#             else:
#                 self[key] = value
#         if partial_chart is not None:
#             self._charts.append(partial_chart)
#     
#     @property
#     def charts(self) -> SSCCharts:
#         return self._charts


# Path: simfile/tests/test_convert.py
import unittest
import simfile
from ..sm import SMSimfile
from ..ssc import SSCSimfile
from ..convert import *




class TestConvert(unittest.TestCase):
    def test_sm_to_ssc(self):
        sm: SMSimfile = simfile.open('testdata/Kryptix.sm')
        
        ssc = sm_to_ssc(sm)

        for property, value in sm.items():
            self.assertEqual(value, ssc[property])
        self.assertEqual('0.83', ssc.version)
        self.assertEqual(len(sm.charts), len(ssc.charts))
        for sm_chart, ssc_chart in zip(sm.charts, ssc.charts):
            for property, value in sm_chart.items():
                self.assertEqual(value, ssc_chart[property])
    
    def test_ssc_to_sm_raises_by_default(self):
        ssc: SSCSimfile = simfile.open('testdata/Springtime.ssc')
        
        self.assertRaises(InvalidPropertyException, ssc_to_sm, ssc)

    def test_ssc_to_sm_with_lenient_invalid_property_behaviors(self):

        ssc: SSCSimfile = simfile.open('testdata/Springtime.ssc')