// Copyright (c) Microsoft Corporation. 
// Licensed under the MIT license.

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "UObject/UObjectGlobals.h"
#include "UObject/Object.h"

#include "SimplygonUE4UI.h"
#include "SimplygonPropertyCasters.h"

#include "SimplygonCustomPipelines.generated.h"

UCLASS( DefaultToInstanced, BlueprintType, Blueprintable, abstract, editinlinenew )
class SIMPLYGONUOBJECTS_API USimplygonStandinPipeline : public UObject
{
	GENERATED_BODY()

public:
	/* Chart aggregation settings to adjust how UVs should be packed when flattening unreal engine materials.*/
	UPROPERTY(EditAnywhere, Category = "Flatten Material Settings")
	FChartAggregatorSettings ChartAggregatorSettings {};

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) { return Simplygon::NullPtr; }
#endif // WITH_EDITOR

};

UCLASS(BlueprintType, Blueprintable, DisplayName = "Near")
class SIMPLYGONUOBJECTS_API UStandinNearPipeline : public USimplygonStandinPipeline
{
	GENERATED_BODY()
		
public:

	UPROPERTY(EditAnywhere, Category = "Settings")
	FAggregationPipelineSettings Settings;

	UStandinNearPipeline()
	{
		Settings.GeometryCullingSettings.UseClippingGeometry = true;
		Settings.GeometryCullingSettings.ClippingGeometrySelectionSetName = SG_CLIPPING_GEOMETRY_SELECTION_SET_NAME;
		Settings.MappingImageSettings.TexCoordGeneratorType = ETexCoordGeneratorType::ChartAggregator;
		Settings.VisibilitySettings.OccluderSelectionSetName = SG_OCCLUDER_GEOMETRY_SELECTION_SET_NAME;
	}

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) override
	{
		return Settings.CreatePipeline(simplygon);
	}
#endif // WITH_EDITOR

};

UCLASS( BlueprintType, Blueprintable, DisplayName = "Far" )
class SIMPLYGONUOBJECTS_API UStandinFarPipeline : public USimplygonStandinPipeline
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, Category = "Settings")
	FRemeshingPipelineSettings Settings;

	UStandinFarPipeline()
	{
		Settings.GeometryCullingSettings.UseClippingGeometry = true;
		Settings.GeometryCullingSettings.ClippingGeometrySelectionSetName = SG_CLIPPING_GEOMETRY_SELECTION_SET_NAME;

		Settings.MaterialPropertyCasters.Add( CreateDefaultSubobject<UBaseColorCaster>(TEXT("DefaultBaseColor0")) );
		Settings.MaterialPropertyCasters.Add( CreateDefaultSubobject<UNormalCaster>(TEXT("DefaultNormal0")) );
	}

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) override
	{
		return Settings.CreatePipeline(simplygon);
	}
#endif // WITH_EDITOR

};

UCLASS(DisplayName = "BillbordCloud")
class SIMPLYGONUOBJECTS_API UBillboardCloudPipeline : public USimplygonStandinPipeline
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, Category = "Settings")
	FBillboardCloudPipelineSettings Settings;

	UBillboardCloudPipeline()
	{
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UBaseColorCaster>(TEXT("DefaultBaseColor0")));
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UOpacityMaskCaster>(TEXT("DefaultOpacityMask0")));
		UBaseColorCaster* BaseCaster = (UBaseColorCaster*)Settings.MaterialPropertyCasters[ 0 ];
		BaseCaster->ColorCasterSettings.OpacityChannel = TEXT( "OpacityMask" );
	}

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) override
	{
		return Settings.CreatePipeline(simplygon);
	}
#endif


};

UCLASS()
class SIMPLYGONUOBJECTS_API UFlipbookPipeline : public USimplygonPipeline
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, Category = "Settings")
	FFlipbookPipelineSettings Settings;

	UFlipbookPipeline()
	{
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UBaseColorCaster>(TEXT("DefaultBaseColor0")));
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UOpacityMaskCaster>(TEXT("DefaultOpacityMask0")));
		UBaseColorCaster* BaseCaster = (UBaseColorCaster*)Settings.MaterialPropertyCasters[ 0 ];
		BaseCaster->ColorCasterSettings.OpacityChannel = TEXT( "OpacityMask" );
	}

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) override
	{
		return Settings.CreatePipeline(simplygon);
	}

#endif
};

UCLASS(DisplayName = "BillboardCloudFoliage")
class SIMPLYGONUOBJECTS_API UBillboardCloudVegetationPipeline : public USimplygonPipeline
{
	GENERATED_BODY()

public:

	UPROPERTY(EditAnywhere, Category = "Settings")
	FBillboardCloudVegetationPipelineSettings Settings;

	UBillboardCloudVegetationPipeline()
	{
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UBaseColorCaster>(TEXT("DefaultBaseColor0")));
		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UOpacityMaskCaster>(TEXT("DefaultOpacityMask0")));
		UBaseColorCaster* BaseCaster = (UBaseColorCaster*)Settings.MaterialPropertyCasters[ 0 ];
		BaseCaster->ColorCasterSettings.OpacityChannel = TEXT( "OpacityMask" );
	}

#if WITH_EDITOR
	virtual Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon) override
	{

		return Settings.CreatePipeline(simplygon);
	}

#endif

};


//NOTE : UCLASS is not allowed to be inside a pre processor block therefore this code is disabled.
// // Enable this if IMPOSTER_BAKER is defined
//UCLASS(DisplayName = "BillboardImposter")
//class SIMPLYGONUOBJECTS_API UImpostorFromSingleViewPipeline : public UObject
//{
//	GENERATED_BODY()
//
//public:
//
//	UPROPERTY(EditAnywhere, Category = "Settings")
//	FImpostorFromSingleViewPipelineSettings Settings;
//
//	UImpostorFromSingleViewPipeline()
//	{
//		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UBaseColorCaster>(TEXT("DefaultBaseColor0")));
//		Settings.MaterialPropertyCasters.Add(CreateDefaultSubobject<UOpacityMaskCaster>(TEXT("DefaultOpacityMask0")));
//	}
//
//#if WITH_EDITOR
//	Simplygon::spPipeline CreatePipeline(Simplygon::ISimplygon* simplygon)
//	{
//		return Settings.CreatePipeline(simplygon);	
//	}
//
//#endif
//
//
//private:
//
//};
