/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmCoreAPI.h"
#include "glmCoreDefinitions.h"

#if GLM_IS_PLATFORM_LINUX
//NOTE: to include various limit defines (ie: UINT32_MAX, ...)
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#define __STDC_CONSTANT_MACROS 1
#undef _STDINT_H
#include <stdint.h>
#endif
#else
#include <stdint.h>
#endif

#ifdef GLM_USE_X11
// included here to avoid name collision with Time
#include "glmX11.h"
#undef Bool // avoid conflicts with X11
#undef Status
#undef True
#undef False
#endif

#include <cstddef>
#include <cassert>

namespace glm
{
    // Time measures type definition to be used throughout golaem APIs
    typedef double Time;

    /**
	* \brief Xml data file save error code
	*/
    struct SaveXMLDataFileErrorCode
    {
        enum Value
        {
            SUCCESS,
            FILE_CREATION_FAILED,
            END
        };
    };

    /**
     * \brief Asset Group Reparition type
     */
    struct AssetGroupWeightType
    {
        enum Value
        {
            RANDOM = 0,
            ATTRIBUTE,
            //CHANNEL,
            END
        };
    };    

    /**
	* \brief Shader attribute type
	*/
    struct ShaderAttributeType
    {
        enum Value
        {
            INT,
            FLOAT,
            STRING,
            VECTOR,
            END
        };
    };

    /**
	* \brief Shader attribute value type
	*/
    struct ShaderAttributeValueType
    {
        enum Value
        {
            RANDOM,
            ATTRIBUTE,
			CHANNEL,
            END
        };
    };

    struct WeightOverrideType
    {
        enum Value
        {
            GROUP,
            SHADER_ATTRIBUTE,
            END
        };
    };

    struct LoadCharacterFileErrorCode
    {
        enum Value
        {
            SUCCESS,
            FILE_NOT_FOUND,
            INCORRECT_VERSION,
            INVALID_FILE,
            INVALID_SKELETON_DESCRIPTION,
            END
        };
    };

    struct SaveCharacterFileErrorCode
    {
        enum Value
        {
            SUCCESS,
            FILE_CREATION_FAILED,
            END
        };
    };

    struct LoadSkeletonMappingErrorCode
    {
        enum Value
        {
            SUCCESS,
            FILE_NOT_FOUND,
            INCORRECT_VERSION,
            INVALID_FILE,
            INVALID_SKELETON_DESCRIPTION,
            END
        };
    };

    struct SaveSkeletonMappingErrorCode
    {
        enum Value
        {
            SUCCESS,
            FILE_CREATION_FAILED,
            END
        };
    };

    struct SkeletonPartType
    {
    public:
        enum Value
        {
            GENERIC = 0,
            SPINE,
            GRASPER,
            LEG,
            ROOT,
            END
        };
    };

    //------------------------------------------------------------
    //! Golaem file categories
    /*	\warning If any changes, please update $gCrowdFileTypes in CrowdUtils.mel
	*/
    //---------------------------------------------------------
    struct GolaemFileType
    {
        enum Value
        {
            CHARACTERS = 0,
            MOTIONS,
            ENVIRONMENTS,
            SHADERS,
            SIMULATIONEXPORT,
            SIMULATIONBAKE,
            SIMULATIONLIBRARY,
            DEEP,
            GOLAEM, // default
            END
        };
    };

    //-------------------------------------------------------------------------
    // CoronalPlaneLocation : http://en.wikipedia.org/wiki/Coronal_plane
    //-------------------------------------------------------------------------
    struct CoronalPlaneLocation
    {
    public:
        enum Value
        {
            FRONT = 0,
            BACK,
            CENTER,
            END
        };
    };

    //-------------------------------------------------------------------------
    // TransversePlaneLocation : http://en.wikipedia.org/wiki/Transverse_plane
    //-------------------------------------------------------------------------
    struct TransversePlaneLocation
    {
    public:
        enum Value
        {
            TOP = 0,
            BOTTOM,
            CENTER,
            END
        };
    };

    //-------------------------------------------------------------------------
    // SagittalPlaneLocation : http://en.wikipedia.org/wiki/Sagittal_plane
    //-------------------------------------------------------------------------
    struct SagittalPlaneLocation
    {
    public:
        enum Value
        {
            RIGHT = 0,
            CENTER,
            LEFT,
            END
        };
    };

    struct RagdollRigidBodyShape
    {
        enum Value
        {
            CYLINDER = 0,
            BOX,
            CAPSULE,
            SPHERE,
            END
        };
    };

    typedef RagdollRigidBodyShape SkeletonDisplayShape;

    struct SnsScaleMode
    {
        enum Value
        {
            UNIFORM_SCALE = 0,
            INVERSE_SQUAREROOT_SCALE = 1,
            NO_SCALE = 2,
            END
        };
    };

    struct GeometryFileType
    {
        enum Value
        {
            GCG,
            FBX,
            END
        };
    };

    struct RotateOrder
    {
        enum Value
        {
            XYZ,
            YZX,
            ZXY,
            XZY,
            YXZ,
            ZYX,
            END
        };
    };

#ifndef NDEBUG
    //-------------------------------------------------------------------------
    // toString
    //-------------------------------------------------------------------------
    inline const char* toString(const SkeletonPartType::Value type)
    {
        assert(type < SkeletonPartType::END);
        static const char* typeNames[] = {"GENERIC", "SPINE", "GRASPER", "LEG", "ROOT", "Unknown type"};
        return typeNames[type];
    }
#endif

    inline const char* toString(const GolaemFileType::Value type)
    {
        assert(type < GolaemFileType::END);
        static const char* typeNames[] = {"Characters", "Motions", "Environment", "Shaders", "SimulationExport", "SimulationBake", "SimulationLibrary", "Deep", "Golaem"};
        return typeNames[type];
    }
} // namespace glm
