// Copyright 2021-2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "../openpgl.h"
#include "Region.h"

namespace openpgl
{
namespace cpp
{
/**
 * @brief Class to store information of the current path segment.
 *
 * The PathSegment class stores all required information for a path segment
 * so that a list of succeeding segments (stored in a PathSegmentStorage)
 * can be used to generate SampleData for training the guiding Field.
 *
 */

using PathSegment = PGLPathSegmentData;

OPENPGL_INLINE void Reset(PathSegment *pathSegment)
{
    OPENPGL_ASSERT(pathSegment);
    *pathSegment = PathSegment();
}

OPENPGL_INLINE void SetPosition(PathSegment *pathSegment, const pgl_point3f &position)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->position = position;
}

OPENPGL_INLINE void SetNormal(PathSegment *pathSegment, const pgl_vec3f &normal)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->normal = normal;
}

OPENPGL_INLINE void SetDirectionIn(PathSegment *pathSegment, const pgl_vec3f &directionIn)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->directionIn = directionIn;
}

OPENPGL_INLINE pgl_vec3f GetDirectionIn(PathSegment *pathSegment)
{
    OPENPGL_ASSERT(pathSegment);
    return pathSegment->directionIn;
}

OPENPGL_INLINE void SetPDFDirectionIn(PathSegment *pathSegment, const float &pdfDirectionIn)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->pdfDirectionIn = pdfDirectionIn;
}

OPENPGL_INLINE void SetDirectionOut(PathSegment *pathSegment, const pgl_vec3f &directionOut)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->directionOut = directionOut;
}

OPENPGL_INLINE void SetVolumeScatter(PathSegment *pathSegment, const bool &volumeScatter)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->volumeScatter = volumeScatter;
}

OPENPGL_INLINE void SetScatteringWeight(PathSegment *pathSegment, const pgl_vec3f &scatteringWeight)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->scatteringWeight = scatteringWeight;
}

OPENPGL_INLINE void SetDirectContribution(PathSegment *pathSegment, const pgl_vec3f &directContribution)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->directContribution = directContribution;
}

OPENPGL_INLINE void AddDirectContribution(PathSegment *pathSegment, const pgl_vec3f &directContribution)
{
    OPENPGL_ASSERT(pathSegment);
    pglVec3fAdd(pathSegment->directContribution, directContribution);
}

OPENPGL_INLINE void SetScatteredContribution(PathSegment *pathSegment, const pgl_vec3f &scatteredContribution)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->scatteredContribution = scatteredContribution;
}

OPENPGL_INLINE void AddScatteredContribution(PathSegment *pathSegment, const pgl_vec3f &scatteredContribution)
{
    OPENPGL_ASSERT(pathSegment);
    pglVec3fAdd(pathSegment->scatteredContribution, scatteredContribution);
}

OPENPGL_INLINE void SetMiWeight(PathSegment *pathSegment, const float &miWeight)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->miWeight = miWeight;
}

OPENPGL_INLINE void SetRussianRouletteProbability(PathSegment *pathSegment, const float &russianRouletteSurvivalProbability)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->russianRouletteSurvivalProbability = russianRouletteSurvivalProbability;
}

OPENPGL_INLINE void SetEta(PathSegment *pathSegment, const float &eta)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->eta = eta;
}

OPENPGL_INLINE void SetIsDelta(PathSegment *pathSegment, const bool &isDelta)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->isDelta = isDelta;
}

OPENPGL_INLINE void SetRoughness(PathSegment *pathSegment, const float &roughness)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->roughness = roughness;
}

OPENPGL_INLINE void SetTransmittanceWeight(PathSegment *pathSegment, const pgl_vec3f &transmittanceWeight)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->transmittanceWeight = transmittanceWeight;
}

// This function is deprecated
OPENPGL_INLINE void SetRegion(PathSegment *pathSegment, const Region &region)
{
    OPENPGL_ASSERT(pathSegment);
    pathSegment->regionPtr = (void *)region.m_regionHandle;
}

}  // namespace cpp
}  // namespace openpgl