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

  Program:   Visualization Toolkit
  Module:    vtkPTSPropertyManager.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 "vtkPTSPropertyManager.h"
#include "vtkSMProperty.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMPropertyIterator.h"
#include "vtkSMProxy.h"
#include "vtkVariant.h"

class vtkPTSPropertyManager::vtkInternals
{
public:
};

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPTSPropertyManager);
//-----------------------------------------------------------------------------
vtkPTSPropertyManager::vtkPTSPropertyManager()
  : Internals(new vtkPTSPropertyManager::vtkInternals())
{
}
//-----------------------------------------------------------------------------
vtkPTSPropertyManager::~vtkPTSPropertyManager() = default;
//-----------------------------------------------------------------------------
std::vector<vtkVariant> vtkPTSPropertyManager::GetPropertyValue(
  vtkSMProxy* proxy, const std::string& name)
{
  std::vector<vtkVariant> value;
  vtkSMProperty* property = proxy->GetProperty(name.c_str());
  if (!property)
  {
    vtkLogF(ERROR, "unknown property %s for proxy %s", name.c_str(), proxy->GetXMLName());
  }
  vtkSMPropertyHelper helper(property);
  value.resize(helper.GetNumberOfElements());
  for (int i = 0; i < helper.GetNumberOfElements(); i++)
  {
    value[i] = helper.GetAsVariant(i);
  }
  return value;
}

//-----------------------------------------------------------------------------
void vtkPTSPropertyManager::SetPropertyValue(
  vtkSMProxy* proxy, const std::string& name, const vtkVariant& value)
{
  const std::vector<vtkVariant> array({ value });
  this->SetPropertyValue(proxy, name, array);
}

//-----------------------------------------------------------------------------
void vtkPTSPropertyManager::SetPropertyValue(
  vtkSMProxy* proxy, const std::string& name, const std::vector<vtkVariant>& value)
{
  vtkSMProperty* property = proxy->GetProperty(name.c_str());
  if (!property)
  {
    vtkLogF(ERROR, "unknown property %s for proxy %s", name.c_str(), proxy->GetXMLName());
  }
  vtkSMPropertyHelper helper(property);
  if (helper.GetNumberOfElements() != value.size())
  {
    vtkLogF(ERROR, "Size mitsmatch between property %s and vector size: %ld !", name.c_str(),
      value.size());
    return;
  }
  for (unsigned int i = 0; i < helper.GetNumberOfElements(); i++)
  {
    if (helper.GetAsVariant(i) != value[i])
    {
      helper.Set(i, value[i]);
    }
  }
  proxy->UpdateVTKObjects();
}

//-----------------------------------------------------------------------------
void vtkPTSPropertyManager::SetPropertyValueElement(
  vtkSMProxy* proxy, const std::string& name, const vtkVariant& value, int index)
{
  vtkSMProperty* property = proxy->GetProperty(name.c_str());
  if (!property)
  {
    vtkLogF(ERROR, "unknown property %s for proxy %s", name.c_str(), proxy->GetXMLName());
  }
  vtkSMPropertyHelper helper(property);
  if (helper.GetNumberOfElements() <= index)
  {
    vtkLogF(ERROR, "Size mitsmatch between property %s and index: %d !", name.c_str(), index);
    return;
  }
  helper.Set(index, value);
}

//-----------------------------------------------------------------------------
vtkVariant vtkPTSPropertyManager::GetPropertyValueElement(
  vtkSMProxy* proxy, const std::string& name, int index)
{
  vtkSMProperty* property = proxy->GetProperty(name.c_str());
  if (!property)
  {
    vtkLogF(ERROR, "unknown property %s for proxy %s", name.c_str(), proxy->GetXMLName());
  }
  vtkSMPropertyHelper helper(property);
  vtkVariant value = helper.GetAsVariant(index);
  return value;
}

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