#by Durik256
from inc_noesis import *

def registerNoesisTypes():
    handle = noesis.register("Football Superstars", ".jiggy")
    noesis.setHandlerTypeCheck(handle, CheckType)
    noesis.setHandlerLoadModel(handle, LoadModel)    
    return 1
    
def CheckType(data):
    if data[:9] != b'_GUID_ID_':
        return 0
    return 1
    
def LoadModel(data, mdlList):
    global bs, bones, anims
    bs = NoeBitStream(data)
    
    KeyFrameAnimData_offsets = data.find(b'_GUID_ID_')
    
    
    bones, anims = [], []
    bs.seek(KeyFrameAnimData_offsets)
    parseANIMS()
    #bs.seek(949)
    #KeyFrameAnimData()
    
    mdl = NoeModel()
    mdl.setBones(bones)
    mdl.setAnims(anims)
    mdlList.append(mdl)
    rapi.setPreviewOption("setAngOfs", "0 90 0")
    return 1
    
def parseANIMS():
    bs.seek(9,1)#_GUID_ID_  36478
    bs.seek(bs.readUInt(),1)#ID 16 bytes

    root = readLabel(bs)
    print('root:', root)
    if root != 'KeyFrameAnimData':
        return 0
    
    global numNode, _exec
    numNode, _exec = bs.readUInt(), ''
    unk0 = bs.readUInt()
    
    for x in range(numNode):
        readNode(bs, x)

    print(_exec)
    globals_dict = {'readLabel': readLabel, 'bs': bs, 'NoeVec3':NoeVec3}
    exec(_exec, globals_dict)
    #print(globals_dict)
    _anm = globals_dict['KeyFrameAnimData']()
    print(bs.tell())

    CreateAnim(_anm)

def readLabel(bs):
    lenght = bs.readUInt()
    if lenght:
        lenght += 1
    return noeStrFromBytes(bs.read(lenght))

def readNode(bs, curIndex):
    global numNode, _exec
    print(curIndex,'Node>>>>>>')
    label = readLabel(bs)
    print('label:',label)
    _exec += 'class %s:\n'%label#print('class %s:\n'%label)
    _exec += '    def __init__(self):\n'#print('    def __init__(self):\n')
    childCount = bs.readUInt()
    print('    childCount:', childCount)
    
    for x in range(childCount):
        readChild(bs)
    if curIndex != numNode - 1:
        array = bs.readUInt()
        print('    array:', array)
    end = bs.readUByte()
    print('    end:', end)
    _exec += '\n'#print('\n')

def readChild(bs):
    global _exec
    label = readLabel(bs)
    print('    ChildNode>>>>>>')
    
    print('        label:', label)
    types = {0:'None', 1:'bs.readInt()', 2:'bs.readUInt()', 3:'bs.readFloat()', 4:'NoeVec3([bs.readFloat(),bs.readFloat(),0])', 5:'NoeVec3.fromBytes(bs.read(12))', 7:'readLabel(bs)',8:'"cxmodel"'}
    type = bs.readUInt()
    print('        type:', type)
    _value = ''
    if type == 9:
        struct_label = readLabel(bs)
        _value = struct_label + '()'
        print('            struct_label:', struct_label)
    else:
        _value = types[type]
    
    array = bs.readUInt()
    if array:
        _exec += '        self.num_%s = bs.readUInt()\n'%label#print('        self.num_%s = bs.readUInt()\n'%label)
        _exec += '        self.%s = []\n'%label#print('        self.%s = []\n'%label)
        _exec += '        for x in range(self.num_%s):\n'%label#print('        for x in range(num_%s):\n'%label)
        _exec += '            self.%s.append(%s)\n'%(label, _value)#print('            %s.append(%s)\n'%(label, _value))
    
    else:
        _exec += '        self.%s = %s\n'%(label, _value)#print('        self.%s = %s\n'%(label, _value))
    
    print('        array:', array)
    end = bs.readUByte()
    print('        end:', end)
    if end == 0:
        unk = bs.readUInt()
        print('        unk:', unk)
        if unk == 1:
            unk2 = bs.readUInt()
            print('        unk2:', unk2)

def CreateAnim(_anm):
    name = _anm.header.sourceFile
    print('header_sourceFile:', name)
    rate = _anm.header.sampleRate
    print('header_sampleRate:', rate)
    print('header_playbackRate:', _anm.header.playbackRate)
    print('num_streams:', _anm.num_streams)
    print('segments:', _anm.segments)
    
    animBones = []
    for stream in _anm.streams:
        bone_name = stream.bone
        print('    stream.bone:', bone_name)
        rotList = []
        posList = []
        sclList = []
        
        #print('    stream.num_orientationFrames:', stream.num_orientationFrames)
        for x in stream.orientationFrames:
            time = x.time
            v = x.orientation.v
            s = x.orientation.s
            rotList.append(NoeKeyFramedValue(time, NoeQuat([v[0], v[1], v[2], s]).transpose()))
        
        #print('    stream.num_translationFrames:', stream.num_translationFrames)
        for x in stream.translationFrames:
            time = x.time
            pos = x.translation
            posList.append(NoeKeyFramedValue(time, pos))
        
        #print('    stream.num_scaleFrames:', stream.num_scaleFrames)
        for x in stream.scaleFrames:
            time = x.time
            scl = x.scale
            sclList.append(NoeKeyFramedValue(time, scl))
        
        parent = stream.parentIndex
        #print('    stream.parentIndex:', parent)
        
        id = len(bones)
        bones.append(NoeBone(id,bone_name,NoeMat43(),None,parent))
        
        keyBone = NoeKeyFramedBone(id)
        keyBone.setRotation(rotList)
        keyBone.setTranslation(posList)
        keyBone.setScale(sclList, noesis.NOEKF_SCALE_VECTOR_3)
        animBones.append(keyBone)
    
    anim = NoeKeyFramedAnim('anim_0', bones, animBones, rate)
    anims.append(anim)