# Path: css2video/constants.py
# class ValueType(object):
#     """Class to define constants for value types"""
# 
#     number = 'number'
#     length = 'length'
#     percentage = 'percentage'
#     time = 'time'
#     color = 'color'
#     text = 'text'
#     url = 'url'
#     function = 'function'
#     array = 'array'
# 
# Path: css2video/parsers/base.py
# class BaseParser(object):
#     """
#     A base class for all the parsers
# 
#     Attributes
#     ----------
#     ParseException : object
#         exception to be raised when there is a parsing error
# 
#     Methods
#     -------
#     grammar :
#         method to be overrridden by inheriting class which defines the grammar
#     parse_action :
#         method to be overrridden by inheriting class which defines the parse
#         action for the matched token
#     parser :
#         returns a parser by setting the parse action to the grammar
#     parse :
#         method to parse a string into a dictionary using the grammar and parse
#         action
#     """
# 
#     ParseException = None
# 
#     @classmethod
#     def grammar(cls):
#         """This method is overridden by the class which inherits the
#         BaseParser. The method should return a grammar"""
#         raise NotImplemented()
# 
#     @classmethod
#     def parse_action(cls):
#         """This method is overridden by the class which inherits the
#         BaseParser. The method should create a dictionary from the parsed
#         tokens"""
#         raise NotImplemented()
# 
#     @classmethod
#     def parser(cls):
#         """Returns the grammar with parse action set so that once the result is
#         parsed, the output is available as a dictionary"""
#         return cls.grammar().setParseAction(cls.parse_action)
# 
#     @classmethod
#     def parse(cls, string):
#         """
#         Parse a given string using the grammar and parse action and returns
#         a dictionary
# 
#         Parameters
#         ----------
#         string : str
#             string to be parsed
# 
#         Returns
#         -------
#         dict :
#             dictionary after parsing the string
#         """
#         try:
#             return cls.parser().parseString(string, parseAll=True)[0]
#         except pp.ParseException:
#             raise cls.ParseException()


import pyparsing as pp
from css2video.constants import ValueType
from .base import BaseParser

    @classmethod
    def grammar(cls):
        """Grammar to parse a function value"""
        name = pp.Word(pp.alphas)
        args = cls.args_parser()

        return (
            name +
            pp.Suppress(pp.Literal('(')) +
            args +
            pp.Suppress(pp.Literal(')'))
        )

    @classmethod
    def parse_action(cls, tokens):
        """Returns a dictionary from the parsed tokens"""
        return {
            'type': ValueType.function,
            'name': tokens[0],
            'args': tokens[1:]
        }

    @classmethod
    def args_parser(cls):
        """Returns the arguments of the function which can be a Number, Length,
        Percentage, Time, Color, Text or URL"""
        arg_types = [Number, Length, Percentage, Time, Color, Text, Url]
        arg_parser = arg_types[0].parser()
        for arg_type in arg_types[1:]:

# Path: css2video/constants.py
# class ValueType(object):
#     """Class to define constants for value types"""
# 
#     number = 'number'
#     length = 'length'
#     percentage = 'percentage'
#     time = 'time'
#     color = 'color'
#     text = 'text'
#     url = 'url'
#     function = 'function'
#     array = 'array'
# 
# Path: css2video/parsers/base.py
# class BaseParser(object):
#     """
#     A base class for all the parsers
# 
#     Attributes
#     ----------
#     ParseException : object
#         exception to be raised when there is a parsing error
# 
#     Methods
#     -------
#     grammar :
#         method to be overrridden by inheriting class which defines the grammar
#     parse_action :
#         method to be overrridden by inheriting class which defines the parse
#         action for the matched token
#     parser :
#         returns a parser by setting the parse action to the grammar
#     parse :
#         method to parse a string into a dictionary using the grammar and parse
#         action
#     """
# 
#     ParseException = None
# 
#     @classmethod
#     def grammar(cls):
#         """This method is overridden by the class which inherits the
#         BaseParser. The method should return a grammar"""
#         raise NotImplemented()
# 
#     @classmethod
#     def parse_action(cls):
#         """This method is overridden by the class which inherits the
#         BaseParser. The method should create a dictionary from the parsed
#         tokens"""
#         raise NotImplemented()
# 
#     @classmethod
#     def parser(cls):
#         """Returns the grammar with parse action set so that once the result is
#         parsed, the output is available as a dictionary"""
#         return cls.grammar().setParseAction(cls.parse_action)
# 
#     @classmethod
#     def parse(cls, string):
#         """
#         Parse a given string using the grammar and parse action and returns
#         a dictionary
# 
#         Parameters
#         ----------
#         string : str
#             string to be parsed
# 
#         Returns
#         -------
#         dict :
#             dictionary after parsing the string
#         """
#         try:
#             return cls.parser().parseString(string, parseAll=True)[0]
#         except pp.ParseException:
#             raise cls.ParseException()


# Path: css2video/parsers/value.py
import pyparsing as pp
from css2video.constants import ValueType
from .base import BaseParser


    @classmethod
    def grammar(cls):
        """Grammar to parse a function value"""
        name = pp.Word(pp.alphas)
        args = cls.args_parser()

        return (
            name +
            pp.Suppress(pp.Literal('(')) +
            args +
            pp.Suppress(pp.Literal(')'))
        )

    @classmethod
    def parse_action(cls, tokens):
        """Returns a dictionary from the parsed tokens"""
        return {
            'type': ValueType.function,
            'name': tokens[0],
            'args': tokens[1:]
        }

    @classmethod
    def args_parser(cls):
        """Returns the arguments of the function which can be a Number, Length,
        Percentage, Time, Color, Text or URL"""
        arg_types = [Number, Length, Percentage, Time, Color, Text, Url]
        arg_parser = arg_types[0].parser()
        for arg_type in arg_types[1:]:

            arg_parser ^= arg_type.parser()