//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt 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.
//=========================================================================

// .NAME vtkModelEntityOperationBase - Change properties of model entities.
// .SECTION Description
// Operation to change the color (RGBA), user name and/or visibility of a
// vtkModelEntity.  Also can be used to build or destroy a
// vtkDiscreteModelEntityGroup.

#ifndef __smtkdiscrete_vtkModelEntityOperationBase_h
#define __smtkdiscrete_vtkModelEntityOperationBase_h

#include "smtk/session/discrete/Exports.h" // For export macro
#include "vtkObject.h"

class vtkDiscreteModel;
class vtkModelEntity;

class SMTKDISCRETESESSION_EXPORT vtkModelEntityOperationBase : public vtkObject
{
public:
  static vtkModelEntityOperationBase* New();
  vtkTypeMacro(vtkModelEntityOperationBase, vtkObject);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  // Description:
  // Set/get the model entity unique persistent id to operate on.
  // This is required to be set before calling Operate.
  vtkGetMacro(IsIdSet, int);
  vtkGetMacro(Id, vtkIdType);
  void SetId(vtkIdType id);

  // Description:
  // Set/get the model entity type.  This is not required to be
  // set before calling Operate but makes the lookup of the
  // entity faster.  Derived classes can modify SetItemType
  // if they only deal with specific model entity types.
  vtkGetMacro(IsItemTypeSet, int);
  vtkGetMacro(ItemType, int);
  virtual void SetItemType(int itemType);

  // Description:
  // Functions to set/get the visibility that will be set.
  vtkGetMacro(IsVisibilitySet, int);
  vtkGetMacro(Visibility, int);
  void SetVisibility(int visibility);

  // Description:
  // Functions to set/get the Pickable that will be set.
  vtkGetMacro(IsPickableSet, int);
  vtkGetMacro(Pickable, int);
  void SetPickable(int pickable);

  // Description:
  // Functions to set/get the ShowTexture that will be set.
  vtkGetMacro(IsShowTextureSet, int);
  vtkGetMacro(ShowTexture, int);
  void SetShowTexture(int show);

  // Description:
  // Functions to set/get the RGBA that will be set.
  vtkGetMacro(IsRGBASet, int);
  vtkGetMacro(IsRepresentationRGBASet, int);

  vtkGetMacro(RGBA, double*);
  vtkGetMacro(RepresentationRGBA, double*);

  void SetRGBA(double* Color);
  void SetRGBA(double R, double G, double B, double A);
  void SetRepresentationRGBA(double* Color);
  void SetRepresentationRGBA(double R, double G, double B, double A);

  // Description:
  // Get/Set the name of the ModelEntity.
  vtkSetStringMacro(UserName);
  vtkGetStringMacro(UserName);

  // Description:
  // Return the model entity.
  virtual vtkModelEntity* GetModelEntity(vtkDiscreteModel* Model);

  // Description:
  // Do the basic operation to modify the model.  This should be
  // able to be done on both the server and the client.
  virtual bool Operate(vtkDiscreteModel* Model);

protected:
  vtkModelEntityOperationBase();
  ~vtkModelEntityOperationBase() override;

  // Description:
  // Check to see if everything is properly set for the operator.
  virtual bool AbleToOperate(vtkDiscreteModel* Model);

  // Description:
  // The type of the model entity to be operated on.  This is not
  // required to be set before calling Operate but makes the lookup of the
  // entity faster.  This is protected so that derived classes can
  // set these values in the constructor if desired.
  int ItemType;
  int IsItemTypeSet;

  // Description:
  // Operation will modify Representation color stored in vtkProperty
  // of the ModelWrapper's composite child.
  double RepresentationRGBA[4];
  int IsRepresentationRGBASet;

private:
  // Description:
  // The unique persistent id of the model entity to be operated on.
  // This is required to be set before calling Operate.
  vtkIdType Id;
  int IsIdSet;

  // Description:
  // Operation will modify the vtkModelEntity to be invisible
  // (Visibility=0) or visible (should be Visibility=1).
  int Visibility;
  int IsVisibilitySet;
  int Pickable;
  int IsPickableSet;
  int ShowTexture;
  int IsShowTextureSet;

  // Description:
  // Operation will modify RGBA of the vtkModelEntity.
  double RGBA[4];
  int IsRGBASet;

  // Description:
  // Operation will modify the UserName of the vtkModelEntity
  // if UserName is not NULL.
  char* UserName;

  vtkModelEntityOperationBase(const vtkModelEntityOperationBase&); // Not implemented.
  void operator=(const vtkModelEntityOperationBase&);              // Not implemented.
};

#endif
