#pragma once

#include <filesystem>
#include <map>
#include <string>
#include <vector>

enum class ShaderParameterType
{
	Float,
	Vec2,
	Color,
	Boolean,
	Enum,
	Text,
	Trigger
};

struct ShaderParameterOption
{
	std::string value;
	std::string label;
};

struct ShaderParameterDefinition
{
	std::string id;
	std::string label;
	std::string description;
	ShaderParameterType type = ShaderParameterType::Float;
	std::vector<double> defaultNumbers;
	std::vector<double> minNumbers;
	std::vector<double> maxNumbers;
	std::vector<double> stepNumbers;
	bool defaultBoolean = false;
	std::string defaultEnumValue;
	std::string defaultTextValue;
	std::string fontId;
	unsigned maxLength = 64;
	std::vector<ShaderParameterOption> enumOptions;
};

struct ShaderParameterValue
{
	std::vector<double> numberValues;
	bool booleanValue = false;
	std::string enumValue;
	std::string textValue;
};

enum class TemporalHistorySource
{
	None,
	Source,
	PreLayerInput
};

struct TemporalSettings
{
	bool enabled = false;
	TemporalHistorySource historySource = TemporalHistorySource::None;
	unsigned requestedHistoryLength = 0;
	unsigned effectiveHistoryLength = 0;
};

struct FeedbackSettings
{
	bool enabled = false;
	std::string writePassId;
};

struct ShaderTextureAsset
{
	std::string id;
	std::filesystem::path path;
	std::filesystem::file_time_type writeTime;
};

struct ShaderFontAsset
{
	std::string id;
	std::filesystem::path path;
	std::filesystem::file_time_type writeTime;
};

struct ShaderPassDefinition
{
	std::string id;
	std::string entryPoint;
	std::filesystem::path sourcePath;
	std::filesystem::file_time_type sourceWriteTime;
	std::vector<std::string> inputNames;
	std::string outputName;
};

struct ShaderPassBuildSource
{
	std::string passId;
	std::string fragmentShaderSource;
	std::vector<std::string> inputNames;
	std::string outputName;
};

struct ShaderPackage
{
	std::string id;
	std::string displayName;
	std::string description;
	std::string category;
	std::string entryPoint;
	std::filesystem::path directoryPath;
	std::filesystem::path shaderPath;
	std::filesystem::path manifestPath;
	std::vector<ShaderPassDefinition> passes;
	std::vector<ShaderParameterDefinition> parameters;
	std::vector<ShaderTextureAsset> textureAssets;
	std::vector<ShaderFontAsset> fontAssets;
	TemporalSettings temporal;
	FeedbackSettings feedback;
	std::filesystem::file_time_type shaderWriteTime;
	std::filesystem::file_time_type manifestWriteTime;
};

struct ShaderPackageStatus
{
	std::string id;
	std::string displayName;
	std::string description;
	std::string category;
	bool available = false;
	std::string error;
};

struct RuntimeRenderState
{
	std::string layerId;
	std::string shaderId;
	std::string shaderName;
	std::vector<ShaderParameterDefinition> parameterDefinitions;
	std::map<std::string, ShaderParameterValue> parameterValues;
	std::vector<ShaderTextureAsset> textureAssets;
	std::vector<ShaderFontAsset> fontAssets;
	double timeSeconds = 0.0;
	double utcTimeSeconds = 0.0;
	double utcOffsetSeconds = 0.0;
	double startupRandom = 0.0;
	double frameCount = 0.0;
	double mixAmount = 1.0;
	double bypass = 0.0;
	unsigned inputWidth = 0;
	unsigned inputHeight = 0;
	unsigned outputWidth = 0;
	unsigned outputHeight = 0;
	bool isTemporal = false;
	TemporalHistorySource temporalHistorySource = TemporalHistorySource::None;
	unsigned requestedTemporalHistoryLength = 0;
	unsigned effectiveTemporalHistoryLength = 0;
	FeedbackSettings feedback;
};
