# coding=utf-8
from abc import ABCMeta, abstractmethod

from .types import *

__all__ = ["PlatformDynamicsFactory", "PlatformDynamics"]


class PlatformDynamics(metaclass=ABCMeta):
    """
        This class represents the state of a dynamical system.


            s0 = ...

            s1 = s0.integrate(dt=0.1, commands=[1,1])
            s2 = s0.integrate(dt=0.1, commands=[1,1])


        Each subclass has its own representation of commands.

    """

    @abstractmethod
    def integrate(self, dt: float, commands):
        """
            Returns the result of applying commands for dt.

            :param dt > 0: time interval
            :param commands: class-specific commands
            :return: the next state
        """

    @abstractmethod
    def TSE2_from_state(self) -> TSE2v:
        """ Returns pose, velocity for the state. """


class PlatformDynamicsFactory(metaclass=ABCMeta):
    @classmethod
    @abstractmethod
    def initialize(cls, c0: TSE2v, t0: float = 0, seed: int = None) -> PlatformDynamics:
        """
            Returns the dynamics initalized at a certain configuration.

            :param c0: configuration in TSE2
            :param t0: time in which to sstart
            :param seed: seed for a possible random number generator

        """
