/* SPDX-FileCopyrightText: 2005 Blender Authors
 *
 * SPDX-License-Identifier: GPL-2.0-or-later */

#include "node_shader_util.hh"

#include "BLI_math_vector.h"

namespace blender {

namespace nodes::node_shader_bsdf_transparent_cc {

static void node_declare(NodeDeclarationBuilder &b)
{
  const bNodeTree *ntree = b.tree_or_null();
  const bool is_gpu_internal = ntree && (ntree->flag & NTREE_IS_GPU_SHADER_INTERNAL);

  b.add_input<decl::Color>("Color"_ustr).default_value({1.0f, 1.0f, 1.0f, 1.0f});
  b.add_input<decl::Float>("Weight"_ustr).available(is_gpu_internal);
  b.add_output<decl::Shader>("BSDF"_ustr);
}

static int node_shader_gpu_bsdf_transparent(GPUMaterial *mat,
                                            bNode *node,
                                            bNodeExecData * /*execdata*/,
                                            GPUNodeStack *in,
                                            GPUNodeStack *out)
{
  if (in[0].link || !is_zero_v3(in[0].vec)) {
    GPU_material_flag_set(mat, GPU_MATFLAG_TRANSPARENT);

    if (in[0].might_be_tinted()) {
      GPU_material_flag_set(mat, GPU_MATFLAG_TRANSPARENT_MAYBE_COLORED);
    }
  }
  return GPU_stack_link(mat, node, "node_bsdf_transparent", in, out);
}

NODE_SHADER_MATERIALX_BEGIN
#ifdef WITH_MATERIALX
{
  switch (to_type_) {
    case NodeItem::Type::BSDF: {
      NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
      /* Returning diffuse node as BSDF component */
      return create_node("oren_nayar_diffuse_bsdf", NodeItem::Type::BSDF, {{"color", color}});
    }
    case NodeItem::Type::SurfaceOpacity: {
      NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
      /* Returning: 1 - <average of color components> */
      return val(1.0f) - color.dotproduct(val(1.0f / 3.0f));
    }
    default:
      break;
  }
  return empty();
}
#endif
NODE_SHADER_MATERIALX_END

}  // namespace nodes::node_shader_bsdf_transparent_cc

/* node type definition */
void register_node_type_sh_bsdf_transparent()
{
  namespace file_ns = nodes::node_shader_bsdf_transparent_cc;

  static bke::bNodeType ntype;

  sh_node_type_base(&ntype, "ShaderNodeBsdfTransparent"_ustr, SH_NODE_BSDF_TRANSPARENT);
  ntype.ui_name = "Transparent BSDF";
  ntype.ui_description =
      "Transparency without refraction, passing straight through the surface as if there were no "
      "geometry";
  ntype.enum_name_legacy = "BSDF_TRANSPARENT";
  ntype.nclass = NODE_CLASS_SHADER;
  ntype.add_ui_poll = object_shader_nodes_poll;
  ntype.declare = file_ns::node_declare;
  ntype.gather_link_search_ops = search_link_ops_for_shader_bsdf_node;
  ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_transparent;
  ntype.materialx_fn = file_ns::node_shader_materialx;

  bke::node_register_type(ntype);
}

}  // namespace blender
