'''rapi model template'''

from inc_noesis import *
import noesis
import rapi
import struct

def registerNoesisTypes():
    '''Register the plugin. Just change the Game name and extension.'''
    
    handle = noesis.register("Virtual Cop Elite", ".bin")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel)
    return 1

def noepyCheckType(data):
    '''Verify that the format is supported by this plugin. Default yes'''
    
    return 1

def noepyLoadModel(data, mdlList):
    '''Build the model, set materials, bones, and animations. You do not
    need all of them as long as they are empty lists (they are by default)'''
    
    ctx = rapi.rpgCreateContext()
    parser = ModelParser(data)
    parser.parse_file()
    mdl = rapi.rpgConstructModel()
    mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList))
    mdl.setBones(parser.boneList)
    mdl.setAnims(parser.animList)
    mdlList.append(mdl)
    return 1

class ModelParser(object):
    
    def __init__(self, data):    
        '''Initialize some data'''
        
        self.inFile = NoeBitStream(data)
        self.meshList = []
        self.uvList = []
        self.normList = []
        self.vertList = []
        self.idxList = []
        self.animList = []
        self.texList = []
        self.matList = []
        self.boneList = []
        
    def parse_file(self):
        '''Main parser method'''
        
    def read_name(self):
            
            return noeStrFromBytes(self.inFile.readBytes(12))
        
    def parse_vertices(self, numVerts):
        
        positions = self.inFile.readBytes(numVerts*16)
        normals = self.inFile.readBytes(numVerts*16)
        uvs = self.inFile.readBytes(numVerts*16)
        unk = self.inFile.readBytes(numVerts*16)
        
        idxBuff = []
        for i in range(numVerts - 2):
            idxBuff.append(i)
            idxBuff.append(i+1)
            idxBuff.append(i+2)
            
        idxStrip = rapi.createTriStrip(idxBuff)
        buff = bytes()
        for idx in idxStrip:
            buff += struct.pack("L", idx)
        
        rapi.rpgBindPositionBufferOfs(positions, noesis.RPGEODATA_FLOAT, 16, 0)
        rapi.rpgCommitTriangles(buff, noesis.RPGEODATA_UINT, numVerts, noesis.RPGEO_TRIANGLE_STRIP, 1)
        
        rapi.rpgClearBufferBinds()
        
    def parse_file(self):
        '''Main parser method'''
        
        self.inFile.read('4L')
        for i in range(3):
            self.read_name()
            self.inFile.readUInt()
        self.read_name()
        self.inFile.readBytes(404)
        
        for i in range(180): #3000 is near the upper limit
            unk1, unk2, unk3, numVerts = self.inFile.read('4L')
            #print(unk1, unk2, unk3, numVerts, self.inFile.tell())
            if numVerts == 0 or unk2 // numVerts != 16:
                self.inFile.seek(32, 1)
            else:
                self.parse_vertices(numVerts)