//=========================================================================
//  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 pqCMBLIDARPieceObject - represents a 3D LIDAR preview piece object.
// .SECTION Description
// .SECTION Caveats

#ifndef __pqCMBLIDARPieceObject_h
#define __pqCMBLIDARPieceObject_h

#include "cmbAppCommonExport.h"
#include <QPointer>
#include "vtkBoundingBox.h"
#include <string>
#include "cmbSystemConfig.h"

class pqPipelineSource;
class pqDataRepresentation;
class pqRenderView;
class pqServer;
class vtkTransform;
class vtkSMProxy;
class vtkSMSourceProxy;

class  CMBAPPCOMMON_EXPORT pqCMBLIDARPieceObject
{
public:
  pqCMBLIDARPieceObject();
  virtual ~pqCMBLIDARPieceObject();

  void setSource(pqPipelineSource *source);
  pqPipelineSource * getSource() const;

  void setThresholdSource(pqPipelineSource *thresholdSource);
  pqPipelineSource * getThresholdSource() const;
  void setContourSource(pqPipelineSource *thresholdSource);
  pqPipelineSource * getContourSource() const;
  pqPipelineSource * getDiggerSource() const;
  pqPipelineSource * getElevationSource() const;

  void setRepresentation(pqDataRepresentation *rep);
  pqDataRepresentation * getRepresentation() const;

  void setFileName(const char *filename)
    {this->FileName = filename;}
  std::string getFileName() const
    {return this->FileName;}

  void setPieceName(const char *name)
    {this->PieceName = name;}
  std::string getPieceName() const
    {return this->PieceName;}

  //void setVisibility(bool mode);
  void updateRepresentation();

  void setElevationFilterLowPoint(double *lowPoint);
  void setElevationFilterHighPoint(double *lowPoint);
  void useElevationFilter(bool useElevation);

  void setPieceIndex(int pieceIdx);
  int getPieceIndex() { return this->PieceIndex;}
  int getDisplayOnRatio() {return this->DisplayOnRatio;}
  void setDisplayOnRatio(int ratio);
  int getSaveOnRatio() {return this->SaveOnRatio;}
  void setSaveOnRatio(int ratio);
  int getNumberOfPoints() { return this->TotalNumberOfPiecePoints;}
  void setNumberOfPoints(int numPts)
    { this->TotalNumberOfPiecePoints = numPts;}
  //int getFileOffset() {return this->FileOffset;}
  //void setFileOffset(int offset)
  //  { this->FileOffset = offset;}
  void setLODMode(int mode, bool updateRep);

  int getReadOnRatio() {return this->ReadOnRatio;}
  void setReadOnRatio(int ratio);

  int getNumberOfReadPoints()
    { return this->NumberOfReadPoints; }
  void setNumberOfReadPoints(int numPoints)
    { this->NumberOfReadPoints = numPoints; }

  //QTableWidgetItem* getWidget()
  //{ return this->Widget;}
  //void setWidget(QTableWidgetItem* widget)
  //{ this->Widget = Widget; }

  static pqCMBLIDARPieceObject *createObject(pqPipelineSource *source,
                                            double *bounds,
                                            pqServer *server, pqRenderView *view,
                                            bool updateRep = true);

  void zoomOnObject();
  void getBounds(double bounds[6]) const;
  int getVisibility()
    { return this->Visibility; }
  void setVisibility(int visible);
  int getHighlight()
    { return this->Highlight; }
  void setHighlight( int highlight);
  void setSelectionInput(vtkSMSourceProxy* selInput);

  void setClipBounds(double xMin, double xMax, double yMin, double yMax,
    double zMin, double zMax)
    { this->ClippingBounds.SetBounds(xMin, xMax, yMin, yMax, zMin, zMax); }
  void setClipBounds(double bounds[6])
    { this->ClippingBounds.SetBounds(bounds); }
  bool areClippingBoundsEqual(vtkBoundingBox &bbox)
    { return bbox == this->ClippingBounds; }
  bool isClipTransformationUnchanged();
  bool isThresholdTransformationUnchanged();

  bool getClipState()
    { return this->ClipState; }
  void setClipState(bool clipState)
    { this->ClipState = clipState; }

  bool isObjectUpToDate(bool clipEnabled, vtkBoundingBox &clipBBox);
  bool isClipUpToDate(bool clipEnabled, vtkBoundingBox &clipBBox);

  void setNumberOfDisplayPointsEstimate(int numPoints)
    { this->NumberOfDisplayPointsEstimate = numPoints; }
  int getNumberOfDisplayPointsEstimate()
    { return this->NumberOfDisplayPointsEstimate; }

  void setNumberOfSavePointsEstimate(int numPoints)
    { this->NumberOfSavePointsEstimate = numPoints; }
  int getNumberOfSavePointsEstimate()
    { return this->NumberOfSavePointsEstimate; }

  void getPosition(double pos[3]) const;
  void setPosition(double pos[3], bool updateRep = true);
  void getOrientation(double ori[3]) const;
  void setOrientation(double ori[3], bool updateRep = true);
  void getScale(double scale[3]) const;
  void setScale(double scale[3], bool updateRep = true);
  void getOrigin(double origin[3]) const;
  void setOrigin(double origin[3], bool updateRep = true);

  void saveClipPosition();
  void saveClipOrientation();
  void saveClipScale();
  void saveClipOrigin();

  void saveThresholdPosition();
  void saveThresholdOrientation();
  void saveThresholdScale();
  void saveThresholdOrigin();

  bool isPieceTransformed();
  void getTransform(vtkTransform *transform) const;

  void updateThresholdUseFilter(int idx, int useFilter);
  void updatePolygonUseFilter(int idx, int useFilter);
  void updatePolygonInvert(int idx, int invert);
  void updatePolygonROI(int idx, int roi);

  void updateGroupInvert(int groupIdx, int invert);

  void resetWithNoThresholds(bool update=true);
  void resetWithNoContours(bool update=true);

  void addThreshold();
  void addContour(vtkSMProxy* implicitLoop);
  void removeThreshold();
  void removeContour(vtkSMProxy* implicitLoop);

  void clearThresholds();
  void clearContours();
  bool hasActiveFilters();
  void setActiveContourGroup(int);

protected:

  void init();
  void updateProxyProperty(pqPipelineSource*, const char* name,
    int idx, int val);

  QPointer<pqPipelineSource> Source;
  QPointer<pqPipelineSource> ContourSource;
  QPointer<pqPipelineSource> DiggerSource;
  QPointer<pqPipelineSource> ThresholdSource;
  QPointer<pqPipelineSource> ElevationSource;
  QPointer<pqDataRepresentation> Representation;
  std::string FileName;
  std::string PieceName;
  int PieceIndex;
  int DisplayOnRatio;
  int SaveOnRatio;
  int ReadOnRatio;
  int TotalNumberOfPiecePoints;
  int NumberOfReadPoints;
  int NumberOfDisplayPointsEstimate;
  int NumberOfSavePointsEstimate;
  //int FileOffset;
  int Visibility;
  int Highlight;
  //QTableWidgetItem* Widget;
  double HighlightColor[3];
  double OriginalColor[3];
  bool ClipState;
  bool UseElevationFilter;
  vtkBoundingBox ClippingBounds;

  double ClipOrigin[3];
  double ClipPosition[3];
  double ClipScale[3];
  double ClipOrientation[3];

  double ThresholdOrigin[3];
  double ThresholdPosition[3];
  double ThresholdScale[3];
  double ThresholdOrientation[3];
};

#endif /* __pqCMBLIDARPieceObject_h */
