// Copyright (c) 2021 NVIDIA CORPORATION.  All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto.  Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#include <OgnTestUsdCastingDatabase.h>
#include <omni/graph/core/ogn/UsdTypes.h>

namespace omni {
namespace graph {
namespace test {


class OgnTestUsdCasting
{
public:
    static bool compute(OgnTestUsdCastingDatabase& db)
    {
        // The input bundle could contain any of the legal data types so check them all. When a match is found then
        // a copy of the regular input attribute with the same type is added to both the state and output bundles.
        // The type check is not normally needed since the copyData would handle that, but this node's purpose is to
        // exercise those same type checks so do them here.
        auto& outputBundle = db.outputs.a_bundle();
        auto& stateBundle = db.state.a_bundle();
        for (const auto& bundledAttribute : db.inputs.a_bundle())
        {
            const auto& bundledType = bundledAttribute.type();
            bool matchingTypeFound =
                bundledAttribute.get<pxr::GfHalf>()
            ||  bundledAttribute.get<pxr::TfToken>()
            ||  bundledAttribute.get<pxr::SdfTimeCode>()
            ||  bundledAttribute.get<pxr::GfMatrix2d>()
            ||  bundledAttribute.get<pxr::GfMatrix3d>()
            ||  bundledAttribute.get<pxr::GfMatrix4d>()
            ||  bundledAttribute.get<pxr::GfVec2d>()
            ||  bundledAttribute.get<pxr::GfVec2f>()
            ||  bundledAttribute.get<pxr::GfVec2h>()
            ||  bundledAttribute.get<pxr::GfVec2i>()
            ||  bundledAttribute.get<pxr::GfVec3d>()
            ||  bundledAttribute.get<pxr::GfVec3f>()
            ||  bundledAttribute.get<pxr::GfVec3h>()
            ||  bundledAttribute.get<pxr::GfVec3i>()
            ||  bundledAttribute.get<pxr::GfVec4d>()
            ||  bundledAttribute.get<pxr::GfVec4f>()
            ||  bundledAttribute.get<pxr::GfVec4h>()
            ||  bundledAttribute.get<pxr::GfVec4i>()
            ||  bundledAttribute.get<pxr::GfQuatd>()
            ||  bundledAttribute.get<pxr::GfQuatf>()
            ||  bundledAttribute.get<pxr::GfQuath>()
            ||  bundledAttribute.get<pxr::GfHalf[]>()
            ||  bundledAttribute.get<pxr::TfToken[]>()
            ||  bundledAttribute.get<pxr::SdfTimeCode[]>()
            ||  bundledAttribute.get<pxr::GfMatrix2d[]>()
            ||  bundledAttribute.get<pxr::GfMatrix3d[]>()
            ||  bundledAttribute.get<pxr::GfMatrix4d[]>()
            ||  bundledAttribute.get<pxr::GfVec2d[]>()
            ||  bundledAttribute.get<pxr::GfVec2f[]>()
            ||  bundledAttribute.get<pxr::GfVec2h[]>()
            ||  bundledAttribute.get<pxr::GfVec2i[]>()
            ||  bundledAttribute.get<pxr::GfVec3d[]>()
            ||  bundledAttribute.get<pxr::GfVec3f[]>()
            ||  bundledAttribute.get<pxr::GfVec3h[]>()
            ||  bundledAttribute.get<pxr::GfVec3i[]>()
            ||  bundledAttribute.get<pxr::GfVec4d[]>()
            ||  bundledAttribute.get<pxr::GfVec4f[]>()
            ||  bundledAttribute.get<pxr::GfVec4h[]>()
            ||  bundledAttribute.get<pxr::GfVec4i[]>()
            ||  bundledAttribute.get<pxr::GfQuatd[]>()
            ||  bundledAttribute.get<pxr::GfQuatf[]>()
            ||  bundledAttribute.get<pxr::GfQuath[]>();

            if (matchingTypeFound)
            {
                auto newOutput = outputBundle.addAttribute(bundledAttribute.name(), bundledType);
                auto newState = stateBundle.addAttribute(bundledAttribute.name(), bundledType);
                newOutput.copyData(bundledAttribute);
                newState.copyData(bundledAttribute);
            }
        }

        return true;
    }
};

REGISTER_OGN_NODE()

} // namespace test
} // namespace graph
} // namespace omni
