// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.

#include "PolishBuildingsPrivatePCH.h"
#include "SPolishBuildingsDialog.h"
#include "Dialogs/DlgPickAssetPath.h"
#include "STextComboBox.h"
#include "RawMesh.h"
#include "PolishBuildingsTool/PolishBuildingsTool.h"

#define LOCTEXT_NAMESPACE "SPolishBuildingsDialog"

//////////////////////////////////////////////////////////////////////////
// SPolishBuildingsDialog

SPolishBuildingsDialog::SPolishBuildingsDialog()
{
}

BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SPolishBuildingsDialog::Construct(const FArguments& InArgs, FPolishBuildingsTool* InTool)
{
	Tool = InTool;
	check(Tool != nullptr);

	// Setup available resolutions for lightmap and merged materials
	const int32 MinTexResolution = 1 << FTextureLODGroup().MinLODMipCount;
	const int32 MaxTexResolution = 1 << FTextureLODGroup().MaxLODMipCount;
	for (int32 TexRes = MinTexResolution; TexRes <= MaxTexResolution; TexRes*=2)
	{
		LightMapResolutionOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(TexRes))));
		MergedMaterialResolutionOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(TexRes))));
	}

	Tool->MergingSettings.TargetLightMapResolution = FMath::Clamp(Tool->MergingSettings.TargetLightMapResolution, MinTexResolution, MaxTexResolution);
	Tool->MergingSettings.MaterialSettings.TextureSize.X = FMath::Clamp( Tool->MergingSettings.MaterialSettings.TextureSize.X, MinTexResolution, MaxTexResolution );
	Tool->MergingSettings.MaterialSettings.TextureSize.Y = FMath::Clamp( Tool->MergingSettings.MaterialSettings.TextureSize.Y, MinTexResolution, MaxTexResolution );

	// Setup available UV channels for an atlased lightmap
	for (int32 Index = 0; Index < MAX_MESH_TEXTURE_COORDS; Index++)
	{
		LightMapChannelOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(Index))));
	}

	for (int32 Index = 0; Index < MAX_STATIC_MESH_LODS; Index++)
	{
		ExportLODOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(Index))));
	}

	// Create widget layout
	this->ChildSlot
	[
		SNew(SVerticalBox)

		+SVerticalBox::Slot()
		.AutoHeight()
		.Padding(0,2,0,0)
		[
			// Lightmap settings
			SNew(SBorder)
			.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
			[
				SNew(SVerticalBox)
									
				// Enable atlasing
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetGenerateLightmapUV)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetGenerateLightmapUV)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("AtlasLightmapUVLabel", "Generate Lightmap UVs"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
					
				// Target lightmap channel / Max lightmap resolution
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SHorizontalBox)

					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					[
						SNew(STextBlock)
						.IsEnabled(this, &SPolishBuildingsDialog::IsLightmapChannelEnabled)
						.Text(LOCTEXT("TargetLightMapChannelLabel", "Target Channel:"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]

					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					.Padding(4,0,4,0)
					[
						SNew(STextComboBox)
						.IsEnabled( this, &SPolishBuildingsDialog::IsLightmapChannelEnabled )
						.OptionsSource(&LightMapChannelOptions)
						.InitiallySelectedItem(LightMapChannelOptions[Tool->MergingSettings.TargetLightMapUVChannel])
						.OnSelectionChanged(this, &SPolishBuildingsDialog::SetTargetLightMapChannel)
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]

					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					[
						SNew(STextBlock)
						.IsEnabled(this, &SPolishBuildingsDialog::IsLightmapChannelEnabled)
						.Text(LOCTEXT("TargetLightMapResolutionLabel", "Target Resolution:"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
												
					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					.Padding(4,0,4,0)
					[
						SNew(STextComboBox)
						.IsEnabled( this, &SPolishBuildingsDialog::IsLightmapChannelEnabled )
						.OptionsSource(&LightMapResolutionOptions)
						.InitiallySelectedItem(LightMapResolutionOptions[FMath::FloorLog2(Tool->MergingSettings.TargetLightMapResolution)])
						.OnSelectionChanged(this, &SPolishBuildingsDialog::SetTargetLightMapResolution)
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
			]
		]

		// Other merging settings
		+SVerticalBox::Slot()
		.AutoHeight()
		.Padding(0,2,0,0)
		[
			SNew(SBorder)
			.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
			[
				SNew(SVerticalBox)

				// LOD to export
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SHorizontalBox)

					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					[
						SNew(SCheckBox)
						.Type(ESlateCheckBoxType::CheckBox)
						.IsChecked(this, &SPolishBuildingsDialog::GetExportSpecificLODEnabled)
						.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportSpecificLODEnabled)
						.Content()
						[
							SNew(STextBlock)
							.IsEnabled(this, &SPolishBuildingsDialog::IsExportSpecificLODEnabled)
							.Text(LOCTEXT("TargetMeshLODIndexLabel", "Export specific LOD:"))
							.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
						]
					]
					
					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					.Padding(4,0,4,0)
					[
						SNew(STextComboBox)
						.IsEnabled(this, &SPolishBuildingsDialog::IsExportSpecificLODEnabled)
						.OptionsSource(&ExportLODOptions)
						.InitiallySelectedItem(ExportLODOptions[Tool->ExportLODIndex])
						.OnSelectionChanged(this, &SPolishBuildingsDialog::SetExportSpecificLODIndex)
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
					
				// Vertex colors
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetImportVertexColors)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetImportVertexColors)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ImportVertexColorsLabel", "Import Vertex Colors"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]

				// Pivot at zero
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetPivotPointAtZero)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetPivotPointAtZero)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("PivotPointAtZeroLabel", "Pivot Point At (0,0,0)"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]

				// Replace source actors
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetReplaceSourceActors)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetReplaceSourceActors)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ReplaceSourceActorsLabel", "Replace Source Actors"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				
				// Merge physics data
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetMergePhyisicData)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetMergePhyisicData)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("MergePhysicsDataLabel", "Merge Physics Data"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]

				// Merge materials
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetMergeMaterials)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetMergeMaterials)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("MergeMaterialsLabel", "Merge Materials"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				// Export normal map
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetExportNormalMap)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportNormalMap)
					.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ExportNormalMapLabel", "Export Normal Map"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				// Export metallic map
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetExportMetallicMap)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportMetallicMap)
					.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ExportMetallicMapLabel", "Export Metallic Map"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				// Export roughness map
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetExportRoughnessMap)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportRoughnessMap)
					.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ExportRoughnessMapLabel", "Export Roughness Map"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				// Export specular map
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SCheckBox)
					.Type(ESlateCheckBoxType::CheckBox)
					.IsChecked(this, &SPolishBuildingsDialog::GetExportSpecularMap)
					.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportSpecularMap)
					.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
					.Content()
					[
						SNew(STextBlock)
						.Text(LOCTEXT("ExportSpecularMapLabel", "Export Specular Map"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]
				
				// Merged texture size
				+SVerticalBox::Slot()
				.AutoHeight()
				.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
				[
					SNew(SHorizontalBox)
					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					[
						SNew(STextBlock)
						.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
						.Text(LOCTEXT("MergedMaterialAtlasResolutionLabel", "Merged Material Atlas Resolution:"))
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
												
					+SHorizontalBox::Slot()
					.AutoWidth()
					.VAlign(VAlign_Center)
					.Padding(4,0,4,0)
					[
						SNew(STextComboBox)
						.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
						.OptionsSource(&MergedMaterialResolutionOptions)
						.InitiallySelectedItem( MergedMaterialResolutionOptions[FMath::FloorLog2( Tool->MergingSettings.MaterialSettings.TextureSize.X )] )
						.OnSelectionChanged(this, &SPolishBuildingsDialog::SetMergedMaterialAtlasResolution)
						.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
					]
				]														
			]
		]
	];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

ECheckBoxState SPolishBuildingsDialog::GetGenerateLightmapUV() const
{
	return (Tool->MergingSettings.bGenerateLightMapUV ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetGenerateLightmapUV(ECheckBoxState NewValue)
{
	Tool->MergingSettings.bGenerateLightMapUV = (ECheckBoxState::Checked == NewValue);
}

bool SPolishBuildingsDialog::IsLightmapChannelEnabled() const
{
	return Tool->MergingSettings.bGenerateLightMapUV;
}

void SPolishBuildingsDialog::SetTargetLightMapChannel(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
	TTypeFromString<int32>::FromString(Tool->MergingSettings.TargetLightMapUVChannel, **NewSelection);
}

void SPolishBuildingsDialog::SetTargetLightMapResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
	TTypeFromString<int32>::FromString(Tool->MergingSettings.TargetLightMapResolution, **NewSelection);
}

ECheckBoxState SPolishBuildingsDialog::GetExportSpecificLODEnabled() const
{
	return (Tool->bExportSpecificLOD ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetExportSpecificLODEnabled(ECheckBoxState NewValue)
{
	Tool->bExportSpecificLOD = (NewValue == ECheckBoxState::Checked);
}

bool SPolishBuildingsDialog::IsExportSpecificLODEnabled() const
{
	return Tool->bExportSpecificLOD;
}

void SPolishBuildingsDialog::SetExportSpecificLODIndex(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
	TTypeFromString<int32>::FromString(Tool->ExportLODIndex, **NewSelection);
}

ECheckBoxState SPolishBuildingsDialog::GetImportVertexColors() const
{
	return ( Tool->MergingSettings.bBakeVertexData ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
}

void SPolishBuildingsDialog::SetImportVertexColors(ECheckBoxState NewValue)
{
	Tool->MergingSettings.bBakeVertexData = ( ECheckBoxState::Checked == NewValue );
}

ECheckBoxState SPolishBuildingsDialog::GetPivotPointAtZero() const
{
	return (Tool->MergingSettings.bPivotPointAtZero ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetPivotPointAtZero(ECheckBoxState NewValue)
{
	Tool->MergingSettings.bPivotPointAtZero = (ECheckBoxState::Checked == NewValue);
}

ECheckBoxState SPolishBuildingsDialog::GetReplaceSourceActors() const
{
	return (Tool->bReplaceSourceActors ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetReplaceSourceActors(ECheckBoxState NewValue)
{
	Tool->bReplaceSourceActors = (ECheckBoxState::Checked == NewValue);
}

ECheckBoxState SPolishBuildingsDialog::GetMergePhyisicData() const
{
	return (Tool->MergingSettings.bMergePhysicsData ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetMergePhyisicData(ECheckBoxState NewValue)
{
	Tool->MergingSettings.bMergePhysicsData = (ECheckBoxState::Checked == NewValue);
}

bool SPolishBuildingsDialog::IsMaterialMergingEnabled() const
{
	return Tool->MergingSettings.bMergeMaterials;
}

ECheckBoxState SPolishBuildingsDialog::GetMergeMaterials() const
{
	return (Tool->MergingSettings.bMergeMaterials ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
}

void SPolishBuildingsDialog::SetMergeMaterials(ECheckBoxState NewValue)
{
	Tool->MergingSettings.bMergeMaterials = (ECheckBoxState::Checked == NewValue);
}

ECheckBoxState SPolishBuildingsDialog::GetExportNormalMap() const
{
	return ( Tool->MergingSettings.MaterialSettings.bNormalMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
}

void SPolishBuildingsDialog::SetExportNormalMap(ECheckBoxState NewValue)
{
	Tool->MergingSettings.MaterialSettings.bNormalMap = ( ECheckBoxState::Checked == NewValue );
}

ECheckBoxState SPolishBuildingsDialog::GetExportMetallicMap() const
{
	return ( Tool->MergingSettings.MaterialSettings.bMetallicMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
}

void SPolishBuildingsDialog::SetExportMetallicMap(ECheckBoxState NewValue)
{
	Tool->MergingSettings.MaterialSettings.bMetallicMap = ( ECheckBoxState::Checked == NewValue );
}

ECheckBoxState SPolishBuildingsDialog::GetExportRoughnessMap() const
{
	return ( Tool->MergingSettings.MaterialSettings.bRoughnessMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
}

void SPolishBuildingsDialog::SetExportRoughnessMap(ECheckBoxState NewValue)
{
	Tool->MergingSettings.MaterialSettings.bRoughnessMap = ( ECheckBoxState::Checked == NewValue );
}

ECheckBoxState SPolishBuildingsDialog::GetExportSpecularMap() const
{
	return ( Tool->MergingSettings.MaterialSettings.bSpecularMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
}

void SPolishBuildingsDialog::SetExportSpecularMap(ECheckBoxState NewValue)
{
	Tool->MergingSettings.MaterialSettings.bSpecularMap = ( ECheckBoxState::Checked == NewValue );
}

void SPolishBuildingsDialog::SetMergedMaterialAtlasResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
	TTypeFromString<int32>::FromString( Tool->MergingSettings.MaterialSettings.TextureSize.X, **NewSelection );
	TTypeFromString<int32>::FromString( Tool->MergingSettings.MaterialSettings.TextureSize.Y, **NewSelection );
}


#undef LOCTEXT_NAMESPACE
