# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

from trytond.model import DictSchemaMixin, ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Eval, If


class ModelViewChangedValues(ModelView):
    __name__ = 'test.modelview.changed_values'
    name = fields.Char('Name')
    target = fields.Many2One('test.modelview.changed_values.target', 'Target')
    stored_target = fields.Many2One(
        'test.modelview.changed_values.stored_target', "Stored Target")
    ref_target = fields.Reference('Target Reference', [
            ('test.modelview.changed_values.target', 'Target'),
            ])
    targets = fields.One2Many('test.modelview.changed_values.target', 'parent',
        'Targets')
    m2m_targets = fields.Many2Many('test.modelview.changed_values.target',
        None, None, 'Targets')
    multiselection = fields.MultiSelection([
            ('a', 'A'), ('b', 'B'),
            ], "MultiSelection")
    dictionary = fields.Dict(
        'test.modelview.changed_values.dictionary', "Dictionary")
    m2m_function = fields.Function(fields.Many2Many(
            'test.modelview.changed_values.target', None, None, "Targets"),
        'on_change_with_m2m_function')

    def on_change_with_m2m_function(self, name=None):
        return


class ModelViewChangedValuesDictSchema(DictSchemaMixin, ModelSQL):
    __name__ = 'test.modelview.changed_values.dictionary'


class ModelViewChangedValuesTarget(ModelView):
    __name__ = 'test.modelview.changed_values.target'
    name = fields.Char('Name')
    parent = fields.Many2One('test.modelview.changed_values', 'Parent')


class ModelViewChangedValuesStoredTarget(ModelSQL):
    __name__ = 'test.modelview.changed_values.stored_target'
    name = fields.Char("Name")


class ModelViewStoredChangedValues(ModelSQL, ModelView):
    __name__ = 'test.modelview.stored.changed_values'
    targets = fields.One2Many(
        'test.modelview.stored.changed_values.target', 'parent', "Targets")


class ModelViewStoredChangedValuesTarget(ModelSQL, ModelView):
    __name__ = 'test.modelview.stored.changed_values.target'
    name = fields.Char("Name")
    parent = fields.Many2One('test.modelview.stored.changed_values', "Parent")


class ModelViewButton(ModelView):
    __name__ = 'test.modelview.button'
    value = fields.Integer("Value")

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls._buttons = {
            'test': {},
            'test_invisible': {
                'invisible': Eval('value', 0) == 42,
                },
            'test_readonly': {
                'readonly': Eval('value', 0) == 42,
                },
            }

    @classmethod
    @ModelView.button
    def test(cls, records):
        cls.test_non_decorated(records)

    @classmethod
    def test_non_decorated(cls, records):
        pass

    @classmethod
    @ModelView.button
    def test_invisible(cls, records):
        pass

    @classmethod
    @ModelView.button
    def test_readonly(cls, records):
        pass


class ModelViewButtonDepends(ModelView):
    __name__ = 'test.modelview.button_depends'
    value = fields.Integer("Value")

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls._buttons = {
            'test': {
                'depends': ['value'],
                },
            }

    @classmethod
    @ModelView.button
    def test(cls, records):
        pass


class ModelViewButtonAction(ModelView):
    __name__ = 'test.modelview.button_action'

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls._buttons = {
            'test': {},
            }

    @classmethod
    @ModelView.button_action('tests.test_modelview_button_action')
    def test(cls, records):
        pass

    @classmethod
    @ModelView.button_action('tests.test_modelview_button_action')
    def test_update(cls, records):
        return {'url': 'http://www.tryton.org/'}


class ModelViewButtonChange(ModelView):
    __name__ = 'test.modelview.button_change'

    name = fields.Char("Name")
    extra = fields.Char("Extra")

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls._buttons = {
            'test': {}
            }

    @ModelView.button_change('name', methods=['extra_method'])
    def test(self):
        self.extra_method()

    @fields.depends('extra')
    def extra_method(self):
        pass


class ModelViewLink(ModelView):
    __name__ = 'test.modelview.link'


class ModelViewLinkTarget(ModelSQL):
    __name__ = 'test.modelview.link.target'


class ModelViewRPC(ModelView):
    __name__ = 'test.modelview.rpc'

    selection = fields.Selection([('a', 'A')], 'Selection')
    computed_selection = fields.Selection(
        'get_selection', 'Computed Selection')
    function_selection = fields.Function(
        fields.Selection('get_function_selection', 'Function Selection'),
        'function_selection_getter')

    reference = fields.Reference('Reference', selection=[('a', 'A')])
    computed_reference = fields.Reference(
        'Computed reference', selection='get_reference')
    function_reference = fields.Function(
        fields.Reference('Function Reference',
            selection='get_function_reference'),
        'function_reference_getter')

    integer = fields.Integer('Integer')
    float = fields.Float('Float')
    char = fields.Char('Char')

    @fields.depends('selection')
    def on_change_with_integer(self):
        pass

    @fields.depends('reference')
    def on_change_float(self):
        pass

    @fields.depends('integer')
    def autocomplete_char(self):
        pass

    @classmethod
    def get_selection(cls):
        pass

    @classmethod
    def get_function_selection(cls):
        pass

    @classmethod
    def get_reference(cls):
        pass

    @classmethod
    def get_function_reference(cls):
        pass


class ModelViewEmptyPage(ModelView):
    __name__ = 'test.modelview.empty_page'


class ModelViewEmptyPageAccess(ModelView):
    __name__ = 'test.modelview.empty_page.access'

    foo = fields.Char("Char")


class ModelViewCircularDepends(ModelView):
    __name__ = 'test.modelview.circular_depends'

    foo = fields.Char("Char", depends=['bar'])
    bar = fields.Char("Char", depends=['foobar'])
    foobar = fields.Char("Char", depends=['foo'])


class ModeViewDependsDepends(ModelView):
    __name__ = 'test.modelview.depends_depends'

    foo = fields.Char("Foo", depends=['bar'])
    bar = fields.Char("Bar", depends=['baz'])
    baz = fields.Char("Baz")


class ModelViewViewAttributes(ModelView):
    __name__ = 'test.modelview.view_attributes'

    foo = fields.Char("Char")

    @classmethod
    def view_attributes(cls):
        return super().view_attributes() + [
            ('//field[@name="foo"]',
                'visual', If(Eval('foo') == 'foo', 'danger', '')),
            ]


class ModelViewViewAttributesDepends(ModelView):
    __name__ = 'test.modelview.view_attributes_depends'

    foo = fields.Char("Char")
    bar = fields.Char("Char")

    @classmethod
    def view_attributes(cls):
        return super().view_attributes() + [
            ('//field[@name="foo"]',
                'visual', If(Eval('bar') == 'foo', 'danger', ''), ['bar']),
            ]


class ModelViewStatesDepends(ModelView):
    __name__ = 'test.modelview.states_depends'

    foo = fields.Char("Foo",
        states={
            'invisible': Eval('bar', True),
            'readonly': Eval('baz', True),
            },
        depends=['quux'])
    bar = fields.Boolean("Bar")
    baz = fields.Boolean("Baz")
    quux = fields.Char("Quux")


class ModelViewAutocomplete(ModelView):
    __name__ = 'test.modelview.autocomplete'

    name = fields.Char("Name")


class ModelViewAutocompleteStorage(ModelSQL, ModelViewAutocomplete):
    __name__ = 'test.modelview.autocomplete.storage'


def register(module):
    Pool.register(
        ModelViewChangedValues,
        ModelViewChangedValuesDictSchema,
        ModelViewChangedValuesTarget,
        ModelViewChangedValuesStoredTarget,
        ModelViewStoredChangedValues,
        ModelViewStoredChangedValuesTarget,
        ModelViewButton,
        ModelViewButtonDepends,
        ModelViewButtonAction,
        ModelViewButtonChange,
        ModelViewLink,
        ModelViewLinkTarget,
        ModelViewRPC,
        ModelViewEmptyPage,
        ModelViewEmptyPageAccess,
        ModelViewCircularDepends,
        ModeViewDependsDepends,
        ModelViewViewAttributes,
        ModelViewViewAttributesDepends,
        ModelViewStatesDepends,
        ModelViewAutocomplete,
        ModelViewAutocompleteStorage,
        module=module, type_='model')
