////////////////////////////////////////////////////////////
//
// ConsoleOutput.h
//
// Optional helper for the console window. The
// GameMode blueprint can use this class to store
// console text as one big string with newlines.
//
// A dirty bit is set whenever text is appended,
// so the blueprint only needs to update the widget
// when the text has actually changed.
//
////////////////////////////////////////////////////////////

#pragma once

#include "Containers/UnrealString.h"
#include "ConsoleOutput.generated.h"

////////////////////////////////////////////////////////////
//
// UlxConsoleOutput
//
// When the lua code executes a print statement, the text
// eventually gets passed to the GameMode blueprint: see
// Docs/Print-Statement-Handling.md for more information.
//
// The GameMode blueprint is expected to create a virtual
// console of some sort to display the print statements.
// This class, ConsoleOutput, is a class that the GameMode
// can optionally use to help implement that virtual console.
//
// This class just collects the print statements and keeps
// a record of what text is in the virtual console.  The
// text is stored as one big string.
//
// This class also contains a 'dirty' bit.  Each time somebody
// appends a line of text to the console, the dirty bit is
// automatically set.  The bit can be checked using 'IsDirty'
// and cleared using 'ClearDirty'.  Assuming that the GameMode
// is maintaining a text widget of some sort, the GameMode
// can transfer the contents of this buffer into the text
// widget only when the dirty bit is set.
//
// Note that the GameMode is not obligated to use this class.
// If the GameMode wants to use some other framework to
// implement the virtual console, that's perfectly fine.
//
////////////////////////////////////////////////////////////

UCLASS(BlueprintType)
class UlxConsoleOutput : public UObject
{
	GENERATED_BODY()

private:
	FString Content;
	bool Dirty;

private:
	// Truncate the console to a reasonable number of lines.
	// The length is hardwired.
	//
	void Truncate();

	// Add a newline if there isn't one.
	//
	// Returns true if it changed anything.
	//
	bool MaybeAppendNewline();

	// Append text.
	// 
	// Returns true if it changed anything.
	//
	bool MaybeAppendText(const FString& text);

public:
	// Append text to the console.
	//
	// If SeparateLine is true, we make sure there's a
	// newline before and after the text.
	//
	UFUNCTION(BlueprintCallable)
	void Append(const FString& text, bool SeparateLine);

	// Get the console text as a string.
	//
	UFUNCTION(BlueprintCallable)
	const FString& Get() const { return Content;  }

	// Return if the dirty flag is set.
	//
	UFUNCTION(BlueprintCallable)
	bool IsDirty() const { return Dirty; }

	// Clear the dirty flag.
	//
	UFUNCTION(BlueprintCallable)
	void ClearDirty() { Dirty = false;  }
};
