
import os
import sys
import struct

import nrfile


class GeometryLoadMode:
    PreVs_Auto   = 1    # Attribute calculated in importer
    PreVs_Manual = 2
    PostVs       = 3    # Projection Matrix(Inversed)


class TextureLoadMode:
    Auto          = 0  # uAttrIdx/uCompIdx and vAttrIdx/vCompIdx  calculated in importer
    AttributeName = 1
    AttributeIndex= 2


class NormalsLoadMode:
    Disabled = 0
    Auto     = 1
    Manual   = 2


class ImportOptions(object):
    def __init__(self):
        self.geometryLoadMode = GeometryLoadMode.PostVs
        # PostVS position reconstruction
        # 45.0/1024/768/0.01/1000
        self.projMat = [[1.8106601717798212, 0.0, 0.0, 0.0], [0.0, 2.414213562373095, 0.0, 0.0], [0.0, 0.0, 1.000010000100001, 1.0], [0.0, 0.0, -0.01000010000100001, 0.0]]
        # PreVS position
        self.prevs_xAttrIdx = 0
        self.prevs_yAttrIdx = 0
        self.prevs_zAttrIdx = 0
        self.prevs_xCompIdx = 0
        self.prevs_yCompIdx = 1
        self.prevs_zCompIdx = 2
        ##########################################################################
        # Texture-UV reconstruction
        self.textureLoadMode = TextureLoadMode.AttributeName
        self.loadExtraUvData = False  # World--> Local   Local-->World
        # ATTRNAME
        self.texAttrName_attribName = 'TEXCOORD'
        self.texAttrName_uCompIdx = 0
        self.texAttrName_vCompIdx = 1
        self.texAttrName_uvIdx    = 0
        # ATTRINDEX
        self.texAttrIdx_uAttribIdx= 1
        self.texAttrIdx_vAttribIdx= 1
        self.texAttrIdx_uCompIdx  = 0
        self.texAttrIdx_vCompIdx  = 1
        ##########################################################################
        # Normals restore params
        self.normalsMode = NormalsLoadMode.Disabled
        self.normal_xAttrIdx = 2
        self.normal_yAttrIdx = 2
        self.normal_zAttrIdx = 2
        self.normal_xCompIdx = 0
        self.normal_yCompIdx = 1
        self.normal_zCompIdx = 2
        ##########################################################################
        # Vertex Colors restore params


    def dump(self):
        if GeometryLoadMode.PostVs == self.geometryLoadMode:
            print("POSTVS: projMat: {:s}".format(str(self.projMat)))
        elif GeometryLoadMode.PreVs_Manual == self.geometryLoadMode:
            print("PREVS: xAttrIdx={:d} yAttrIdx={:d} zAttrIdx={:d}   xCompIdx={:d} yCompIdx={:d} zCompIdx={:d}".format(self.prevs_xAttrIdx, self.prevs_yAttrIdx, self.prevs_zAttrIdx, self.prevs_xCompIdx, self.prevs_yCompIdx, self.prevs_zCompIdx))
        elif GeometryLoadMode.PreVs_Auto == self.geometryLoadMode:
            print("PREVS: Auto")

        if self.loadExtraUvData:
            print("loadExtraUvData=True")
        else:
            print("loadExtraUvData=False")

        if TextureLoadMode.Auto == self.textureLoadMode:
            print("TexMode: Auto")
        elif TextureLoadMode.AttributeName == self.textureLoadMode:
            print("TexMode: attribName: {:s} uCompIdx={:d} vCompIdx={:d} uvIdx={:d}".format(self.texAttrName_attribName, self.texAttrName_uCompIdx, self.texAttrName_vCompIdx, self.texAttrName_uvIdx))
        elif TextureLoadMode.AttributeIndex == self.textureLoadMode:
            print("TexMode: uAttribIdx={:d} vAttribIdx={:d} uCompIdx={:d} vCompIdx={:d}".format(self.texAttrIdx_uAttribIdx, self.texAttrIdx_vAttribIdx, self.texAttrIdx_uCompIdx, self.texAttrIdx_vCompIdx))



# UnrealEngine PreVs Layout
#ATTRIBUTE: x=0.588235 y=0.113725 z=0.803922 w=0.501961   Normal
#ATTRIBUTE: x=0.701961 y=0.811765 z=0.831373 w=1          Normal
#ATTRIBUTE: x=72.4522 y=2.471 z=151.232                   Position
#ATTRIBUTE: x=0.195679 y=0.789551                         Texcoord0
#ATTRIBUTE: x=0.195679 y=0.789551 
#ATTRIBUTE: x=0.195679 y=0.789551 
#ATTRIBUTE: x=0.195679 y=0.789551 
#ATTRIBUTE: x=1 y=1 z=1 w=1 
#ATTRIBUTE: x=0 y=1 z=0 w=0 
#ATTRIBUTE: x=0 y=0 z=0 w=0 
#ATTRIBUTE: x=0.941176 y=0.0588235 z=0 w=0 
#ATTRIBUTE: x=0 y=0 z=0 w=0 


def isUnrealEngineVertexLayout(vatrs):
    for idx in range(0, vatrs.getAttribsCount()):
        attr = vatrs.getAttr(idx)
        if attr.semantic.lower() != 'attribute':
            return False
    return True


# AUTO Geometry Detection
# Return [ [xatrIdx, xcompIdx], [yatrIdx, ycompIdx], [zatrIdx, zcompIdx] ]
def createPreVsAuto(vatrs):
    # Try 'POSITION' semantic
    for idx in range(0, vatrs.getAttribsCount()):
        attr = vatrs.getAttr(idx)
        if attr.semantic.lower() == 'position':
            return [[idx, 0], [idx, 1], [idx, 2]]

    # Try ATTRIBUTE semantic (Unreal Engine)
    for idx in range(0, vatrs.getAttribsCount()):
        attr = vatrs.getAttr(idx)
        if attr.semantic.lower() == 'attribute' and (3 == attr.compCount):
            return [[idx, 0], [idx, 1], [idx, 2]]

    return [[0,0], [0,1], [0,2]]




# AUTO Texcoord Detection
class TexCoordAttrComp(object):
    def __init__(self):
        self.uAttrIdx = 0
        self.uCompIdx = 0

        self.vAttrIdx = 0
        self.vCompIdx = 1


def createTexCoordAuto(vatrs):
    res = []
    for idx in range(0, vatrs.getAttribsCount()):
        attr = vatrs.getAttr(idx)
        if attr.semantic.lower() == 'texcoord':
            tc = TexCoordAttrComp()
            tc.uAttrIdx = idx
            tc.vAttrIdx = idx
            tc.uCompIdx = 0
            tc.vCompIdx = 1
            res.append(tc)
    if 0 == len(res):
        if isUnrealEngineVertexLayout(vatrs):
            # UnrealEngine
            for idx in range(0, vatrs.getAttribsCount()):
                attr = vatrs.getAttr(idx)
                if (attr.semantic.lower() == 'attribute') and (2 == attr.compCount):
                    tc = TexCoordAttrComp()
                    tc.uAttrIdx = idx
                    tc.vAttrIdx = idx
                    tc.uCompIdx = 0
                    tc.vCompIdx = 1
                    res.append(tc)
        else:
            # TEXCOORD/ATTRIBUTE semantic not found. Using all attributes
            for idx in range(0, vatrs.getAttribsCount()):
                attr = vatrs.getAttr(idx)
                if attr.compCount > 1:
                    tc = TexCoordAttrComp()
                    tc.uAttrIdx = idx
                    tc.vAttrIdx = idx
                    tc.uCompIdx = 0
                    tc.vCompIdx = 1
                    res.append(tc)
    return res


def createTexCoordAttributeIndex(vatrs, options):
    res = []
    tc = TexCoordAttrComp()

    tc.uAttrIdx = options.texAttrIdx_uAttribIdx
    tc.vAttrIdx = options.texAttrIdx_vAttribIdx
    tc.uCompIdx = options.texAttrIdx_uCompIdx
    tc.vCompIdx = options.texAttrIdx_vCompIdx

    res.append(tc)
    return res


def createTexCoordAttributeName(vatrs, options):
    res = []
    tc = TexCoordAttrComp()

    for idx in range(0, vatrs.getAttribsCount()):
        attr = vatrs.getAttr(idx)
        if attr.semantic.lower() == options.texAttrName_attribName.lower():
            tc = TexCoordAttrComp()
            tc.uAttrIdx = idx
            tc.vAttrIdx = idx
            tc.uCompIdx = options.texAttrName_uCompIdx
            tc.vCompIdx = options.texAttrName_vCompIdx
            res.append(tc)

    res.append(tc)
    return res
