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

Program:   Visualization Toolkit

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.

=========================================================================*/
/**
* @class   vtkOpenVRModel
* @brief   OpenVR device model

* This internal class is used to load models
* such as for the trackers and controllers and to
* render them in the scene
*/

#ifndef vtkOpenVRModel_h
#define vtkOpenVRModel_h

#include "vtkRenderingOpenVRModule.h" // For export macro
#include "vtkObject.h"
#include "vtkOpenGLHelper.h" // ivar
#include "vtkNew.h" // for ivar
#include <openvr.h> // for ivars

class vtkOpenVRRenderWindow;
class vtkRenderWindow;
class vtkOpenGLVertexBufferObject;
class vtkTextureObject;
class vtkMatrix4x4;
class vtkOpenVRRay;

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

  bool Build(vtkOpenVRRenderWindow *win);
  void Render(vtkOpenVRRenderWindow *win,
    const vr::TrackedDevicePose_t &pose);

  const std::string & GetName() const {
    return this->ModelName;
  }
  void SetName(const std::string & modelName) {
    this->ModelName = modelName;
  };

  // show the model
  void SetVisibility(bool v) {
    this->Visibility = v;
  };
  bool GetVisibility() {
    return this->Visibility;
  };

  //Set Ray parameters
  void SetShowRay(bool v);
  void SetRayLength(double length);
  vtkOpenVRRay *GetRay() { return this->Ray; }

  void ReleaseGraphicsResources(vtkRenderWindow *win);

  // the tracked device this model represents if any
  vr::TrackedDeviceIndex_t TrackedDevice;

  vr::RenderModel_t *RawModel;

protected:
  vtkOpenVRModel();
  ~vtkOpenVRModel()  override;

  std::string ModelName;

  bool Visibility;
  bool Loaded;
  bool FailedToLoad;

  vr::RenderModel_TextureMap_t *RawTexture;
  vtkOpenGLHelper ModelHelper;
  vtkOpenGLVertexBufferObject *ModelVBO;
  vtkNew<vtkTextureObject> TextureObject;
  vtkNew<vtkMatrix4x4> PoseMatrix;

  //Controller ray
  vtkNew<vtkOpenVRRay> Ray;

private:
  vtkOpenVRModel(const vtkOpenVRModel&) = delete;
  void operator=(const vtkOpenVRModel&) = delete;
};

#endif
