/**
 * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
 * MaterialExpressionMaterialFunctionCall - an expression which allows a material to use a material function
 */
class MaterialExpressionMaterialFunctionCall extends MaterialExpression
	native(Material)
	hidecategories(object);

/** The function to call. */
var() MaterialFunction MaterialFunction;

/** Struct that stores information about a function input which is needed to maintain connections and implement the function call. */
struct native FunctionExpressionInput
{
	/** 
	 * Reference to the FunctionInput in the material function.  
	 * This is a reference to a private object so it can't be saved, and must be generated by UpdateFromFunctionResource or SetMaterialFunction. 
	 */
	var transient MaterialExpressionFunctionInput ExpressionInput;

	/** Id of the FunctionInput, used to link ExpressionInput. */
	var guid ExpressionInputId;

	/** Actual input struct which stores information about how this input is connected in the material. */
	var ExpressionInput Input;
};

/** Array of all the function inputs that this function exposes. */
var array<FunctionExpressionInput> FunctionInputs;

/** Struct that stores information about a function output which is needed to maintain connections and implement the function call. */
struct native FunctionExpressionOutput
{
	/** 
	 * Reference to the FunctionOutput in the material function.  
	 * This is a reference to a private object so it can't be saved, and must be generated by UpdateFromFunctionResource or SetMaterialFunction. 
	 */
	var transient MaterialExpressionFunctionOutput ExpressionOutput;

	/** Id of the FunctionOutput, used to link ExpressionOutput. */
	var guid ExpressionOutputId;

	/** Actual output struct which stores information about how this output is connected in the material. */
	var ExpressionOutput Output;
};

/** Array of all the function outputs that this function exposes. */
var array<FunctionExpressionOutput> FunctionOutputs;

cpptext
{
	// UObject interface
	virtual void PreEditChange(UProperty* PropertyAboutToChange);
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent);

	// UMaterialExpression interface
	virtual INT Compile(FMaterialCompiler* Compiler, INT OutputIndex);
	virtual FString GetCaption() const;
	void SwapReferenceTo( UMaterialExpression* OldExpression, UMaterialExpression* NewExpression );
	virtual const TArray<FExpressionInput*> GetInputs();
	virtual FExpressionInput* GetInput(INT InputIndex);
	virtual FString GetInputName(INT InputIndex) const;
	virtual UBOOL IsInputConnectionRequired(INT InputIndex) const;
	virtual void GetConnectorToolTip(INT InputIndex, INT OutputIndex, TArray<FString>& OutToolTip);
	virtual void GetExpressionToolTip(TArray<FString>& OutToolTip);
	virtual UBOOL MatchesSearchQuery( const TCHAR* SearchQuery );

	/** Sets a new material function, given an old function so that links can be passed over if the name matches. */
	void SetMaterialFunction(UMaterialFunction* ThisFunctionResource, UMaterialFunction* OldFunctionResource, UMaterialFunction* NewResource);

	/** 
	 * Updates FunctionInputs and FunctionOutputs from the MaterialFunction.  
	 * This must be called to keep the inputs and outputs up to date with the function being used. 
	 */
	void UpdateFromFunctionResource();

private:
	
	/** Helper that fixes up expression links where possible. */
	void FixupReferencingExpressions(
		const TArray<FFunctionExpressionOutput>& NewOutputs,
		const TArray<FFunctionExpressionOutput>& OriginalOutputs,
		TArray<UMaterialExpression*>& Expressions, 
		TArray<FExpressionInput*>& MaterialInputs,
		UBOOL bMatchByName);
};

defaultproperties
{
	bShowOutputNameOnPin=true
	bHidePreviewWindow=true
	MenuCategories(0)="Functions"
	BorderColor=(R=0,G=116,B=255)
}
