/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team


All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

/** @file Implementation of the material part of the MDL importer class */


#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER

// internal headers
#include "MDLLoader.h"
#include "MDLDefaultColorMap.h"
#include "StringUtils.h"
#include <assimp/texture.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/Defines.h>
#include "qnan.h"


using namespace Assimp;
static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);

// ------------------------------------------------------------------------------------------------
// Find a suitable pallette file or take the default one
void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
{
    // now try to find the color map in the current directory
    IOStream* pcStream = pIOHandler->Open(configPalette,"rb");

    const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
    if(pcStream)
    {
        if (pcStream->FileSize() >= 768)
        {
            unsigned char* colorMap = new unsigned char[256*3];
            szColorMap = colorMap;
            pcStream->Read(colorMap,256*3,1);
            DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
                "It will be used to decode embedded textures in palletized formats.");
        }
        delete pcStream;
        pcStream = NULL;
    }
    *pszColorMap = szColorMap;
}

// ------------------------------------------------------------------------------------------------
// Free the palette again
void MDLImporter::FreePalette(const unsigned char* szColorMap)
{
    if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
        delete[] szColorMap;
}

// ------------------------------------------------------------------------------------------------
// Check whether we can replace a texture with a single color
aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
{
    ai_assert(NULL != pcTexture);

    aiColor4D clrOut;
    clrOut.r = get_qnan();
    if (!pcTexture->mHeight || !pcTexture->mWidth)
        return clrOut;

    const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
    const aiTexel* pcTexel = pcTexture->pcData+1;
    const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];

    while (pcTexel != pcTexelEnd)
    {
        if (*pcTexel != *(pcTexel-1))
        {
            pcTexel = NULL;
            break;
        }
        ++pcTexel;
    }
    if (pcTexel)
    {
        clrOut.r = pcTexture->pcData->r / 255.0f;
        clrOut.g = pcTexture->pcData->g / 255.0f;
        clrOut.b = pcTexture->pcData->b / 255.0f;
        clrOut.a = pcTexture->pcData->a / 255.0f;
    }
    return clrOut;
}

// ------------------------------------------------------------------------------------------------
// Read a texture from a MDL3 file
void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
{
    const MDL::Header *pcHeader = (const MDL::Header*)mBuffer;  //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function

    VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
        pcHeader->skinheight);

    // allocate a new texture object
    aiTexture* pcNew = new aiTexture();
    pcNew->mWidth = pcHeader->skinwidth;
    pcNew->mHeight = pcHeader->skinheight;

    pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];

    const unsigned char* szColorMap;
    this->SearchPalette(&szColorMap);

    // copy texture data
    for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
    {
        const unsigned char val = szData[i];
        const unsigned char* sz = &szColorMap[val*3];

        pcNew->pcData[i].a = 0xFF;
        pcNew->pcData[i].r = *sz++;
        pcNew->pcData[i].g = *sz++;
        pcNew->pcData[i].b = *sz;
    }

    FreePalette(szColorMap);

    // store the texture
    aiTexture** pc = this->pScene->mTextures;
    this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
    for (unsigned int i = 0; i <pScene->mNumTextures;++i)
        pScene->mTextures[i] = pc[i];

    pScene->mTextures[this->pScene->mNumTextures] = pcNew;
    pScene->mNumTextures++;
    delete[] pc;
    return;
}

// ------------------------------------------------------------------------------------------------
// Read a texture from a MDL4 file
void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
    unsigned int iType,
     unsigned int* piSkip)
{
    ai_assert(NULL != piSkip);

    const MDL::Header *pcHeader = (const MDL::Header*)mBuffer;  //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function

    if (iType == 1 || iType > 3)
    {
        DefaultLogger::get()->error("Unsupported texture file format");
        return;
    }

    const bool bNoRead = *piSkip == UINT_MAX;

    // allocate a new texture object
    aiTexture* pcNew = new aiTexture();
    pcNew->mWidth = pcHeader->skinwidth;
    pcNew->mHeight = pcHeader->skinheight;

    if (bNoRead)pcNew->pcData = bad_texel;
    ParseTextureColorData(szData,iType,piSkip,pcNew);

    // store the texture
    if (!bNoRead)
    {
        if (!this->pScene->mNumTextures)
        {
            pScene->mNumTextures = 1;
            pScene->mTextures = new aiTexture*[1];
            pScene->mTextures[0] = pcNew;
        }
        else
        {
            aiTexture** pc = pScene->mTextures;
            pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
            for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
                pScene->mTextures[i] = pc[i];
            pScene->mTextures[pScene->mNumTextures] = pcNew;
            pScene->mNumTextures++;
            delete[] pc;
        }
    }
    else {
        pcNew->pcData = NULL;
        delete pcNew;
    }
    return;
}

// ------------------------------------------------------------------------------------------------
// Load color data of a texture and convert it to our output format
void MDLImporter::ParseTextureColorData(const unsigned char* szData,
    unsigned int iType,
    unsigned int* piSkip,
    aiTexture* pcNew)
{
    const bool do_read = bad_texel != pcNew->pcData;

    // allocate storage for the texture image
    if (do_read) {
        pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
    }

    // R5G6B5 format (with or without MIPs)
    // ****************************************************************
    if (2 == iType || 10 == iType)
    {
        VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);

        // copy texture data
        unsigned int i;
        if (do_read)
        {
            for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
            {
                MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
                AI_SWAP2(val);

                pcNew->pcData[i].a = 0xFF;
                pcNew->pcData[i].r = (unsigned char)val.b << 3;
                pcNew->pcData[i].g = (unsigned char)val.g << 2;
                pcNew->pcData[i].b = (unsigned char)val.r << 3;
            }
        }
        else i = pcNew->mWidth*pcNew->mHeight;
        *piSkip = i * 2;

        // apply MIP maps
        if (10 == iType)
        {
            *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
            VALIDATE_FILE_SIZE(szData + *piSkip);
        }
    }
    // ARGB4 format (with or without MIPs)
    // ****************************************************************
    else if (3 == iType || 11 == iType)
    {
        VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);

        // copy texture data
        unsigned int i;
        if (do_read)
        {
            for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
            {
                MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
                AI_SWAP2(val);

                pcNew->pcData[i].a = (unsigned char)val.a << 4;
                pcNew->pcData[i].r = (unsigned char)val.r << 4;
                pcNew->pcData[i].g = (unsigned char)val.g << 4;
                pcNew->pcData[i].b = (unsigned char)val.b << 4;
            }
        }
        else i = pcNew->mWidth*pcNew->mHeight;
        *piSkip = i * 2;

        // apply MIP maps
        if (11 == iType)
        {
            *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
            VALIDATE_FILE_SIZE(szData + *piSkip);
        }
    }
    // RGB8 format (with or without MIPs)
    // ****************************************************************
    else if (4 == iType || 12 == iType)
    {
        VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);

        // copy texture data
        unsigned int i;
        if (do_read)
        {
            for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
            {
                const unsigned char* _szData = &szData[i*3];

                pcNew->pcData[i].a = 0xFF;
                pcNew->pcData[i].b = *_szData++;
                pcNew->pcData[i].g = *_szData++;
                pcNew->pcData[i].r = *_szData;
            }
        }
        else i = pcNew->mWidth*pcNew->mHeight;


        // apply MIP maps
        *piSkip = i * 3;
        if (12 == iType)
        {
            *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
            VALIDATE_FILE_SIZE(szData + *piSkip);
        }
    }
    // ARGB8 format (with ir without MIPs)
    // ****************************************************************
    else if (5 == iType || 13 == iType)
    {
        VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);

        // copy texture data
        unsigned int i;
        if (do_read)
        {
            for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
            {
                const unsigned char* _szData = &szData[i*4];

                pcNew->pcData[i].b = *_szData++;
                pcNew->pcData[i].g = *_szData++;
                pcNew->pcData[i].r = *_szData++;
                pcNew->pcData[i].a = *_szData;
            }
        }
        else i = pcNew->mWidth*pcNew->mHeight;

        // apply MIP maps
        *piSkip = i << 2;
        if (13 == iType)
        {
            *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
        }
    }
    // palletized 8 bit texture. As for Quake 1
    // ****************************************************************
    else if (0 == iType)
    {
        VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);

        // copy texture data
        unsigned int i;
        if (do_read)
        {

            const unsigned char* szColorMap;
            SearchPalette(&szColorMap);

            for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
            {
                const unsigned char val = szData[i];
                const unsigned char* sz = &szColorMap[val*3];

                pcNew->pcData[i].a = 0xFF;
                pcNew->pcData[i].r = *sz++;
                pcNew->pcData[i].g = *sz++;
                pcNew->pcData[i].b = *sz;
            }
            this->FreePalette(szColorMap);

        }
        else i = pcNew->mWidth*pcNew->mHeight;
        *piSkip = i;

        // FIXME: Also support for MIP maps?
    }
}

// ------------------------------------------------------------------------------------------------
// Get a texture from a MDL5 file
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
    unsigned int iType,
    unsigned int* piSkip)
{
    ai_assert(NULL != piSkip);
    bool bNoRead = *piSkip == UINT_MAX;

    // allocate a new texture object
    aiTexture* pcNew = new aiTexture();

    VALIDATE_FILE_SIZE(szData+8);

    // first read the size of the texture
    pcNew->mWidth = *((uint32_t*)szData);
    AI_SWAP4(pcNew->mWidth);
    szData += sizeof(uint32_t);

    pcNew->mHeight = *((uint32_t*)szData);
    AI_SWAP4(pcNew->mHeight);
    szData += sizeof(uint32_t);

    if (bNoRead) {
        pcNew->pcData = bad_texel;
    }

    // this should not occur - at least the docs say it shouldn't.
    // however, one can easily try out what MED does if you have
    // a model with a DDS texture and export it to MDL5 ...
    // yeah, it embedds the DDS file.
    if (6 == iType)
    {
        // this is a compressed texture in DDS format
        *piSkip = pcNew->mWidth;
        VALIDATE_FILE_SIZE(szData + *piSkip);

        if (!bNoRead)
        {
            // place a hint and let the application know that this is a DDS file
            pcNew->mHeight = 0;
            pcNew->achFormatHint[0] = 'd';
            pcNew->achFormatHint[1] = 'd';
            pcNew->achFormatHint[2] = 's';
            pcNew->achFormatHint[3] = '\0';

            pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
            ::memcpy(pcNew->pcData,szData,pcNew->mWidth);
        }
    }
    else
    {
        // parse the color data of the texture
        ParseTextureColorData(szData,iType,piSkip,pcNew);
    }
    *piSkip += sizeof(uint32_t) * 2;

    if (!bNoRead)
    {
        // store the texture
        if (!this->pScene->mNumTextures)
        {
            pScene->mNumTextures = 1;
            pScene->mTextures = new aiTexture*[1];
            pScene->mTextures[0] = pcNew;
        }
        else
        {
            aiTexture** pc = pScene->mTextures;
            pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
            for (unsigned int i = 0; i < pScene->mNumTextures;++i)
                this->pScene->mTextures[i] = pc[i];

            pScene->mTextures[pScene->mNumTextures] = pcNew;
            pScene->mNumTextures++;
            delete[] pc;
        }
    }
    else {
        pcNew->pcData = NULL;
        delete pcNew;
    }
    return;
}

// ------------------------------------------------------------------------------------------------
// Get a skin from a MDL7 file - more complex than all other subformats
void MDLImporter::ParseSkinLump_3DGS_MDL7(
    const unsigned char* szCurrent,
    const unsigned char** szCurrentOut,
    aiMaterial* pcMatOut,
    unsigned int iType,
    unsigned int iWidth,
    unsigned int iHeight)
{
    aiTexture* pcNew = nullptr;

    // get the type of the skin
    unsigned int iMasked = (unsigned int)(iType & 0xF);

    if (0x1 ==  iMasked)
    {
        // ***** REFERENCE TO ANOTHER SKIN INDEX *****
        int referrer = (int)iWidth;
        pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
    }
    else if (0x6 == iMasked)
    {
        // ***** EMBEDDED DDS FILE *****
        if (1 != iHeight)
        {
            DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
                "but texture height is not equal to 1, which is not supported by MED");
        }

        pcNew = new aiTexture();
        pcNew->mHeight = 0;
        pcNew->mWidth = iWidth;

        // place a proper format hint
        pcNew->achFormatHint[0] = 'd';
        pcNew->achFormatHint[1] = 'd';
        pcNew->achFormatHint[2] = 's';
        pcNew->achFormatHint[3] = '\0';

        pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
        memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
        szCurrent += iWidth;
    }
    else if (0x7 == iMasked)
    {
        // ***** REFERENCE TO EXTERNAL FILE *****
        if (1 != iHeight)
        {
            DefaultLogger::get()->warn("Found a reference to an external texture, "
                "but texture height is not equal to 1, which is not supported by MED");
        }

        aiString szFile;
        const size_t iLen = strlen((const char*)szCurrent);
        size_t iLen2 = iLen+1;
        iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
        memcpy(szFile.data,(const char*)szCurrent,iLen2);
        szFile.length = iLen;

        szCurrent += iLen2;

        // place this as diffuse texture
        pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
    }
    else if (iMasked || !iType || (iType && iWidth && iHeight))
    {
        pcNew = new aiTexture();
        if (!iHeight || !iWidth)
        {
            DefaultLogger::get()->warn("Found embedded texture, but its width "
                "an height are both 0. Is this a joke?");

            // generate an empty chess pattern
            pcNew->mWidth = pcNew->mHeight = 8;
            pcNew->pcData = new aiTexel[64];
            for (unsigned int x = 0; x < 8;++x)
            {
                for (unsigned int y = 0; y < 8;++y)
                {
                    const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
                        (0 != x % 2 && 0 == y % 2));

                    aiTexel* pc = &pcNew->pcData[y * 8 + x];
                    pc->r = pc->b = pc->g = (bSet?0xFF:0);
                    pc->a = 0xFF;
                }
            }
        }
        else
        {
            // it is a standard color texture. Fill in width and height
            // and call the same function we used for loading MDL5 files

            pcNew->mWidth = iWidth;
            pcNew->mHeight = iHeight;

            unsigned int iSkip = 0;
            ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);

            // skip length of texture data
            szCurrent += iSkip;
        }
    }

    // sometimes there are MDL7 files which have a monochrome
    // texture instead of material colors ... posssible they have
    // been converted to MDL7 from other formats, such as MDL5
    aiColor4D clrTexture;
    if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew);
    else clrTexture.r = get_qnan();

    // check whether a material definition is contained in the skin
    if (iType & AI_MDL7_SKINTYPE_MATERIAL)
    {
        BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
        szCurrent = (unsigned char*)(pcMatIn+1);
        VALIDATE_FILE_SIZE(szCurrent);

        aiColor3D clrTemp;

#define COLOR_MULTIPLY_RGB() \
    if (is_not_qnan(clrTexture.r)) \
        { \
        clrTemp.r *= clrTexture.r; \
        clrTemp.g *= clrTexture.g; \
        clrTemp.b *= clrTexture.b; \
        }

        // read diffuse color
        clrTemp.r = pcMatIn->Diffuse.r;
        AI_SWAP4(clrTemp.r);
        clrTemp.g = pcMatIn->Diffuse.g;
        AI_SWAP4(clrTemp.g);
        clrTemp.b = pcMatIn->Diffuse.b;
        AI_SWAP4(clrTemp.b);
        COLOR_MULTIPLY_RGB();
        pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);

        // read specular color
        clrTemp.r = pcMatIn->Specular.r;
        AI_SWAP4(clrTemp.r);
        clrTemp.g = pcMatIn->Specular.g;
        AI_SWAP4(clrTemp.g);
        clrTemp.b = pcMatIn->Specular.b;
        AI_SWAP4(clrTemp.b);
        COLOR_MULTIPLY_RGB();
        pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);

        // read ambient color
        clrTemp.r = pcMatIn->Ambient.r;
        AI_SWAP4(clrTemp.r);
        clrTemp.g = pcMatIn->Ambient.g;
        AI_SWAP4(clrTemp.g);
        clrTemp.b = pcMatIn->Ambient.b;
        AI_SWAP4(clrTemp.b);
        COLOR_MULTIPLY_RGB();
        pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);

        // read emissive color
        clrTemp.r = pcMatIn->Emissive.r;
        AI_SWAP4(clrTemp.r);
        clrTemp.g = pcMatIn->Emissive.g;
        AI_SWAP4(clrTemp.g);
        clrTemp.b = pcMatIn->Emissive.b;
        AI_SWAP4(clrTemp.b);
        pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);

#undef COLOR_MULITPLY_RGB

        // FIX: Take the opacity from the ambient color.
        // The doc say something else, but it is fact that MED exports the
        // opacity like this .... oh well.
        clrTemp.r = pcMatIn->Ambient.a;
        AI_SWAP4(clrTemp.r);
        if (is_not_qnan(clrTexture.r)) {
            clrTemp.r *= clrTexture.a;
        }
        pcMatOut->AddProperty<ai_real>(&clrTemp.r,1,AI_MATKEY_OPACITY);

        // read phong power
        int iShadingMode = (int)aiShadingMode_Gouraud;
        AI_SWAP4(pcMatIn->Power);
        if (0.0f != pcMatIn->Power)
        {
            iShadingMode = (int)aiShadingMode_Phong;
            // pcMatIn is packed, we can't form pointers to its members
            float power = pcMatIn->Power;
            pcMatOut->AddProperty<float>(&power,1,AI_MATKEY_SHININESS);
        }
        pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
    }
    else if (is_not_qnan(clrTexture.r))
    {
        pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
        pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
    }
    // if the texture could be replaced by a single material color
    // we don't need the texture anymore
    if (is_not_qnan(clrTexture.r))
    {
        delete pcNew;
        pcNew = NULL;
    }

    // If an ASCII effect description (HLSL?) is contained in the file,
    // we can simply ignore it ...
    if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
    {
        VALIDATE_FILE_SIZE(szCurrent);
        int32_t iMe = *((int32_t*)szCurrent);
        AI_SWAP4(iMe);
        szCurrent += sizeof(char) * iMe + sizeof(int32_t);
        VALIDATE_FILE_SIZE(szCurrent);
    }

    // If an embedded texture has been loaded setup the corresponding
    // data structures in the aiScene instance
    if (pcNew && pScene->mNumTextures <= 999)
    {

        // place this as diffuse texture
        char szCurrent[5];
        ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);

        aiString szFile;
        const size_t iLen = strlen((const char*)szCurrent);
        ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
        szFile.length = iLen;

        pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));

        // store the texture
        if (!pScene->mNumTextures)
        {
            pScene->mNumTextures = 1;
            pScene->mTextures = new aiTexture*[1];
            pScene->mTextures[0] = pcNew;
        }
        else
        {
            aiTexture** pc = pScene->mTextures;
            pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
            for (unsigned int i = 0; i < pScene->mNumTextures;++i) {
                pScene->mTextures[i] = pc[i];
            }

            pScene->mTextures[pScene->mNumTextures] = pcNew;
            pScene->mNumTextures++;
            delete[] pc;
        }
    }
    VALIDATE_FILE_SIZE(szCurrent);
    *szCurrentOut = szCurrent;
    if ( nullptr != pcNew ) {
        delete pcNew;
    }
}

// ------------------------------------------------------------------------------------------------
// Skip a skin lump
void MDLImporter::SkipSkinLump_3DGS_MDL7(
    const unsigned char* szCurrent,
    const unsigned char** szCurrentOut,
    unsigned int iType,
    unsigned int iWidth,
    unsigned int iHeight)
{
    // get the type of the skin
    const unsigned int iMasked = (unsigned int)(iType & 0xF);

    if (0x6 == iMasked)
    {
        szCurrent += iWidth;
    }
    if (0x7 == iMasked)
    {
        const size_t iLen = ::strlen((const char*)szCurrent);
        szCurrent += iLen+1;
    }
    else if (iMasked || !iType)
    {
        if (iMasked || !iType || (iType && iWidth && iHeight))
        {
            // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
            // return the size of the color data in bytes in iSkip
            unsigned int iSkip = 0;

            aiTexture tex;
            tex.pcData = bad_texel;
            tex.mHeight = iHeight;
            tex.mWidth = iWidth;
            ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);

            // FIX: Important, otherwise the destructor will crash
            tex.pcData = NULL;

            // skip length of texture data
            szCurrent += iSkip;
        }
    }

    // check whether a material definition is contained in the skin
    if (iType & AI_MDL7_SKINTYPE_MATERIAL)
    {
        BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
        szCurrent = (unsigned char*)(pcMatIn+1);
    }

    // if an ASCII effect description (HLSL?) is contained in the file,
    // we can simply ignore it ...
    if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
    {
        int32_t iMe = *((int32_t*)szCurrent);
        AI_SWAP4(iMe);
        szCurrent += sizeof(char) * iMe + sizeof(int32_t);
    }
    *szCurrentOut = szCurrent;
}

// ------------------------------------------------------------------------------------------------
void MDLImporter::ParseSkinLump_3DGS_MDL7(
    const unsigned char* szCurrent,
    const unsigned char** szCurrentOut,
    std::vector<aiMaterial*>& pcMats)
{
    ai_assert(NULL != szCurrent);
    ai_assert(NULL != szCurrentOut);

    *szCurrentOut = szCurrent;
    BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent;
    AI_SWAP4(pcSkin->width);
    AI_SWAP4(pcSkin->height);
    szCurrent += 12;

    // allocate an output material
    aiMaterial* pcMatOut = new aiMaterial();
    pcMats.push_back(pcMatOut);

    // skip length of file name
    szCurrent += AI_MDL7_MAX_TEXNAMESIZE;

    ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
        pcSkin->typ,pcSkin->width,pcSkin->height);

    // place the name of the skin in the material
    if (pcSkin->texture_name[0])
    {
        // the 0 termination could be there or not - we can't know
        aiString szFile;
        ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
        szFile.data[sizeof(pcSkin->texture_name)] = '\0';
        szFile.length = ::strlen(szFile.data);

        pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
    }
}

#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
