#=============================================================================
#
#  Copyright (c) Kitware, Inc.
#  All rights reserved.
#  See LICENSE.txt for details.
#
#  This software is distributed WITHOUT ANY WARRANTY; without even
#  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
#  PURPOSE.  See the above copyright notice for more information.
#
#=============================================================================
"""
Manual port of SMTK/smtk/attribute/Testing/basicAttributeDerivationTest.cxx
For verifying python-shiboken wrappers

Requires smtkCorePython.so to be in module path
"""

import smtk
from smtk import attribute
from smtk import model

itemNames = ["IntComp1", "IntComp2", "DoubleComp1",
             "DoubleComp2", "StringComp1", "StringComp2",
             "ModelComp1_FACE", "ModelComp2_GROUP"]

if __name__ == '__main__':
    import sys
    import os

    status = 0

    system = smtk.attribute.System.create()
    print 'System created'
    base = system.createDefinition("BaseDef")

    # Lets add some item definitions
    icompdef = smtk.attribute.IntItemDefinition.New(itemNames[0])
    itemdef = smtk.attribute.IntItemDefinition.ToItemDefinition(icompdef)
    base.addItemDefinition(itemdef)
    icompdef2 = smtk.attribute.IntItemDefinition.New(itemNames[1])
    icompdef2.setDefaultValue(10)
    itemdef2 = smtk.attribute.IntItemDefinition.ToItemDefinition(icompdef2)
    base.addItemDefinition(itemdef2)

    def1 = system.createDefinition('Derived1', 'BaseDef')
    # Lets add some item definitions
    dcompdef = smtk.attribute.DoubleItemDefinition.New(itemNames[2])
    itemdef = smtk.attribute.DoubleItemDefinition.ToItemDefinition(dcompdef)
    def1.addItemDefinition(itemdef)
    dcompdef2 = smtk.attribute.DoubleItemDefinition.New(itemNames[3])
    dcompdef2.setDefaultValue(-35.2)
    itemdef2 = smtk.attribute.DoubleItemDefinition.ToItemDefinition(dcompdef2)
    def1.addItemDefinition(itemdef2)

    def2 = system.createDefinition('Derived2', 'Derived1')
    # Lets add some item definitions
    scompdef = smtk.attribute.StringItemDefinition.New(itemNames[4])
    itemdef = smtk.attribute.StringItemDefinition.ToItemDefinition(scompdef)
    def2.addItemDefinition(itemdef)
    scompdef2 = smtk.attribute.StringItemDefinition.New(itemNames[5])
    scompdef2.setDefaultValue('Default')
    itemdef2 = smtk.attribute.StringItemDefinition.ToItemDefinition(scompdef2)
    def2.addItemDefinition(itemdef2)

    def3 = system.createDefinition('Derived3', 'Derived1')
    # Lets add some item definitions
    scompdef = smtk.attribute.ModelEntityItemDefinition.New(itemNames[6])
    scompdef.setMembershipMask(int(smtk.model.FACE))
    # Need to set this or numberOfRequiredValues
    scompdef.setIsExtensible(True)
    itemdef = smtk.attribute.ModelEntityItemDefinition.ToItemDefinition(
        scompdef)
    def3.addItemDefinition(itemdef)
    scompdef3 = smtk.attribute.ModelEntityItemDefinition.New(itemNames[7])
    scompdef3.setMembershipMask(int(
        smtk.model.CELL_ENTITY | smtk.model.GROUP_ENTITY | smtk.model.HOMOGENOUS_GROUP))
    # Need to set this or numberOfRequiredValues
    scompdef3.setIsExtensible(True)
    itemdef3 = smtk.attribute.ModelEntityItemDefinition.ToItemDefinition(
        scompdef3)
    def3.addItemDefinition(itemdef3)

    # Lets test out the find item position method
    pstatus = 0
    for j in range(0, 6):
        if (def2.findItemPosition(itemNames[j]) != j):
            print "Incorrect Position Returned for %s, position returned is %d, but it should be %d\n" % (itemNames[j], def2.findItemPosition(itemNames[j]), j)
            pstatus = -1
    if pstatus == 0:
        print "Initial Position Test Passed!\n"
    else:
        print "Initial Position Test Failed!\n"
        status = -1

    # Lets add a  component to the base def and verify that positions are
    # reordered
    stringItemDefinition = smtk.attribute.StringItemDefinition.New(
        "InsertStringItem")
    base.addItemDefinition(stringItemDefinition)
    pstatus = 0
    for j in range(2, 6):
        if def2.findItemPosition(itemNames[j]) != (j + 1):
            print "Incorrect Position Returned for %s, position returned is %d, but it should be %d\n" % (itemNames[j], def2.findItemPosition(itemNames[j]), j + 1)
            pstatus = -1

    if pstatus == 0:
        print "Insertion Position Test Passed!\n"
    else:
        print "Insertion Position Test Failed!\n"
        status = -1

    att = system.createAttribute('testAtt', 'Derived2')
    if not att is None:
        print 'Attribute testAtt created'
    else:
        print 'ERROR: Attribute testAtt not created'
        status = -1
    comp = att.find("DoubleComp1")
    if not comp is None:
        vvcomp = smtk.attribute.ValueItem.CastTo(comp)
        print " Value = %s" % vvcomp.valueAsString()
    else:
        print "ERROR: could not find the base's item"
        status = -1

    n = att.numberOfItems()
    for i in range(n):
        comp = att.item(i)
        print '\t%s Type = %s, ' % (comp.name(),
                                    smtk.attribute.Item.type2String(
                                        comp.type())),
        vcomp = smtk.attribute.ValueItem.CastTo(comp)
        if vcomp:
            if vcomp.type() == smtk.attribute.Item.DOUBLE:
                print ' Value = %s' % vcomp.valueAsString()
            elif vcomp.type() == smtk.attribute.Item.INT:
                print ' Value = %s' % vcomp.valueAsString()
            elif vcomp.type() == smtk.attribute.Item.STRING:
                print 'String Val = %s' % vcomp.valueAsString()
        else:
            ecomp = smtk.attribute.ModelEntityItem.CastTo(comp)
            if ecomp:
                if ecomp.type() == smtk.attribute.Item.MODEL_ENTITY:
                    print ' Value = %s' % ecomp.valueAsString()
            else:
                print comp

    # ======
    # Now test setting entity-valued attribute-items
    # I. Create a model manager and add some entities to it:
    mmgr = smtk.model.Manager.create()
    system.setRefModelManager(mmgr)
    mdl = mmgr.addModel(3, 3, 'TestModel')
    edg = mmgr.addEdge()
    fac = mmgr.addFace()
    gr0 = mmgr.addGroup(smtk.model.HOMOGENOUS_GROUP, 'GroupA')
    gr1 = mmgr.addGroup(smtk.model.PARTITION, 'GroupB')
    gr0.addEntity(fac)
    gr1.addEntity(edg)

    # II. Have the attribute system create an attribute with model-entity
    att = system.createAttribute('testMEAtt', 'Derived3')
    if not att is None:
        print 'Attribute testMEAtt created'
    else:
        print 'ERROR: Attribute testMEAtt not created'
        status = -1
    # III. Find the face-only attribute item and try fuzzing its arguments a
    # bit
    comp = att.find("ModelComp1_FACE")
    if not comp is None:
        print comp
        fcomp = smtk.attribute.ModelEntityItem.CastTo(comp)
        print fcomp
        print dir(fcomp)
        if fcomp.appendValue(edg):
            print 'ERROR: Face-only attribute value accepted an edge'
            status = -1
        if not fcomp.appendValue(fac):
            print 'ERROR: Face-only attribute value did not accept a face'
            status = -1
        print " Value = %s" % fcomp.valueAsString()
    else:
        print "ERROR: could not find the base's item"
        status = -1
    # IV. Find the homogenous-group-only attribute item and try fuzzing its
    # arguments a bit
    comp = att.find("ModelComp2_GROUP")
    if not comp is None:
        gcomp = smtk.attribute.ModelEntityItem.CastTo(comp)
        if not gcomp.appendValue(gr0):
            print 'ERROR: Homogenous-group-only attribute value did not accept a homogenous group'
            status = -1
        if gcomp.appendValue(gr1):
            print 'ERROR: Homogenous-group-only attribute value accepted a more relaxed group'
            status = -1
        print " Value = %s" % gcomp.valueAsString()
    else:
        print "ERROR: could not find the base's item"
        status = -1

    n = att.numberOfItems()
    for i in range(n):
        comp = att.item(i)
        print '\t%s Type = %s, ' % (comp.name(),
                                    smtk.attribute.Item.type2String(
                                        comp.type())),
        vcomp = smtk.attribute.ValueItem.CastTo(comp)
        if vcomp:
            if vcomp.type() == smtk.attribute.Item.DOUBLE:
                print ' Value = %s' % vcomp.valueAsString()
            elif vcomp.type() == smtk.attribute.Item.INT:
                print ' Value = %s' % vcomp.valueAsString()
            elif vcomp.type() == smtk.attribute.Item.STRING:
                print 'String Val = %s' % vcomp.valueAsString()
        else:
            ecomp = smtk.attribute.ModelEntityItem.CastTo(comp)
            if ecomp:
                if ecomp.type() == smtk.attribute.Item.MODEL_ENTITY:
                    print ' Value = %s' % ecomp.valueAsString()
            else:
                print comp
    # ======

    del system
    print 'System destroyed'

    sys.exit(status)
