from inc_noesis import *
import noesis
import rapi
from Sanae3D.Sanae import SanaeObject

def registerNoesisTypes():
    '''Register the plugin. Just change the Game name and extension.'''
    
    handle = noesis.register("Dragon Nest", ".msh")
    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 = SanaeParser(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 SanaeParser(SanaeObject):
    
    def __init__(self, data):    
        '''Initialize some data. Refer to Sanae.py to see what is already
        initialized'''
        
        super(SanaeParser, self).__init__(data)
        self.hasBones = True
        
    def read_name(self):
        
        return noeStrFromBytes(self.inFile.readBytes(256))
    
    def parse_bones(self, numBones):
        
        for i in range(numBones):
            boneName = self.read_name()
            matrix = self.inFile.readBytes(64)
            
    def parse_faces(self, numIdx):
        
        return self.inFile.readBytes(numIdx * 2)
    
    def parse_vertices(self, numVerts):

        positions = self.inFile.readBytes(numVerts * 12)
        normals = self.inFile.readBytes(numVerts * 12)
        uv = self.inFile.readBytes(numVerts * 8)
        
        rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12)
        rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12)
        rapi.rpgBindUV1Buffer(uv, noesis.RPGEODATA_FLOAT, 8)        
        
        if self.hasBones:
            bones = self.inFile.readBytes(numVerts * 8) #4 shorts
            weights = self.inFile.readBytes(numVerts * 16) #4 floats
        
        
        
    def parse_unk(self, count):
        
        for i in range(count):
            self.read_name()
            
    def parse_mesh(self, numMesh):
        
        for i in range(numMesh):
            print(self.inFile.tell())
            self.read_name() #scene root
            meshName = self.read_name()
            rapi.rpgSetName(meshName)
            numVerts, numIdx, unk, unk2 = self.inFile.read('4L')
            print(numVerts, numIdx, unk, unk2, self.hasBones)
            self.inFile.seek(496, 1)
            idxBuff = self.parse_faces(numIdx)
            print(self.inFile.tell())
            self.parse_vertices(numVerts)
    
            texName = meshName + ".dds"
            matName = "material"
            material = NoeMaterial(matName, texName)
            self.matList.append(material)
            
            rapi.rpgSetMaterial(matName)
            if unk == 1:
                rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE_STRIP, 1)
            else:
                rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
        
            if not self.inFile.checkEOF():
                count = self.inFile.readUInt()
                self.parse_unk(count)

    def parse_file(self):
        '''Main parser method'''
        
        idstring = self.read_name()
        version, numMesh, unk1, unk2 = self.inFile.read('4L')
        self.inFile.read('6f')
        numBones = self.inFile.readUInt()
        if not numBones:
            self.hasBones = False
        self.inFile.read('2L')
        
        self.inFile.seek(716, 1)
        self.parse_bones(numBones)
        self.parse_mesh(numMesh)