/*
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.

----------------------------------------------------------------------
*/



#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER

#include "OgreImporter.h"
#include "TinyFormatter.h"
#include <assimp/material.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include "fast_atof.h"

#include <vector>
#include <sstream>
#include <memory>

using namespace std;

namespace Assimp
{
namespace Ogre
{

static const string partComment    = "//";
static const string partBlockStart = "{";
static const string partBlockEnd   = "}";

void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh)
{
    std::vector<aiMaterial*> materials;

    // Create materials that can be found and parsed via the IOSystem.
    for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
    {
        SubMesh *submesh = mesh->GetSubMesh(i);
        if (submesh && !submesh->materialRef.empty())
        {
            aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
            if (material)
            {
                submesh->materialIndex = static_cast<int>(materials.size());
                materials.push_back(material);
            }
        }
    }

    AssignMaterials(pScene, materials);
}

void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh)
{
    std::vector<aiMaterial*> materials;

    // Create materials that can be found and parsed via the IOSystem.
    for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
    {
        SubMeshXml *submesh = mesh->GetSubMesh( static_cast<uint16_t>(i));
        if (submesh && !submesh->materialRef.empty())
        {
            aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
            if (material)
            {
                submesh->materialIndex = static_cast<int>(materials.size());
                materials.push_back(material);
            }
        }
    }

    AssignMaterials(pScene, materials);
}

void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &materials)
{
    pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
    if (pScene->mNumMaterials > 0)
    {
        pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
        for(size_t i=0;i<pScene->mNumMaterials; ++i) {
            pScene->mMaterials[i] = materials[i];
        }
    }
}

aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string &materialName)
{
    if (materialName.empty()) {
        return 0;
    }

    // Full reference and examples of Ogre Material Script
    // can be found from http://www.ogre3d.org/docs/manual/manual_14.html

    /*and here is another one:

    import * from abstract_base_passes_depth.material
    import * from abstract_base.material
    import * from mat_shadow_caster.material
    import * from mat_character_singlepass.material

    material hero/hair/caster : mat_shadow_caster_skin_areject
    {
      set $diffuse_map "hero_hair_alpha_c.dds"
    }

    material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights
    {
      set $diffuse_map  "hero_hair_alpha_c.dds"
      set $specular_map "hero_hair_alpha_s.dds"
      set $normal_map   "hero_hair_alpha_n.dds"
      set $light_map    "black_lightmap.dds"

      set $shadow_caster_material "hero/hair/caster"
    }
    */

    stringstream ss;

    // Scope for scopre_ptr auto release
    {
        /* There are three .material options in priority order:
            1) File with the material name (materialName)
            2) File with the mesh files base name (pFile)
            3) Optional user defined material library file (m_userDefinedMaterialLibFile) */
        std::vector<string> potentialFiles;
        potentialFiles.push_back(materialName + ".material");
        potentialFiles.push_back(pFile.substr(0, pFile.rfind(".mesh")) + ".material");
        if (!m_userDefinedMaterialLibFile.empty())
            potentialFiles.push_back(m_userDefinedMaterialLibFile);

        IOStream *materialFile = 0;
        for(size_t i=0; i<potentialFiles.size(); ++i)
        {
            materialFile = pIOHandler->Open(potentialFiles[i]);
            if (materialFile) {
                break;
            }
            DefaultLogger::get()->debug(Formatter::format() << "Source file for material '" << materialName << "' " << potentialFiles[i] << " does not exist");
        }
        if (!materialFile)
        {
            DefaultLogger::get()->error(Formatter::format() << "Failed to find source file for material '" << materialName << "'");
            return 0;
        }

        std::unique_ptr<IOStream> stream(materialFile);
        if (stream->FileSize() == 0)
        {
            DefaultLogger::get()->warn(Formatter::format() << "Source file for material '" << materialName << "' is empty (size is 0 bytes)");
            return 0;
        }

        // Read bytes
        vector<char> data(stream->FileSize());
        stream->Read(&data[0], stream->FileSize(), 1);

        // Convert to UTF-8 and terminate the string for ss
        BaseImporter::ConvertToUTF8(data);
        data.push_back('\0');

        ss << &data[0];
    }

    DefaultLogger::get()->debug("Reading material '" + materialName + "'");

    aiMaterial *material = new aiMaterial();
    m_textures.clear();

    aiString ts(materialName);
    material->AddProperty(&ts, AI_MATKEY_NAME);

    // The stringstream will push words from a line until newline.
    // It will also trim whitespace from line start and between words.
    string linePart;
    ss >> linePart;

    const string partMaterial   = "material";
    const string partTechnique  = "technique";

    while(!ss.eof())
    {
        // Skip commented lines
        if (linePart == partComment)
        {
            NextAfterNewLine(ss, linePart);
            continue;
        }
        if (linePart != partMaterial)
        {
            ss >> linePart;
            continue;
        }

        ss >> linePart;
        if (linePart != materialName)
        {
            //DefaultLogger::get()->debug(Formatter::format() << "Found material '" << linePart << "' that does not match at index " << ss.tellg());
            ss >> linePart;
            continue;
        }

        NextAfterNewLine(ss, linePart);
        if (linePart != partBlockStart)
        {
            DefaultLogger::get()->error(Formatter::format() << "Invalid material: block start missing near index " << ss.tellg());
            return material;
        }

        DefaultLogger::get()->debug("material '" + materialName + "'");

        while(linePart != partBlockEnd)
        {
            // Proceed to the first technique
            ss >> linePart;

            if (linePart == partTechnique)
            {
                string techniqueName = SkipLine(ss);
                ReadTechnique(Trim(techniqueName), ss, material);
            }

            // Read information from a custom material
            /** @todo This "set $x y" does not seem to be a official Ogre material system feature.
                Materials can inherit other materials and override texture units by using the (unique)
                parent texture unit name in your cloned material.
                This is not yet supported and below code is probably some hack from the original
                author of this Ogre importer. Should be removed? */
            if (linePart=="set")
            {
                ss >> linePart;
                if (linePart=="$specular")//todo load this values:
                {
                }
                else if (linePart=="$diffuse")
                {
                }
                else if (linePart=="$ambient")
                {
                }
                else if (linePart=="$colormap")
                {
                    ss >> linePart;
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
                }
                else if (linePart=="$normalmap")
                {
                    ss >> linePart;
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
                }
                else if (linePart=="$shininess_strength")
                {
                    ss >> linePart;
                    float Shininess = fast_atof(linePart.c_str());
                    material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
                }
                else if (linePart=="$shininess_exponent")
                {
                    ss >> linePart;
                    float Shininess = fast_atof(linePart.c_str());
                    material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS);
                }
                //Properties from Venetica:
                else if (linePart=="$diffuse_map")
                {
                    ss >> linePart;
                    if (linePart[0] == '"')// "file" -> file
                        linePart = linePart.substr(1, linePart.size()-2);
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
                }
                else if (linePart=="$specular_map")
                {
                    ss >> linePart;
                    if (linePart[0] == '"')// "file" -> file
                        linePart = linePart.substr(1, linePart.size()-2);
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0));
                }
                else if (linePart=="$normal_map")
                {
                    ss >> linePart;
                    if (linePart[0]=='"')// "file" -> file
                        linePart = linePart.substr(1, linePart.size()-2);
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
                }
                else if (linePart=="$light_map")
                {
                    ss >> linePart;
                    if (linePart[0]=='"') {
                        linePart = linePart.substr(1, linePart.size() - 2);
                    }
                    aiString ts(linePart);
                    material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0));
                }
            }
        }
        ss >> linePart;
    }

    return material;
}

bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream &ss, aiMaterial *material)
{
    string linePart;
    ss >> linePart;

    if (linePart != partBlockStart)
    {
        DefaultLogger::get()->error(Formatter::format() << "Invalid material: Technique block start missing near index " << ss.tellg());
        return false;
    }

    DefaultLogger::get()->debug(" technique '" + techniqueName + "'");

    const string partPass  = "pass";

    while(linePart != partBlockEnd)
    {
        ss >> linePart;

        // Skip commented lines
        if (linePart == partComment)
        {
            SkipLine(ss);
            continue;
        }

        /// @todo Techniques have other attributes than just passes.
        if (linePart == partPass)
        {
            string passName = SkipLine(ss);
            ReadPass(Trim(passName), ss, material);
        }
    }
    return true;
}

bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material)
{
    string linePart;
    ss >> linePart;

    if (linePart != partBlockStart)
    {
        DefaultLogger::get()->error(Formatter::format() << "Invalid material: Pass block start missing near index " << ss.tellg());
        return false;
    }

    DefaultLogger::get()->debug("  pass '" + passName + "'");

    const string partAmbient     = "ambient";
    const string partDiffuse     = "diffuse";
    const string partSpecular    = "specular";
    const string partEmissive    = "emissive";
    const string partTextureUnit = "texture_unit";

    while(linePart != partBlockEnd)
    {
        ss >> linePart;

        // Skip commented lines
        if (linePart == partComment)
        {
            SkipLine(ss);
            continue;
        }

        // Colors
        /// @todo Support alpha via aiColor4D.
        if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive)
        {
            float r, g, b;
            ss >> r >> g >> b;
            const aiColor3D color(r, g, b);

            DefaultLogger::get()->debug(Formatter::format() << "   " << linePart << " " << r << " " << g << " " << b);

            if (linePart == partAmbient)
            {
                material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT);
            }
            else if (linePart == partDiffuse)
            {
                material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE);
            }
            else if (linePart == partSpecular)
            {
                material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR);
            }
            else if (linePart == partEmissive)
            {
                material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE);
            }
        }
        else if (linePart == partTextureUnit)
        {
            string textureUnitName = SkipLine(ss);
            ReadTextureUnit(Trim(textureUnitName), ss, material);
        }
    }
    return true;
}

bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstream &ss, aiMaterial *material)
{
    string linePart;
    ss >> linePart;

    if (linePart != partBlockStart)
    {
        DefaultLogger::get()->error(Formatter::format() << "Invalid material: Texture unit block start missing near index " << ss.tellg());
        return false;
    }

    DefaultLogger::get()->debug("   texture_unit '" + textureUnitName + "'");

    const string partTexture      = "texture";
    const string partTextCoordSet = "tex_coord_set";
    const string partColorOp      = "colour_op";

    aiTextureType textureType = aiTextureType_NONE;
    std::string textureRef;
    int uvCoord = 0;

    while(linePart != partBlockEnd)
    {
        ss >> linePart;

        // Skip commented lines
        if (linePart == partComment)
        {
            SkipLine(ss);
            continue;
        }

        if (linePart == partTexture)
        {
            ss >> linePart;
            textureRef = linePart;

            // User defined Assimp config property to detect texture type from filename.
            if (m_detectTextureTypeFromFilename)
            {
                size_t posSuffix = textureRef.find_last_of(".");
                size_t posUnderscore = textureRef.find_last_of("_");

                if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore)
                {
                    string identifier = Ogre::ToLower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
                    DefaultLogger::get()->debug(Formatter::format() << "Detecting texture type from filename postfix '" << identifier << "'");

                    if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap")
                    {
                        textureType = aiTextureType_NORMALS;
                    }
                    else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap")
                    {
                        textureType = aiTextureType_SPECULAR;
                    }
                    else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion")
                    {
                        textureType = aiTextureType_LIGHTMAP;
                    }
                    else if (identifier == "_disp" || identifier == "_displacement")
                    {
                        textureType = aiTextureType_DISPLACEMENT;
                    }
                    else
                    {
                        textureType = aiTextureType_DIFFUSE;
                    }
                }
                else
                {
                    textureType = aiTextureType_DIFFUSE;
                }
            }
            // Detect from texture unit name. This cannot be too broad as
            // authors might give names like "LightSaber" or "NormalNinja".
            else
            {
                string unitNameLower = Ogre::ToLower(textureUnitName);
                if (unitNameLower.find("normalmap") != string::npos)
                {
                    textureType = aiTextureType_NORMALS;
                }
                else if (unitNameLower.find("specularmap") != string::npos)
                {
                    textureType = aiTextureType_SPECULAR;
                }
                else if (unitNameLower.find("lightmap") != string::npos)
                {
                    textureType = aiTextureType_LIGHTMAP;
                }
                else if (unitNameLower.find("displacementmap") != string::npos)
                {
                    textureType = aiTextureType_DISPLACEMENT;
                }
                else
                {
                    textureType = aiTextureType_DIFFUSE;
                }
            }
        }
        else if (linePart == partTextCoordSet)
        {
            ss >> uvCoord;
        }
        /// @todo Implement
        else if(linePart == partColorOp)
        {
            /*
            ss >> linePart;
            if("replace"==linePart)//I don't think, assimp has something for this...
            {
            }
            else if("modulate"==linePart)
            {
                //TODO: set value
                //material->AddProperty(aiTextureOp_Multiply)
            }
            */
        }
    }

    if (textureRef.empty())
    {
        DefaultLogger::get()->warn("Texture reference is empty, ignoring texture_unit.");
        return false;
    }
    if (textureType == aiTextureType_NONE)
    {
        DefaultLogger::get()->warn("Failed to detect texture type for '" + textureRef  + "', ignoring texture_unit.");
        return false;
    }

    unsigned int textureTypeIndex = m_textures[textureType];
    m_textures[textureType]++;

    DefaultLogger::get()->debug(Formatter::format() << "    texture '" << textureRef << "' type " << textureType
        << " index " << textureTypeIndex << " UV " << uvCoord);

    aiString assimpTextureRef(textureRef);
    material->AddProperty(&assimpTextureRef, AI_MATKEY_TEXTURE(textureType, textureTypeIndex));
    material->AddProperty(&uvCoord, 1, AI_MATKEY_UVWSRC(textureType, textureTypeIndex));

    return true;
}

} // Ogre
} // Assimp

#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
