"""
Provides container token classes for the GiPSy scanner.

Library Version 1.1

Copyright 2013 Paul Griffiths
Email: mail@paulgriffiths.net

Distributed under the terms of the GNU General Public License.
http://www.gnu.org/licenses/
"""


from gipsy.tokenlist import TokenList
from gipsy.token import Token


class OpeningToken(Token):

    """
    Generic matched opening container token class.
    """

    def __init__(self, value):

        """
        Class initializer.

        Arguments:
        value -- the string to be tokenized.
        """

        Token.__init__(self, value)
        self._token_type_string = "Opening"


class ClosingToken(Token):

    """
    Generic matched closing container token class.
    """

    def __init__(self, value):

        """
        Class initializer.

        Arguments:
        value -- the string to be tokenized.
        """

        Token.__init__(self, value)
        self._token_type_string = "Closing"


class UnmatchedToken(Token):

    """
    Generic unmatched opening or closing container token class.
    """

    def __init__(self, value):

        """
        Class initializer.

        Arguments:
        value -- the string to be tokenized.
        """

        Token.__init__(self, value)
        self._token_type_string = "Unmatched"


class ContainerToken(Token):

    """
    Container token class.

    Allows a container (e.g. matched pair of parentheses,
    braces, brackets) to be represented by a single token
    in another list of tokens, and treated as such.

    Instance attributes:
    _tlist : a TokenList instance containing the contained tokens

    """

    def __init__(self, value, parser):

        """
        Class initializer.

        Arguments:
        value -- the string to be tokenized.
        parser -- a reference to the parser which instantiated
        the instance, used to parse the contained tokens.
        """

        Token.__init__(self, value)
        self._token_type_string = "Container"
        self._tlist = TokenList()

        # Push opening container token, parsed contained
        # tokens, and closing container token onto the list

        c_open, c_middle, c_close = value[0], value[1:-1], value[-1]
        self._tlist.push(OpeningToken(c_open))
        self._tlist.push(parser.list_tokenize(c_middle))
        self._tlist.push(ClosingToken(c_close))

    def read(self, decorated=False, html=False, tree=False):

        """
        Returns a string representing the unmodified or modified tokens.

        Arguments:
        decorated -- set to True to decorate with dec_open and dec_close
        html -- set to True to HTML-escape the characters
        tree -- set to True to output in an indented tree view
        """

        if tree:
            old_prefix = Token.prefix
            Token.prefix += "  "

        out_str = self._tlist.read(decorated=decorated, html=html, tree=tree)

        if tree:
            Token.prefix = old_prefix

        return out_str
