#pragma once

#include "RE/M/MemoryManager.h"
#include "RE/N/NiGeometryData.h"
#include "RE/N/NiObject.h"
#include "RE/V/VertexDesc.h"

namespace RE
{
	struct ID3D11Buffer;

	namespace BSGraphics
	{
		struct TriShape
		{
			ID3D11Buffer*          vertexBuffer;   // 00
			ID3D11Buffer*          indexBuffer;    // 08
			BSGraphics::VertexDesc vertexDesc;     // 10
			volatile std::uint32_t refCount;       // 18
			std::uint32_t          pad1C;          // 1C
			std::uint8_t*          rawVertexData;  // 20
			std::uint16_t*         rawIndexData;   // 28
		};
		static_assert(sizeof(TriShape) == 0x30);
	}

	class NiSkinPartition : public NiObject
	{
	public:
		inline static constexpr auto RTTI = RTTI_NiSkinPartition;
		inline static constexpr auto Ni_RTTI = NiRTTI_NiSkinPartition;
		inline static constexpr auto VTABLE = VTABLE_NiSkinPartition;

		class Partition
		{
		public:
			BSGraphics::VertexDesc vertexDesc;      // 00
			std::uint16_t*         bones;           // 08
			float*                 weights;         // 10
			std::uint16_t*         vertexMap;       // 18
			std::uint8_t*          bonePalette;     // 20
			std::uint16_t*         triList;         // 28
			std::uint16_t*         stripLengths;    // 30
			std::uint16_t          vertices;        // 38
			std::uint16_t          triangles;       // 3A
			std::uint16_t          numBones;        // 3C
			std::uint16_t          strips;          // 3E
			std::uint16_t          bonesPerVertex;  // 40
			std::uint16_t          pad42;           // 42
			float                  unk44;           // 44
			BSGraphics::TriShape*  buffData;        // 48
		};
		static_assert(sizeof(Partition) == 0x50);

		~NiSkinPartition() override;  // 00

		// override (NiObject)
		const NiRTTI* GetRTTI() const override;                          // 02
		void          LoadBinary(NiStream& a_stream) override;           // 18
		void          LinkObject(NiStream& a_stream) override;           // 19 - { NiObject::LinkObject(a_stream); }
		bool          RegisterStreamables(NiStream& a_stream) override;  // 1A - { return NiObject::RegisterStreamables(a_stream); }
		void          SaveBinary(NiStream& a_stream) override;           // 1B
		bool          IsEqual(NiObject* a_object) override;              // 1C

		// add
		virtual void Unk_25(void);  // 25

		// members
		std::uint32_t          numPartitions;  // 10
		std::uint32_t          pad14;          // 14
		SimpleArray<Partition> partitions;     // 18
		std::uint32_t          vertexCount;    // 20
		std::uint32_t          unk24;          // 24
	};
	static_assert(sizeof(NiSkinPartition) == 0x28);
}
