#!/usr/bin/env python
# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import re
import sys

import in_generator
import template_expander


class StyleBuilderWriter(in_generator.Writer):
    class_name = 'StyleBuilder'

    valid_values = {
        'apply_type': ['default', 'length'],
        'use_none': [True, False],
        'use_intrinsic': [True, False],
        'use_auto': [True, False],
        'custom_all': [True, False],
        'custom_initial': [True, False],
        'custom_inherit': [True, False],
        'custom_value': [True, False],
    }
    defaults = {
        'condition': None,
        'apply_type': 'default',
        'name_for_methods': None,
        'use_handlers_for': None,
# These depend on property name by default
        'type_name': None,
        'getter': None,
        'setter': None,
        'initial': None,
# Setting these stops default handlers being generated
# Setting custom_all is the same as setting the other three
        'custom_all': False,
        'custom_initial': False,
        'custom_inherit': False,
        'custom_value': False,
# For the length apply type. Will get moved out to StyleBuilderFunctions.cpp.tmpl
        'use_none': False,
        'use_intrinsic': False,
        'use_auto': False,
    }

    def __init__(self, in_files, enabled_conditions):
        super(StyleBuilderWriter, self).__init__(in_files, enabled_conditions)
        self._outputs = {("StyleBuilderFunctions.h"): self.generate_style_builder_functions_h,
                         ("StyleBuilderFunctions.cpp"): self.generate_style_builder_functions_cpp,
                         ("StyleBuilder.cpp"): self.generate_style_builder,
                        }

        self._properties = self.in_file.name_dictionaries

        def set_if_none(property, key, value):
            if property[key] is None:
                property[key] = value

        for property in self._properties:
            cc = self._camelcase_property_name(property["name"])
            property["property_id"] = "CSSProperty" + cc
            cc = property["name_for_methods"] or cc.replace("Webkit", "")
            property["camel_case_name"] = cc
            set_if_none(property, "type_name", "E" + cc)
            set_if_none(property, "getter", self._lower_first(cc))
            set_if_none(property, "setter", "set" + cc)
            set_if_none(property, "initial", "initial" + cc)
            if property["custom_all"]:
                property["custom_initial"] = True
                property["custom_inherit"] = True
                property["custom_value"] = True

        self._properties = dict((property["property_id"], property) for property in self._properties)

# FIXME: some of these might be better in a utils file
    @staticmethod
    def _camelcase_property_name(property_name):
        return re.sub(r'(^[^-])|-(.)', lambda match: (match.group(1) or match.group(2)).upper(), property_name)

    @staticmethod
    def _lower_first(s):
        return s[0].lower() + s[1:]

    @staticmethod
    def _upper_first(s):
        return s[0].upper() + s[1:]

    @template_expander.use_jinja("StyleBuilderFunctions.h.tmpl")
    def generate_style_builder_functions_h(self):
        return {
            "properties": self._properties,
        }

    @template_expander.use_jinja("StyleBuilderFunctions.cpp.tmpl")
    def generate_style_builder_functions_cpp(self):
        return {
            "properties": self._properties,
        }

    @template_expander.use_jinja("StyleBuilder.cpp.tmpl")
    def generate_style_builder(self):
        return {
            "properties": self._properties,
        }


if __name__ == "__main__":
    in_generator.Maker(StyleBuilderWriter).main(sys.argv)
