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

  Program:   CMB
  Module:    CmbScenePolyline.h

Copyright (c) 1998-2005 Kitware Inc. 28 Corporate Drive, Suite 204,
Clifton Park, NY, 12065, USA.

All rights reserved. No part of this software may be reproduced,
distributed,
or modified, in any form or by any means, without permission in writing from
Kitware Inc.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
=========================================================================*/
// .NAME CmbScenePolyline - represents a contour object.
// .SECTION Description
// .SECTION Caveats

#ifndef __CmbScenePolyline_h
#define __CmbScenePolyline_h


#include "cmbAppCommonExport.h"
#include "pqCMBSceneObjectBase.h"
#include "cmbSystemConfig.h"
#include <set>

class pqRenderView;
class pqServer;
class vtkSMOutputPort;
class pqPipelineSource;
class pqDataRepresentation;
class vtkSMNewWidgetRepresentationProxy;
class vtkSMSourceProxy;
class vtkPVArcInfo;
class vtkIdTypeArray;
class pqCMBPolygon;

class  CMBAPPCOMMON_EXPORT pqCMBArc : public pqCMBSceneObjectBase
{
  typedef pqCMBSceneObjectBase Superclass;
public:
  //Description: Default constructor that than
  //needs createArc called on once its input for arc shape is created
  pqCMBArc();

  //Description: Constructor that takes in the proxy
  //to call createArc on.
  pqCMBArc(vtkSMSourceProxy *proxy);

  virtual ~pqCMBArc();

  //Description:
  //The server side arc has already been created, we just
  //need to create the client side object and the representation.
  //this called after a split operation
  //Note: This doesn't change to make sure the arcId exists on the
  //server so watch out!
  virtual bool createArc(const vtkIdType& arcId);

  //Description:
  //Creates the server side arc from the widget poly data that is passed in
  //this method can only be called once per cmbArc.
  //returns true if it created the arc
  virtual bool createArc(vtkSMNewWidgetRepresentationProxy *widget);

  //Description:
  //Edit this arc representation with the widget proxy passed in
  //this will update the arc state when it is done
  virtual bool editArc(vtkSMNewWidgetRepresentationProxy *widget);

  //Description:
  //Given a selection object find the middle point and use
  //that as the new selection for the arc. This is used when
  //determine the start and end points for editing an arc, when
  //the user want to edit on a section of the arc.
  virtual bool findPickPoint(vtkSMOutputPort *port);

  //Description:
  //Update the server side arc with the new widget proxy shape
  //returns true if it could update the arc
  //filles the passed in vtkIdTypeArray with arcs that need to be created
  virtual bool updateArc(vtkSMNewWidgetRepresentationProxy *widget,
                         vtkIdTypeArray *newlyCreatedArcIds);

  //Description:
  //Update the server with a connection between this arc
  //and the arc that is being passed in
  //Returns the id of the created arc. Will return -1 if we can't connect
  //the arcs
  virtual vtkIdType autoConnect(const vtkIdType& secondArcId);

  virtual pqCMBSceneObjectBase::enumObjectType getType() const;
  virtual bool isDefaultConstrained() const{return true;}
  virtual pqCMBSceneObjectBase *duplicate(pqServer *server, pqRenderView *view,
                                    bool updateRep = true);
  vtkPVArcInfo* getArcInfo();

  vtkIdType getArcId(){return ArcId;}

  bool isClosedLoop();
  int getClosedLoop();

  bool isUsedByPolygons() const
    { return this->PolygonsUsingArc.size() > 0; }

  const std::set< pqCMBPolygon* >& polygonsUsingArc() const
    { return this->PolygonsUsingArc; }

  void inheritPolygonRelationships(pqCMBArc* parent);

  int getPlaneProjectionNormal(){return PlaneProjectionNormal;}
  double getPlaneProjectionPosition(){return PlaneProjectionPosition;}

  void setPlaneProjectionNormal(const int &norm)
      {PlaneProjectionNormal=norm;}
  void setPlaneProjectionPosition(const double &pos)
      {PlaneProjectionPosition=pos;}

  // Overwrite the databounds
  virtual void getDataBounds(double bounds[6]) const
    {this->getBounds(bounds);}

  virtual void setSelectionInput(vtkSMSourceProxy *selectionInput);
  virtual void select();
  virtual void deselect();

  virtual void getColor(double color[4]) const;
  virtual void setColor(double color[4], bool updateRep = true);

  virtual void setMarkedForDeletion();
  virtual void unsetMarkedForDeletion();

  void arcIsModified();
  virtual void updateRepresentation();
protected:
  //make pqCMBPolygon a friend class so that we can have
  //arcs and polygons refresh each other if needed
  friend class pqCMBPolygon;

  void addPolygon(pqCMBPolygon* poly);
  void removePolygon(pqCMBPolygon* poly);

  vtkPVArcInfo *ArcInfo;

  //Description:
  //Creates the server side arc from the proxy poly data that is passed in
  //this method can only be called once per cmbArc.
  //returns true if it created the arc
  virtual bool createArc(vtkSMSourceProxy *proxy);

  virtual void setRepresentation(pqDataRepresentation *rep);
  void updatePlaneProjectionInfo(vtkSMNewWidgetRepresentationProxy *widget);

  // Indicates the projection normal as lying along the
  // XAxis, YAxis, ZAxis, or Oblique. For X, Y, and Z axes,
  // the projection normal is assumed to be anchored at
  // (0,0,0)
  int             PlaneProjectionNormal; // for the bounded plane

  // Indicates a distance from the origin of the projection
  // normal where the project plane will be placed
  double          PlaneProjectionPosition;

  double origColor[4];
  double selColor[4];

  vtkIdType ArcId;

  std::set<pqCMBPolygon*> PolygonsUsingArc;

};
#endif
