/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkRIBProperty.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkRIBProperty.h"
#include "vtkObjectFactory.h"

vtkStandardNewMacro(vtkRIBProperty);

vtkRIBProperty::vtkRIBProperty ()
{
  this->Declarations = nullptr;
  this->SurfaceShaderParameters = nullptr;
  this->DisplacementShaderParameters = nullptr;
  this->SurfaceShader = new char[strlen("plastic") + 1];
  strcpy (this->SurfaceShader, "plastic");
  this->DisplacementShader = nullptr;
  this->SurfaceShaderUsesDefaultParameters = true;

  // create a vtkProperty that can be rendered
  this->Property = vtkProperty::New ();
}

vtkRIBProperty::~vtkRIBProperty()
{
  delete [] this->SurfaceShader;
  delete [] this->DisplacementShader;
  delete [] this->Declarations;

  if (this->Property)
  {
    this->Property->Delete ();
  }

  delete [] this->SurfaceShaderParameters;
  delete [] this->DisplacementShaderParameters;
}

void vtkRIBProperty::Render(vtkActor *anActor, vtkRenderer *ren)
{
  int ref;

  // Copy this property's ivars into the property to be rendered
  ref = this->Property->GetReferenceCount();
  this->Property->DeepCopy(this);
  this->Property->SetReferenceCount(ref);

  // Render the property
  this->Property->Render (anActor, ren);
}

void vtkRIBProperty::SetVariable (const char *variable, const char *value)
{
  delete [] this->Declarations;

  // format of line is: Declare "variable" "type"\n
  size_t length = strlen ("Declare ") +
                  strlen (variable) +
                  strlen (value) +
                  8;
  this->Declarations = new char [length];

  snprintf (this->Declarations, length, "Declare \"%s\" \"%s\"\n", variable, value);
  this->Modified ();
}

void vtkRIBProperty::AddVariable (const char *variable, const char *value)
{
  if (this->Declarations == nullptr)
  {
    this->SetVariable (variable, value);
  }
  else
  {
    size_t length = strlen ("Declare ") +
                    strlen (variable) +
                    strlen (value) +
                    8;
    char *newVariable = new char [length];

    snprintf (newVariable, length, "Declare \"%s\" \"%s\"\n", variable, value);
    char *oldDeclarations = this->Declarations;

    this->Declarations = new char [strlen (oldDeclarations) + strlen (newVariable) + 1];
    strcpy (this->Declarations, oldDeclarations);
    strcat (this->Declarations, newVariable);
    delete [] oldDeclarations;
    delete [] newVariable;
    this->Modified ();
  }
}

void vtkRIBProperty::SetParameter (const char *parameter, const char *value)
{
  vtkWarningMacro("vtkRIBProperty::SetParameter is deprecated. Using SetSurfaceShaderParameter instead.");
  this->SetSurfaceShaderParameter(parameter, value);
}

void vtkRIBProperty::SetSurfaceShaderParameter (const char *parameter, const char *value)
{
  delete [] this->SurfaceShaderParameters;

  // format of line is: "parameter" "value"
  size_t length = strlen (parameter) +
                  strlen (value) +
                  7;
  this->SurfaceShaderParameters = new char [length];

  snprintf (this->SurfaceShaderParameters, length, " \"%s\" [%s]", parameter, value);
  this->Modified ();
}

void vtkRIBProperty::SetDisplacementShaderParameter (const char *parameter, const char *value)
{
  delete [] this->DisplacementShaderParameters;

  // format of line is: "parameter" "value"
  size_t length = strlen (parameter) +
                   strlen (value) +
                   7;
  this->DisplacementShaderParameters = new char [length];

  snprintf (this->DisplacementShaderParameters, length, " \"%s\" [%s]", parameter, value);
  this->Modified ();
}

void vtkRIBProperty::AddParameter (const char *parameter, const char *value)
{
  vtkWarningMacro("vtkRIBProperty::AddParameter is deprecated. Using AddSurfaceShaderParameter instead.");
  this->AddSurfaceShaderParameter(parameter, value);
}

void vtkRIBProperty::AddSurfaceShaderParameter (const char *SurfaceShaderParameter, const char *value)
{
  if (this->SurfaceShaderParameters == nullptr)
  {
    this->SetSurfaceShaderParameter (SurfaceShaderParameter, value);
  }
  else
  {
    size_t length = strlen (SurfaceShaderParameter) +
                    strlen (value) +
                    7;
    char *newSurfaceShaderParameter = new char [length];

    snprintf (newSurfaceShaderParameter, length, " \"%s\" [%s]", SurfaceShaderParameter, value);
    char *oldSurfaceShaderParameters = this->SurfaceShaderParameters;

    this->SurfaceShaderParameters = new char [strlen (oldSurfaceShaderParameters) + strlen (newSurfaceShaderParameter) + 1];
    strcpy (this->SurfaceShaderParameters, oldSurfaceShaderParameters);
    strcat (this->SurfaceShaderParameters, newSurfaceShaderParameter);
    delete [] oldSurfaceShaderParameters;
    delete [] newSurfaceShaderParameter;
    this->Modified ();
  }
}

void vtkRIBProperty::AddDisplacementShaderParameter (const char *DisplacementShaderParameter, const char *value)
{
  if (this->DisplacementShaderParameters == nullptr)
  {
    this->SetDisplacementShaderParameter (DisplacementShaderParameter, value);
  }
  else
  {
    size_t length = strlen (DisplacementShaderParameter) +
                    strlen (value) +
                    7;
    char *newDisplacementShaderParameter = new char [length];

    snprintf (newDisplacementShaderParameter, length, " \"%s\" [%s]", DisplacementShaderParameter, value);
    char *oldDisplacementShaderParameters = this->DisplacementShaderParameters;

    this->DisplacementShaderParameters = new char [strlen (oldDisplacementShaderParameters) + strlen (newDisplacementShaderParameter) + 1];
    strcpy (this->DisplacementShaderParameters, oldDisplacementShaderParameters);
    strcat (this->DisplacementShaderParameters, newDisplacementShaderParameter);
    delete [] oldDisplacementShaderParameters;
    delete [] newDisplacementShaderParameter;
    this->Modified ();
  }
}

char *vtkRIBProperty::GetParameters ()
{
  vtkWarningMacro("vtkRIBProperty::GetParameters is deprecated. Using GetSurfaceShaderParameter instead.");
  return this->GetSurfaceShaderParameters();
}

char *vtkRIBProperty::GetSurfaceShaderParameters ()
{
  return this->SurfaceShaderParameters;
}

char *vtkRIBProperty::GetDisplacementShaderParameters ()
{
  return this->DisplacementShaderParameters;
}

char *vtkRIBProperty::GetDeclarations ()
{
  return this->Declarations;
}

void vtkRIBProperty::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  if (this->SurfaceShader)
  {
    os << indent << "SurfaceShader: " << this->SurfaceShader << "\n";
  }
  else
  {
    os << indent << "SurfaceShader: (none)\n";
  }
  if (this->DisplacementShader)
  {
    os << indent << "DisplacementShader: " << this->DisplacementShader << "\n";
  }
  else
  {
    os << indent << "DisplacementShader: (none)\n";
  }
  if (this->Declarations)
  {
    os << indent << "Declarations: " << this->Declarations;
  }
  else
  {
    os << indent << "Declarations: (none)\n";
  }
  if (this->SurfaceShaderParameters)
  {
    os << indent << "SurfaceShaderParameters: " << this->SurfaceShaderParameters;
  }
  else
  {
    os << indent << "SurfaceShaderParameters: (none)\n";
  }
  if (this->DisplacementShaderParameters)
  {
    os << indent << "DisplacementShaderParameters: " << this->DisplacementShaderParameters;
  }
  else
  {
    os << indent << "DisplacementShaderParameters: (none)\n";
  }
  os << indent << "SurfaceShaderUsesDefaultParameters: "
     << this->GetSurfaceShaderUsesDefaultParameters() << std::endl;
}

