/*
    C++ Mesh Generation Library
    Copyright (c) 2000-2026 Eric Bechet <eric at bechet dot ca>

    This file is part of the C++ Mesh Generation Library.

    See the NOTICE & LICENSE files for conditions.
*/
#ifndef PCNODE_H
#define PCNODE_H

#include "Node.h"

using namespace std;

namespace FM
{
  enum status {
    fix = 0, inNB = 1, ukn = 2
  };

  enum topology {
    def = 0, onEdge = 1, vertex = 2
  };

  struct edge {
    int edgeIdx;
    double normal[3];
  };

  class PCNode : public Node
  {
  protected:
    double grad[3]; // distance gradient
    double val; //stored value (distance or else)
    status stat;
    topology geo;
    edge edges[2]; // list of the edges of the node

  public:
    double pos[3]; // coordinates
    double n[3]; // geometric normal
    double pcv[3]; // principal curv vec (other one is n^pcv
    double pc1,pc2; // principal curvatures
    PCNode() {pos[0]=0.;pos[1]=0.;pos[2]=0.;val=0.0; stat=ukn; setGradient(0,0,0); geo=def;}
    PCNode(double x,double y,double z) {pos[0]=x;pos[1]=y;pos[2]=z;val=0.0;stat=ukn; setGradient(0,0,0); geo=def;}
    virtual void GetPos ( double& x,double &y,double &z ) const {x=pos[0];y=pos[1];z=pos[2];}
    virtual void SetPos ( double& x,double &y,double &z ) {pos[0]=x;pos[1]=y;pos[2]=z;}
    void setVal (double val_) { val = val_;}
    double getVal() const { return val; }
    void setStatus (status stat_) { stat = stat_;}
    status getStatus() const { return stat; }

    virtual bool operator < ( const Node& other ) const 
    { 
      double pos2[3];
      other.GetPos(pos2[0],pos2[1],pos2[2]);
      if (pos[0]<pos2[0]) return true;
      if (pos2[0]<pos[0]) return false;
      if (pos[1]<pos2[1]) return true;
      if (pos2[1]<pos[1]) return false;
      if (pos[2]<pos2[2]) return true;
      return false; //equal or >
    }

    void getGradient(double &x,double &y,double &z) const { x=grad[0]; y=grad[1]; z=grad[2];}
    void setGradient(double x,double y,double z) { grad[0]=x; grad[1]=y; grad[2]=z;}

    topology getTopology() const {return geo;}
    void setTopology(topology topol) {geo=topol;}
    
  };

}
#endif //PCNODE_H
