/*
---------------------------------------------------------------------------
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  Exporter.hpp
*  @brief Defines the CPP-API for the Assimp export interface
*/
#pragma once
#ifndef AI_EXPORT_HPP_INC
#define AI_EXPORT_HPP_INC

#ifndef ASSIMP_BUILD_NO_EXPORT

#include "cexport.h"
#include <map>

namespace Assimp {
    
class ExporterPimpl;
class IOSystem;

// ----------------------------------------------------------------------------------
/** CPP-API: The Exporter class forms an C++ interface to the export functionality
 * of the Open Asset Import Library. Note that the export interface is available
 * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
 *
 * The interface is modeled after the importer interface and mostly
 * symmetric. The same rules for threading etc. apply.
 *
 * In a nutshell, there are two export interfaces: #Export, which writes the
 * output file(s) either to the regular file system or to a user-supplied
 * #IOSystem, and #ExportToBlob which returns a linked list of memory
 * buffers (blob), each referring to one output file (in most cases
 * there will be only one output file of course, but this extra complexity is
 * needed since Assimp aims at supporting a wide range of file formats).
 *
 * #ExportToBlob is especially useful if you intend to work
 * with the data in-memory.
*/
class ASSIMP_API ExportProperties;

class ASSIMP_API Exporter {
public:
    /** Function pointer type of a Export worker function */
    typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);

    /** Internal description of an Assimp export format option */
    struct ExportFormatEntry
    {
        /// Public description structure to be returned by aiGetExportFormatDescription()
        aiExportFormatDesc mDescription;

        // Worker function to do the actual exporting
        fpExportFunc mExportFunction;

        // Post-processing steps to be executed PRIOR to invoking mExportFunction
        unsigned int mEnforcePP;

        // Constructor to fill all entries
        ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u)
        {
            mDescription.id = pId;
            mDescription.description = pDesc;
            mDescription.fileExtension = pExtension;
            mExportFunction = pFunction;
            mEnforcePP = pEnforcePP;
        }

        ExportFormatEntry() :
            mExportFunction()
          , mEnforcePP()
        {
            mDescription.id = NULL;
            mDescription.description = NULL;
            mDescription.fileExtension = NULL;
        }
    };


public:
    Exporter();
    ~Exporter();

public:
    // -------------------------------------------------------------------
    /** Supplies a custom IO handler to the exporter to use to open and
     * access files.
     *
     * If you need #Export to use custom IO logic to access the files,
     * you need to supply a custom implementation of IOSystem and
     * IOFile to the exporter.
     *
     * #Exporter takes ownership of the object and will destroy it
     * afterwards. The previously assigned handler will be deleted.
     * Pass NULL to take again ownership of your IOSystem and reset Assimp
     * to use its default implementation, which uses plain file IO.
     *
     * @param pIOHandler The IO handler to be used in all file accesses
     *   of the Importer. */
    void SetIOHandler( IOSystem* pIOHandler);

    // -------------------------------------------------------------------
    /** Retrieves the IO handler that is currently set.
     * You can use #IsDefaultIOHandler() to check whether the returned
     * interface is the default IO handler provided by ASSIMP. The default
     * handler is active as long the application doesn't supply its own
     * custom IO handler via #SetIOHandler().
     * @return A valid IOSystem interface, never NULL. */
    IOSystem* GetIOHandler() const;

    // -------------------------------------------------------------------
    /** Checks whether a default IO handler is active
     * A default handler is active as long the application doesn't
     * supply its own custom IO handler via #SetIOHandler().
     * @return true by default */
    bool IsDefaultIOHandler() const;

    // -------------------------------------------------------------------
    /** Exports the given scene to a chosen file format. Returns the exported
    * data as a binary blob which you can write into a file or something.
    * When you're done with the data, simply let the #Exporter instance go
    * out of scope to have it released automatically.
    * @param pScene The scene to export. Stays in possession of the caller,
    *   is not changed by the function.
    * @param pFormatId ID string to specify to which format you want to
    *   export to. Use
    * #GetExportFormatCount / #GetExportFormatDescription to learn which
    *   export formats are available.
    * @param pPreprocessing See the documentation for #Export
    * @return the exported data or NULL in case of error.
    * @note If the Exporter instance did already hold a blob from
    *   a previous call to #ExportToBlob, it will be disposed.
    *   Any IO handlers set via #SetIOHandler are ignored here.
    * @note Use aiCopyScene() to get a modifiable copy of a previously
    *   imported scene. */
    const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* = NULL);
    const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);

    // -------------------------------------------------------------------
    /** Convenience function to export directly to a file. Use
     *  #SetIOSystem to supply a custom IOSystem to gain fine-grained control
     *  about the output data flow of the export process.
     * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
     * @param pPath Full target file name. Target must be accessible.
     * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
     *   flags, but in reality only a subset of them makes sense here. Specifying
     *   'preprocessing' flags is useful if the input scene does not conform to
     *   Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
     *   In short, this means the geometry data should use a right-handed coordinate systems, face
     *   winding should be counter-clockwise and the UV coordinate origin is assumed to be in
     *   the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
     *   #aiProcess_FlipWindingOrder flags are used in the import side to allow users
     *   to have those defaults automatically adapted to their conventions. Specifying those flags
     *   for exporting has the opposite effect, respectively. Some other of the
     *   #aiPostProcessSteps enumerated values may be useful as well, but you'll need
     *   to try out what their effect on the exported file is. Many formats impose
     *   their own restrictions on the structure of the geometry stored therein,
     *   so some preprocessing may have little or no effect at all, or may be
     *   redundant as exporters would apply them anyhow. A good example
     *   is triangulation - whilst you can enforce it by specifying
     *   the #aiProcess_Triangulate flag, most export formats support only
     *   triangulate data so they would run the step even if it wasn't requested.
     *
     *   If assimp detects that the input scene was directly taken from the importer side of
     *   the library (i.e. not copied using aiCopyScene and potentially modified afterwards),
     *   any post-processing steps already applied to the scene will not be applied again, unless
     *   they show non-idempotent behavior (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
     *   #aiProcess_FlipWindingOrder).
     * @return AI_SUCCESS if everything was fine.
     * @note Use aiCopyScene() to get a modifiable copy of a previously
     *   imported scene.*/
    aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
    aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,  unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);

    // -------------------------------------------------------------------
    /** Returns an error description of an error that occurred in #Export
     *    or #ExportToBlob
     *
     * Returns an empty string if no error occurred.
     * @return A description of the last error, an empty string if no
     *   error occurred. The string is never NULL.
     *
     * @note The returned function remains valid until one of the
     * following methods is called: #Export, #ExportToBlob, #FreeBlob */
    const char* GetErrorString() const;

    // -------------------------------------------------------------------
    /** Return the blob obtained from the last call to #ExportToBlob */
    const aiExportDataBlob* GetBlob() const;

    // -------------------------------------------------------------------
    /** Orphan the blob from the last call to #ExportToBlob. This means
     *  the caller takes ownership and is thus responsible for calling
     *  the C API function #aiReleaseExportBlob to release it. */
    const aiExportDataBlob* GetOrphanedBlob() const;

    // -------------------------------------------------------------------
    /** Frees the current blob.
     *
     *  The function does nothing if no blob has previously been
     *  previously produced via #ExportToBlob. #FreeBlob is called
     *  automatically by the destructor. The only reason to call
     *  it manually would be to reclaim as much storage as possible
     *  without giving up the #Exporter instance yet. */
    void FreeBlob( );

    // -------------------------------------------------------------------
    /** Returns the number of export file formats available in the current
     *  Assimp build. Use #Exporter::GetExportFormatDescription to
     *  retrieve infos of a specific export format.
     *
     *  This includes built-in exporters as well as exporters registered
     *  using #RegisterExporter.
     **/
    size_t GetExportFormatCount() const;

    // -------------------------------------------------------------------
    /** Returns a description of the nth export file format. Use #
     *  #Exporter::GetExportFormatCount to learn how many export
     *  formats are supported.
     *
     * The returned pointer is of static storage duration if the
     * pIndex pertains to a built-in exporter (i.e. one not registered
     * via #RegistrerExporter). It is restricted to the life-time of the
     * #Exporter instance otherwise.
     *
     * @param pIndex Index of the export format to retrieve information
     *  for. Valid range is 0 to #Exporter::GetExportFormatCount
     * @return A description of that specific export format.
     *  NULL if pIndex is out of range. */
    const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const;

    // -------------------------------------------------------------------
    /** Register a custom exporter. Custom export formats are limited to
     *    to the current #Exporter instance and do not affect the
     *    library globally. The indexes under which the format's
     *    export format description can be queried are assigned
     *    monotonously.
     *  @param desc Exporter description.
     *  @return aiReturn_SUCCESS if the export format was successfully
     *    registered. A common cause that would prevent an exporter
     *    from being registered is that its format id is already
     *    occupied by another format. */
    aiReturn RegisterExporter(const ExportFormatEntry& desc);

    // -------------------------------------------------------------------
    /** Remove an export format previously registered with #RegisterExporter
     *  from the #Exporter instance (this can also be used to drop
     *  built-in exporters because those are implicitly registered
     *  using #RegisterExporter).
     *  @param id Format id to be unregistered, this refers to the
     *    'id' field of #aiExportFormatDesc.
     *  @note Calling this method on a format description not yet registered
     *    has no effect.*/
    void UnregisterExporter(const char* id);

protected:
    // Just because we don't want you to know how we're hacking around.
    ExporterPimpl* pimpl;
};

class ASSIMP_API ExportProperties {
public:
    // Data type to store the key hash
    typedef unsigned int KeyType;

    // typedefs for our four configuration maps.
    // We don't need more, so there is no need for a generic solution
    typedef std::map<KeyType, int> IntPropertyMap;
    typedef std::map<KeyType, ai_real> FloatPropertyMap;
    typedef std::map<KeyType, std::string> StringPropertyMap;
    typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;

public:
    /** Standard constructor
    * @see ExportProperties()
    */
    ExportProperties();

    // -------------------------------------------------------------------
    /** Copy constructor.
     *
     * This copies the configuration properties of another ExportProperties.
     * @see ExportProperties(const ExportProperties& other)
     */
    ExportProperties(const ExportProperties& other);

    // -------------------------------------------------------------------
    /** Set an integer configuration property.
     * @param szName Name of the property. All supported properties
     *   are defined in the aiConfig.g header (all constants share the
     *   prefix AI_CONFIG_XXX and are simple strings).
     * @param iValue New value of the property
     * @return true if the property was set before. The new value replaces
     *   the previous value in this case.
     * @note Property of different types (float, int, string ..) are kept
     *   on different stacks, so calling SetPropertyInteger() for a
     *   floating-point property has no effect - the loader will call
     *   GetPropertyFloat() to read the property, but it won't be there.
     */
    bool SetPropertyInteger(const char* szName, int iValue);

    // -------------------------------------------------------------------
    /** Set a boolean configuration property. Boolean properties
     *  are stored on the integer stack internally so it's possible
     *  to set them via #SetPropertyBool and query them with
     *  #GetPropertyBool and vice versa.
     * @see SetPropertyInteger()
     */
    bool SetPropertyBool(const char* szName, bool value)    {
        return SetPropertyInteger(szName,value);
    }

    // -------------------------------------------------------------------
    /** Set a floating-point configuration property.
     * @see SetPropertyInteger()
     */
    bool SetPropertyFloat(const char* szName, ai_real fValue);

    // -------------------------------------------------------------------
    /** Set a string configuration property.
     * @see SetPropertyInteger()
     */
    bool SetPropertyString(const char* szName, const std::string& sValue);

    // -------------------------------------------------------------------
    /** Set a matrix configuration property.
     * @see SetPropertyInteger()
     */
    bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);

    // -------------------------------------------------------------------
    /** Get a configuration property.
     * @param szName Name of the property. All supported properties
     *   are defined in the aiConfig.g header (all constants share the
     *   prefix AI_CONFIG_XXX).
     * @param iErrorReturn Value that is returned if the property
     *   is not found.
     * @return Current value of the property
     * @note Property of different types (float, int, string ..) are kept
     *   on different lists, so calling SetPropertyInteger() for a
     *   floating-point property has no effect - the loader will call
     *   GetPropertyFloat() to read the property, but it won't be there.
     */
    int GetPropertyInteger(const char* szName,
        int iErrorReturn = 0xffffffff) const;

    // -------------------------------------------------------------------
    /** Get a boolean configuration property. Boolean properties
     *  are stored on the integer stack internally so it's possible
     *  to set them via #SetPropertyBool and query them with
     *  #GetPropertyBool and vice versa.
     * @see GetPropertyInteger()
     */
    bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
        return GetPropertyInteger(szName,bErrorReturn)!=0;
    }

    // -------------------------------------------------------------------
    /** Get a floating-point configuration property
     * @see GetPropertyInteger()
     */
    ai_real GetPropertyFloat(const char* szName,
        ai_real fErrorReturn = 10e10f) const;

    // -------------------------------------------------------------------
    /** Get a string configuration property
     *
     *  The return value remains valid until the property is modified.
     * @see GetPropertyInteger()
     */
    const std::string GetPropertyString(const char* szName,
        const std::string& sErrorReturn = "") const;

    // -------------------------------------------------------------------
    /** Get a matrix configuration property
     *
     *  The return value remains valid until the property is modified.
     * @see GetPropertyInteger()
     */
    const aiMatrix4x4 GetPropertyMatrix(const char* szName,
        const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;

    // -------------------------------------------------------------------
    /** Determine a integer configuration property has been set.
    * @see HasPropertyInteger()
     */
    bool HasPropertyInteger(const char* szName) const;

    /** Determine a boolean configuration property has been set.
    * @see HasPropertyBool()
     */
    bool HasPropertyBool(const char* szName) const;

    /** Determine a boolean configuration property has been set.
    * @see HasPropertyFloat()
     */
    bool HasPropertyFloat(const char* szName) const;

    /** Determine a String configuration property has been set.
    * @see HasPropertyString()
     */
    bool HasPropertyString(const char* szName) const;

    /** Determine a Matrix configuration property has been set.
    * @see HasPropertyMatrix()
     */
    bool HasPropertyMatrix(const char* szName) const;

protected:

    /** List of integer properties */
    IntPropertyMap mIntProperties;

    /** List of floating-point properties */
    FloatPropertyMap mFloatProperties;

    /** List of string properties */
    StringPropertyMap mStringProperties;

    /** List of Matrix properties */
    MatrixPropertyMap mMatrixProperties;
};

// ----------------------------------------------------------------------------------
inline 
const aiExportDataBlob* Exporter::ExportToBlob(  const aiScene* pScene, const std::string& pFormatId,
                                                 unsigned int pPreprocessing, const ExportProperties* pProperties)
{
    return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
}

// ----------------------------------------------------------------------------------
inline
aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, 
                                    const std::string& pPath, unsigned int pPreprocessing, 
                                    const ExportProperties* pProperties)
{
    return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
}

} // namespace Assimp

#endif // ASSIMP_BUILD_NO_EXPORT
#endif // AI_EXPORT_HPP_INC
