from tiramisu.config import Config
from tiramisu import option
# we shall keep extendable types out of the reach of unexceptional guys like us 
# horror __metaclass__ = extendabletype

def get_fullpath(opt, path):
    if path:
        return "%s.%s" % (path, opt._name)
    else:
        return opt._name

class Option:
    def make_rest_doc(self, path=""):
        fullpath = get_fullpath(self, path)
        result = Rest(
            Title(fullpath, abovechar="=", belowchar="="),
            ListItem(Strong("name:"), self._name),
            ListItem(Strong("description:"), self.doc))
        return result

class ChoiceOption(Option, option.ChoiceOption):
    def make_rest_doc(self, path=""):
        content = super(ChoiceOption, self).make_rest_doc(path)
        content.add(ListItem(Strong("option type:"), "choice option"))
        content.add(ListItem(Strong("possible values:"),
                             *[ListItem(str(val)) for val in self.values]))
        if self.default is not None:
            content.add(ListItem(Strong("default:"), str(self.default)))

#        requirements = []
#        
#        for val in self.values:
#            if val not in self._requires:
#                continue
#            req = self._requires[val]
#            requirements.append(ListItem("value '%s' requires:" % (val, ),
#                *[ListItem(Link(opt, opt + ".html"),
#                           "to be set to '%s'" % (rval, ))
#                      for (opt, rval) in req]))
#        if requirements:
#            content.add(ListItem(Strong("requirements:"), *requirements))
        return content

class BoolOption(Option, option.BoolOption):
    def make_rest_doc(self, path=""):
        content = super(BoolOption, self).make_rest_doc(path)
        fullpath = get_fullpath(self, path)
        content.add(ListItem(Strong("option type:"), "boolean option"))
        if self.default is not None:
            content.add(ListItem(Strong("default:"), str(self.default)))
#        if self._requires is not None:
#            requirements = [ListItem(Link(opt, opt + ".html"),
#                               "must be set to '%s'" % (rval, ))
#                                for (opt, rval) in self._requires]
#            if requirements:
#                content.add(ListItem(Strong("requirements:"), *requirements))
        return content

class IntOption(Option, option.IntOption):
    def make_rest_doc(self, path=""):
        content = super(IntOption, self).make_rest_doc(path)
        content.add(ListItem(Strong("option type:"), "integer option"))
        if self.default is not None:
            content.add(ListItem(Strong("default:"), str(self.default)))
        return content

class FloatOption(Option, option.FloatOption):
    def make_rest_doc(self, path=""):
        content = super(FloatOption, self).make_rest_doc(path)
        content.add(ListItem(Strong("option type:"), "float option"))
        if self.default is not None:
            content.add(ListItem(Strong("default:"), str(self.default)))
        return content

class StrOption(Option, option.StrOption):
    def make_rest_doc(self, path=""):
        content = super(StrOption, self).make_rest_doc(path)
        content.add(ListItem(Strong("option type:"), "string option"))
        if self.default is not None:
            content.add(ListItem(Strong("default:"), str(self.default)))
        return content

#class ArbitraryOption:
#    def make_rest_doc(self, path=""):
#        content = super(ArbitraryOption, self).make_rest_doc(path)
#        content.add(ListItem(Strong("option type:"),
#                             "arbitrary option (mostly internal)"))
#        if self.default is not None:
#            content.add(ListItem(Strong("default:"), str(self.default)))
#        elif self.defaultfactory is not None:
#            content.add(ListItem(Strong("factory for the default value:"),
#                                 str(self.defaultfactory)))
#        return content

class OptionDescription(option.OptionDescription):
    def make_rest_doc(self, path=""):
        fullpath = get_fullpath(self, path)
        content = Rest(
            Title(fullpath, abovechar="=", belowchar="="))
        toctree = []
        for child in self._children:
            subpath = fullpath + "." + child._name
            toctree.append(subpath)
        content.add(Directive("toctree", *toctree, **{'maxdepth': 4}))
        content.join(
            ListItem(Strong("name:"), self._name),
            ListItem(Strong("description:"), self.doc))
        stack = []
        curr = content
#        config = Config(self)
        return content

# ____________________________________________________________