#pragma once
#include "c-opast.hh"
#include "c-opcomp.hh"

#include <ebcl/Algorithms.hh>

struct T_SyncCurves;

namespace opopt {

// Persistent data for the various stages of the optimizer.
struct T_OptData
{
	// Logger
	F_OPLogger logger{ []( auto , auto ) {} };

	// List of errors generated by the optimizer
	T_Array< ebcl::T_SRDError > errors;

	// If the size of the ouput is fixed, this field contains it as a
	// <width,height> pair.
	T_Optional< std::pair< uint32_t , uint32_t > > fixedSize;

	// The curves that will be bound to the inputs.
	T_SyncCurves const* curves{ nullptr };

	// A visitor to be used for the tree
	ebcl::T_Visitor< opast::A_Node > visitor{ opast::ASTVisitorBrowser };

	// Table of input declarations; used to fold constant inputs.
	struct T_InputDecl {
		ebcl::T_SRDLocation location;
		float value;
	};
	T_Optional< T_KeyValueTable< T_String , T_Array< T_InputDecl > > > inputDecls;

	//----------------------------------------------------------------------

	void findInputDecls( T_OpsParserOutput& program ) noexcept;
};

/*----------------------------------------------------------------------------*/

// Attempts to fold constant expressions into single constants. Returns true if
// transformations were made, false if not.
//
bool FoldConstants( T_OpsParserOutput& program ,
		T_OptData& optData ) noexcept;

// Attempt to remove blocks of code that will not be executed because of
// constant conditions. Returns true if transformations were made, false if not.
//
bool RemoveDeadCode( T_OpsParserOutput& program ,
		T_OptData& optData ) noexcept;


} // namespace opopt