// Gnurbs - A curve and surface library
// Copyright (C) 2008-2026 Eric Bechet
//
// See the LICENSE file for contributions and license information.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//


#ifndef __NMESH_H
#define __NMESH_H

#include <set>
#include <vector>

#include "nutil.h"



enum typv {nil,regular_A,regular_B,start,end,separate,fuse};

extern data_container* datap;

struct hedge;

struct cmp_hedge
{
  bool operator()( const hedge * e1,const hedge * e2) const;
};

struct cmp_hedge_len
{
  bool operator()( const hedge * e1,const hedge * e2) const;
};

struct vertex
{
  vertex(): pt(npoint2()),e(0x0),type(nil){};
  vertex(npoint2 pt_): pt(pt_),e(0x0),type(nil){};
  npoint2 pt;
  hedge *e; // any edge starting there
  typv type;
  bool operator < ( const vertex & other ) const // lexico
  {
    if (pt[0]<other.pt[0]) return true;
    if (pt[0]>other.pt[0]) return false;
    if (pt[1]<other.pt[1]) return true;
    return false;
  }
};

typedef std::set<vertex,std::less<vertex> > evt_queue_type;

typedef std::set<hedge*,cmp_hedge> status_type;

typedef std::set<hedge*,cmp_hedge_len> swap_type;

struct hedge
{
  hedge():s(0x0),p(0x0),n(0x0),t(0x0),corr(0x0) {}
  hedge(vertex *s_) : s(s_),p(0x0),n(0x0),t(0x0),corr(0x0) {}
  hedge(vertex *s_,hedge *n_) : s(s_),n(n_),corr(0x0) {}
  vertex *s; //start vertex
  hedge *p;//prev
  hedge *n;//next
  hedge *t;//twin
  mutable vertex *corr; // corresponding vertex
  status_type::iterator sptr; // pointer to status
};

void monotone(std::vector<hedge*> &contour,std::vector<vertex*> &diagonals);
void split(std::vector<hedge*> &contour,std::vector<vertex*> &diagonals); // make sure the diagonals belong to the global half-edge data structure...
void clear_tag(std::vector<hedge*> &contour);
void triangulate_loop(hedge* start, std::vector< vertex* >& tris, std::vector< vertex* >& diagonals);
void triangulate(std::vector<hedge*> &contour,std::vector< vertex* >& tris,bool split=true);
int find_next_loop(std::vector<hedge*> &contour,int start);
void find_all_loops(std::vector<hedge*> &contour,std::vector<hedge*> &loops);
bool legal(hedge *e);
double length(const hedge* e);
void swap(hedge* e,swap_type& set_edges); // swap the edge e (no geo checks are made)

#endif // NMESH