# (C) Copyright 2004-2021 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!

#-------------------------------------------------------------------------
#  Imports:
#-------------------------------------------------------------------------

from traits.api \
    import HasStrictTraits, Str, Int, Regex, List, Instance

from traitsui.api \
    import View, Group, Item, TableEditor, EnumEditor

from traitsui.table_column \
    import ObjectColumn

from traitsui.table_filter \
    import TableFilter, RuleTableFilter, RuleFilterTemplate, \
    MenuFilterTemplate, EvalFilterTemplate

#-------------------------------------------------------------------------
#  'Person' class:
#-------------------------------------------------------------------------


class Person(HasStrictTraits):

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    name = Str()
    age = Int()
    phone = Regex(value='000-0000', regex='\d\d\d[-]\d\d\d\d')
    state = Str()

    #-------------------------------------------------------------------------
    #  Traits view definition:
    #-------------------------------------------------------------------------

    traits_view = View('name', 'age', 'phone', 'state',
                       title='Create new person',
                       width=0.18,
                       buttons=['OK', 'Cancel'])

#-------------------------------------------------------------------------
#  Sample data:
#-------------------------------------------------------------------------

people = [
    Person(name='Dave', age=39, phone='555-1212'),
    Person(name='Mike', age=28, phone='555-3526'),
    Person(name='Joe', age=34, phone='555-6943'),
    Person(name='Tom', age=22, phone='555-7586'),
    Person(name='Dick', age=63, phone='555-3895'),
    Person(name='Harry', age=46, phone='555-3285'),
    Person(name='Sally', age=43, phone='555-8797'),
    Person(name='Fields', age=31, phone='555-3547')
]

#-------------------------------------------------------------------------
#  'AgeFilter' class:
#-------------------------------------------------------------------------


class AgeFilter(TableFilter):

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    name = "Age filter"
    _name = "Age filter"

    age = Int(0)

    #-------------------------------------------------------------------------
    #  Traits view definitions:
    #-------------------------------------------------------------------------

    #filter_view = Group( 'age{Age >=}' )

    #-------------------------------------------------------------------------
    #  Returns whether an object passes the filter or not:
    #-------------------------------------------------------------------------

    def filter(self, person):
        """ Returns whether an object passes the filter or not.
        """
        return (person.age >= self.age)

    #-------------------------------------------------------------------------
    #  Returns a user readable description of what the filter does:
    #-------------------------------------------------------------------------

    def description(self):
        """ Returns a user readable description of what the filter does.
        """
        return 'Age >= %d' % self.age

    def _age_changed(self, old, new):
        self.name = self.description()
        print('AgeFilter _age_changed', self.name)

#-------------------------------------------------------------------------
#  'NameFilter' class:
#-------------------------------------------------------------------------


class NameFilter(TableFilter):

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    mname = Str()

    #-------------------------------------------------------------------------
    #  Traits view definitions:
    #-------------------------------------------------------------------------

    filter_view = Group('mname{Name contains}')

    #-------------------------------------------------------------------------
    #  Returns whether an object passes the filter or not:
    #-------------------------------------------------------------------------

    def filter(self, person):
        """ Returns whether an object passes the filter or not.
        """
        return (person.name.lower().find(self.mname.lower()) >= 0)

    #-------------------------------------------------------------------------
    #  Returns a user readable description of what the filter does:
    #-------------------------------------------------------------------------

    def description(self):
        """ Returns a user readable description of what the filter does.
        """
        return "Name contains '%s'" % self.mname

#-------------------------------------------------------------------------
#  Table editor definition:
#-------------------------------------------------------------------------

filters = [
    AgeFilter(
        age=30),
    NameFilter(
        mname='d'),
    EvalFilterTemplate,
    MenuFilterTemplate,
    RuleFilterTemplate,
]


def evaluate_value(v):
    print('evaluate_value', v)
    return str(v)
#-------------------------------------------------------------------------
#  'TableTest' class:
#-------------------------------------------------------------------------


class TableTest(HasStrictTraits):

    #-------------------------------------------------------------------------
    #  Trait definitions:
    #-------------------------------------------------------------------------

    #people = Instance( Person )
    people = List(Person)

    #-------------------------------------------------------------------------
    #  Traits view definitions:
    #-------------------------------------------------------------------------

    _valid_states = List(["AL", "AR", "AZ", "AK"])

    _state_editor = EnumEditor(
        name="_valid_states",
        evaluate=evaluate_value,
        object='table_editor_object'
    )

    table_editor = TableEditor(
        columns=[ObjectColumn(name='name'),
                 ObjectColumn(name='age'),
                 ObjectColumn(name='phone'),
                 ObjectColumn(name='state',
                              editor=_state_editor), ],
        editable=True,
        deletable=True,
        sortable=True,
        sort_model=True,
        show_lines=True,
        orientation='vertical',
        show_column_labels=True,
        edit_view=View(['name', 'age', 'phone', 'state', '|[]'],
                       resizable=True),
        filter=None,
        filters=filters,
        row_factory=Person
    )

    traits_view = View(
        [Item('people',
              id='people',
              editor=table_editor),
         '|[]<>'],
        title='Table Editor Test',
        id='traitsui.tests.table_editor_test',
        dock='horizontal',
        width=.4,
        height=.3,
        resizable=True,
        kind='live')


#-------------------------------------------------------------------------
#  Run the tests:
#-------------------------------------------------------------------------

if __name__ == '__main__':
    tt = TableTest(people=people)
    tt.configure_traits()
    for p in tt.people:
        p.print_traits()
        print('--------------')
