"""Subclass of IsClassMethods, which is generated by wxFormBuilder."""

import wxx
from activity.models.ui import ui as ui
from app.utils import cached_type
import model


# Implementing IsClassMethods
class IsClassMethods(ui.IsClassMethods):
    """
    This dialog allows to add/remove is_class methods.
    """
    @wxx.SetInfo(__doc__)
    def __init__(self, parent, container):
        """Dialog initialization"""
        super(IsClassMethods, self).__init__(parent)
        # container es la clase base
        self.container = container
        # create a map of feasible casts
        self._classes = []
        for k in container._deriv:
            self.visit(k)
        # get current methods
        self._is_class_methods = container(model.cc.IsClassMethod)
        # create map from names to implementations
        self._is_class_method_names = dict([(x._name, x) for x in self._is_class_methods])
        # create map from feasible is_class to current impl
        self._map = {}
        for k in self._classes:
            name = k.scoped
            name = "is_" + name.replace('::', '_')
            if name in self._is_class_method_names:
                self._map[name] = (k, self._is_class_method_names[name])
            else:
                self._map[name] = (k, None)
        # do a label insertion remembering state
        pos = 0
        for k in self._map:
            v = self._map[k]
            self.m_checkList2.Insert(k, pos, v)
            if v[1]:
                self.m_checkList2.Check(pos)
            pos = pos + 1

    def visit(self, k):
        """Add inheritance branch"""
        for l in k._deriv:
            self.visit(l)
        self._classes.append(k)

    def get_kwargs(self):
        """Returns kwargs dictionary suitable for objects creation"""
        kwargs_list = []
        tbool = cached_type(self.container.project, 'bool')
        for item in range(0, self.m_checkList2.GetCount()):
            v = self.m_checkList2.GetClientData(item)
            c = self.m_checkList2.IsChecked(item)
            if  (c and v[1]) or (not c and not v[1]):
                continue
            if c:
                kwargs = {}
                derivative = v[0]
                kwargs['parent'] = self.container
                kwargs['name'] = 'is_' + derivative.scoped.replace('::', '_')
                kwargs['type'] = model.cc.typeinst(
                        type=tbool, const=True)
                kwargs['constmethod'] = True
                kwargs['note'] = 'This method checks if the instance is specialized as {}'.format(derivative.GetFullLabel())
                kwargs['declare'] = True
                kwargs['implement'] = True
                kwargs['content'] = '\treturn ( dynamic_cast<const {}*>(this) != nullptr );'.format(name)
                kwargs_list.append(kwargs)
            else:
                v[1].Delete()
        return kwargs_list
