//
// Copyright 2019 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#ifndef PXR_USD_PCP_DYNAMIC_FILE_FORMAT_INTERFACE_H
#define PXR_USD_PCP_DYNAMIC_FILE_FORMAT_INTERFACE_H

#include "pxr/pxr.h"
#include "pxr/usd/pcp/api.h"
#include "pxr/usd/sdf/fileFormat.h"

PXR_NAMESPACE_OPEN_SCOPE

class PcpDynamicFileFormatContext;
class VtValue;

/// \class PcpDynamicFileFormatInterface
///
/// Interface mixin that can be included by SdfFileFormat subclasses to enable
/// dynamic file format argument generation for a file format plugin.
/// When prim index composition encounters a payload to an asset of a file 
/// format that implements this interface, it will call 
/// ComposeFieldsForFileFormatArguments to generate arguments from the current
/// composition context at which the payload is being added. The derived file
/// format is on the hook for using the provided context to compute any prim
/// field values it needs and generate the relevant file format arguments for
/// its content.
class PcpDynamicFileFormatInterface
{
public:
    /// Empty virtual destructor to prevent build errors with some compilers.
    PCP_API
    virtual ~PcpDynamicFileFormatInterface();

    /// Derived classes must implement this function to compose prim metadata 
    /// fields and/or attribute default values using the given \p context and 
    /// use them to generate file format arguments for the layer at 
    /// \p assetPath. 
    ///
    /// The context provides the methods for composing prim metadata field 
    /// values and attribute default values at the current point in prim index 
    /// composition which can be used to generate the relevant file format 
    /// arguments. In the implementation, these arguments need to be added to 
    /// the set of file format arguments provided by \p args. 
    /// 
    /// Additionally, implementations can output \p dependencyContextData of
    /// any value type that will then be passed back in to calls to 
    /// CanFieldChangeAffectFileFormatArguments and 
    /// CanAttributeDefaultValueChangeAffectFileFormatArguments during change 
    /// processing. This can be used to provide more that context that is 
    /// specific to the file format when determining whether a field change 
    /// really does affect the arguments generated by a particular call to this
    /// function.
    PCP_API
    virtual void ComposeFieldsForFileFormatArguments(
        const std::string &assetPath, 
        const PcpDynamicFileFormatContext &context,
        SdfFileFormat::FileFormatArguments *args,
        VtValue *dependencyContextData) const = 0;

    /// Return true if the change to scene description of the field named 
    /// \p field can affect the dynamic file format arguments generated by 
    /// ComposeFieldsForFileFormatArguments. 
    ///
    /// This function will be called during change processing to determine
    /// whether a change to a field affects the dynamic file format arguments of
    /// a payload that a prim index depends on.
    ///
    /// The default implementation always returns true, indicating that any 
    /// value change for a passed in field will require file format arguments to
    /// be recomputed. Derived classes can override this function to be more 
    /// discerning about which changes would truly cause a file format argument
    /// update, reducing the number of unnecessary recompositions of dynamic 
    /// payloads using its file format.
    ///
    /// \p oldValue and \p newValue contain the old and new values of the field.
    /// \p dependencyContextData is the arbitrary typed data that was generated
    /// by the call to ComposeFieldsForFileFormatArguments when the payload arc
    /// was computed.
    PCP_API
    virtual bool CanFieldChangeAffectFileFormatArguments(
        const TfToken &field,
        const VtValue &oldValue,
        const VtValue &newValue,
        const VtValue &dependencyContextData) const;

    /// Return true if the change to scene description of the default field 
    /// for the attribute named \p attributeName can affect the dynamic file 
    /// format arguments generated by ComposeFieldsForFileFormatArguments. 
    /// 
    /// This function will be called during change processing to determine
    /// whether a change to a attribute's default value affects the dynamic file
    /// format arguments of a payload that a prim index depends on.
    ///
    /// The default implementation always returns true, indicating that any 
    /// default value change for a passed in attribute will require file format
    /// arguments to be recomputed. Derived classes can override this function
    /// to be more discerning about which changes would truly cause a file 
    /// format argument update, reducing the number of unnecessary 
    /// recompositions of dynamic payloads using its file format.
    ///
    /// \p oldValue and \p newValue contain the old and new values of the 
    /// default value field. \p dependencyContextData is the arbitrary typed 
    /// data that was generated by the call to 
    /// ComposeFieldsForFileFormatArguments when the payload arc was computed.
    PCP_API
    virtual bool CanAttributeDefaultValueChangeAffectFileFormatArguments(
        const TfToken &attributeName,
        const VtValue &oldValue,
        const VtValue &newValue,
        const VtValue &dependencyContextData) const;
};

PXR_NAMESPACE_CLOSE_SCOPE

#endif // PXR_USD_PCP_DYNAMIC_FILE_FORMAT_INTERFACE_H
