#  Copyright 2020 Modelling, Simulation and Design Lab (MSDL) at
#  McGill University and the University of Antwerp (http://msdl.cs.mcgill.ca/)
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

"""Helper file for :class:`pypdevsbbl.generic.transformers.Pack` and :class:`pypdevsbbl.generic.transformers.Unpack` blocks.

The classes in this file represent generic containers in which items can be "packed" together.
"""

class Package:
    """Generic container that holds items.

    All custom containers must inherit from this class,
    or implement the same methods.

    Attributes:
        contents (list):    A container for all packed items.
    """
    def __init__(self, *args):
        self.contents = []

    def pack(self, new, elapsed=0.0, time=0.0):
        """Packs a new item in this package.

        Args:
            new (any):          The new object to join to the package.
            elapsed (numeric):  The elpased time since the last package.
                                Defaults to 0.
            time (numeric):     The total simulation time. Defaults to 0.
        """
        self.contents.append(new)

    def unpack(self):
        """Releases the contents of this package.

        After this method is executed, the Package must be in its original state.
        """
        ret = self.contents[:]
        self.contents.clear()
        return ret

    def finished(self):
        """Indicates if the package is finished or not.

        Whenever this evaluates to ``True`` after a :meth:`pack`-call, the package
        should be released automatically.
        """
        return False


class SizedPackage(Package):
    """A :class:`Package` that has a maximal size."""
    def __init__(self, size):
        super(SizedPackage, self).__init__()
        self.size = size

    def finished(self):
        return len(self.contents) >= self.size
