# Path: simfile/_private/generic.py
# E = TypeVar('E')
# 
# class ListWithRepr(UserList, MutableSequence[E]):
#     """
#     Subclass of UserList with type hints and some overrides for convenience.
#     """
#     def __repr__(self) -> str:
#         return '%s(%s)' % (self.__class__.__name__, super().__repr__())
# 
# Path: simfile/_private/property.py
# def item_property(name, alias=None):
#     
#     # Decide whether to use the property's alias instead of its primary name
#     def _name_or_alias(self):
#         if name not in self and alias and alias in self:
#             return alias
#         else:
#             return name
# 
#     @property
#     def item_property(self: MutableMapping[str, str]) -> Optional[str]:
#         return self.get(_name_or_alias(self))
# 
#     @item_property.setter
#     def item_property(self: MutableMapping[str, str], value: str) -> None:
#         self[_name_or_alias(self)] = value
#     
#     @item_property.deleter
#     def item_property(self: MutableMapping[str, str]) -> None:
#         del self[_name_or_alias(self)]
# 
#     return item_property
# 
# Path: simfile/_private/serializable.py
# class Serializable(metaclass=ABCMeta):
# 
#     @abstractmethod
#     def serialize(self, file: TextIO) -> None:
#         """
#         Write the object to provided text file object as MSD.
#         """
#         pass
#     
#     def __str__(self) -> str:
#         """
#         Convert the object to an MSD string.
#         """
#         serialized = StringIO()
#         self.serialize(serialized)
#         return serialized.getvalue()


from abc import ABCMeta, abstractclassmethod, abstractmethod
from collections import OrderedDict
from typing import Iterator, Optional, TextIO, Tuple, Union
from msdparser import parse_msd
from ._private.generic import E, ListWithRepr
from ._private.property import item_property
from ._private.serializable import Serializable
    stepstype = item_property('STEPSTYPE')
    description = item_property('DESCRIPTION')
    difficulty = item_property('DIFFICULTY')
    meter = item_property('METER')
    radarvalues = item_property('RADARVALUES')
    notes = item_property('NOTES')
    
    @abstractmethod
    def _parse(self, parser: MSD_ITERATOR):
        pass

    @abstractclassmethod
    def blank(cls):
        """
        Generate a blank, valid chart populated with standard keys.

        This should approximately match blank charts produced by the
        StepMania editor. 
        """

    def __repr__(self) -> str:
        """
        Pretty repr() for charts.
        
        Includes the class name, stepstype, difficulty, and meter.
        """
        cls = self.__class__.__name__
        return f'<{cls}: {self.stepstype} {self.difficulty} {self.meter}>'



# Path: simfile/_private/generic.py
# E = TypeVar('E')
# 
# class ListWithRepr(UserList, MutableSequence[E]):
#     """
#     Subclass of UserList with type hints and some overrides for convenience.
#     """
#     def __repr__(self) -> str:
#         return '%s(%s)' % (self.__class__.__name__, super().__repr__())
# 
# Path: simfile/_private/property.py
# def item_property(name, alias=None):
#     
#     # Decide whether to use the property's alias instead of its primary name
#     def _name_or_alias(self):
#         if name not in self and alias and alias in self:
#             return alias
#         else:
#             return name
# 
#     @property
#     def item_property(self: MutableMapping[str, str]) -> Optional[str]:
#         return self.get(_name_or_alias(self))
# 
#     @item_property.setter
#     def item_property(self: MutableMapping[str, str], value: str) -> None:
#         self[_name_or_alias(self)] = value
#     
#     @item_property.deleter
#     def item_property(self: MutableMapping[str, str]) -> None:
#         del self[_name_or_alias(self)]
# 
#     return item_property
# 
# Path: simfile/_private/serializable.py
# class Serializable(metaclass=ABCMeta):
# 
#     @abstractmethod
#     def serialize(self, file: TextIO) -> None:
#         """
#         Write the object to provided text file object as MSD.
#         """
#         pass
#     
#     def __str__(self) -> str:
#         """
#         Convert the object to an MSD string.
#         """
#         serialized = StringIO()
#         self.serialize(serialized)
#         return serialized.getvalue()


# Path: simfile/base.py
from abc import ABCMeta, abstractclassmethod, abstractmethod
from collections import OrderedDict
from typing import Iterator, Optional, TextIO, Tuple, Union
from msdparser import parse_msd
from ._private.generic import E, ListWithRepr
from ._private.property import item_property
from ._private.serializable import Serializable

    stepstype = item_property('STEPSTYPE')
    description = item_property('DESCRIPTION')
    difficulty = item_property('DIFFICULTY')
    meter = item_property('METER')
    radarvalues = item_property('RADARVALUES')
    notes = item_property('NOTES')
    
    @abstractmethod
    def _parse(self, parser: MSD_ITERATOR):
        pass

    @abstractclassmethod
    def blank(cls):
        """
        Generate a blank, valid chart populated with standard keys.

        This should approximately match blank charts produced by the
        StepMania editor. 
        """

    def __repr__(self) -> str:
        """
        Pretty repr() for charts.
        
        Includes the class name, stepstype, difficulty, and meter.
        """
        cls = self.__class__.__name__
        return f'<{cls}: {self.stepstype} {self.difficulty} {self.meter}>'



class BaseCharts(ListWithRepr[E], Serializable, metaclass=ABCMeta):