/* vmaster.h */
/* This program takes 3d model data and constructs a 2d view for
 * subsequent plotting.                                  */
/* #cxe- Wed Apr 10 18:10:10 PDT 2002 */
/* $Date: 2002/04/24 09:31:36 $ - $Revision: 1.3 $ */

#include <getopt.h>

/* #include "../vector.h" */

#include "camera.h"
#include "cxe_inputline.h"

const float MINVAL=0.00005;
const float MINANGVAL=0.0005;

/* Declare global fucntions */
void dealwithoptions(int optc, char **optv, camera &firstcam);
Vector getnextasvector(cxe_inputline &inputnow);
Vector getnextasvector(cxe_finputline &inputnow);

class Plist {
public:
 Plist();
/* ~Plist();    use default */
 bool islast();
 Plist* searchfor(Vector); /* Null if not found */
 Plist* searchfor(unsigned int Pnum); /* Null if not found */
 Vector querypoint();
 Vector editpoint(Vector);
 unsigned int querypnum();
 Plist* querylink();
 void setup(unsigned int, Vector, Plist *); 
 void linkredirect(Plist *nextone);

private:
 unsigned int Pnumber;
 Vector P;
 Plist *link;
};

/* Class of Redundant points i.e. point 3 and 6 both = (1,2,3) */
/* This will be used to optimize. Requests for the redundantly specified */
/* point can be redirected to the first specification of that location. */
/* After input phase, the redundant list can be deleted. */
class Redlist : public Plist {
public:
Redlist* queryredlink();
  void setredlink(Redlist *);
  bool islast(); /* needs redefine because we use a different link */
private:
/* Use Plist's link for symbolic link to first */
  Redlist *redlink;
};

class Llist {
public:
 bool islast();
 Plist* queryA();
 Plist* queryB();
 Vector querypointA();
 Vector querypointB();
 unsigned int querypnumA();
 unsigned int querypnumB();
 Llist* querylink();
 void setup(Plist *A, Plist *B, Llist *link); 
 void setupA(Plist *a);
 void setupB(Plist *b);
 void setlink(Llist *l);
 void printXY(ostream *os);

/* Not done!!!!!!!! */
 Llist* searchfor(unsigned int Pnum); /* Null if not found */

  
protected:
 Plist *A, *B;
 Llist *link;
};


/* This is needed for the HLR and must be here before the Tlist class... */
/* It contains the values used to do the HLR operations based on the */
/* interactions of a line and a triface. */
typedef struct { float Ax, Ay, Azl, Azt,
               Bx, By, Bzl, Bzt,
               Px, Py, Pz,
               C1x, C1y, C1zl, C1zt,
               C2x, C2y, C2zl, C2zt; } line_tri_int_values ;

/* CLASS Triface list */
class Tlist : public Llist {
public:
 bool islast();
 Plist* queryC();
 Vector querypointC();
 unsigned int querypnumC();
 Tlist* querylink();
 void setup(Plist *A, Plist *B, Plist *C, Tlist *link); 
 void setlink(Tlist *l);
 bool trionedge();
 bool BBinterfere(Llist *L);
 int  line_interact(Llist *L, line_tri_int_values &t_l);

private:
  Plist *C;
  Tlist *link;
};

ostream &operator<<(ostream &os, Llist *L);

Plist* addpoint(unsigned int N, Vector P, Plist *prev);

Redlist* addREDpoint(unsigned int N, Vector P,
                      Plist *shouldbe, Redlist *prev);

Llist* addline(Plist *A, Plist *B,
    unsigned int iA, unsigned int iB, Llist *prev);

Tlist* addtri(Plist *A, Plist *B, Plist *C,
  unsigned int iA, unsigned int iB, unsigned int iC, Tlist *prev);

void kill_entire_Plist(Plist *baseoflist);

void kill_entire_REDlist(Redlist *baseoflist);

void kill_entire_Llist(Llist *baseoflist);

void kill_entire_Tlist(Tlist *baseoflist);

Plist* find_matching_vector(Vector V, Plist *list2search);

Plist* find_matching_pnum(unsigned int N, Plist *list2search);

Redlist* find_matching_pnum_inRED(unsigned int N, Redlist *list2search);

Plist* useredlist(unsigned int N, Plist *node, Redlist *redpts);

Llist* searchlinelist(Plist *Anode, Plist *Bnode, Llist *lines);

Tlist* searchtrilist(Plist *Anode, Plist *Bnode, Plist *Cnode, Tlist *tris); 

Plist* setupview(Plist *Pnode, camera &c);

Llist* hlr(Plist *all, Llist *all, Tlist *all, camera cam);

Llist* shallowanglecull(Llist *allL, Tlist *allT, float ang, char *hids);

/* Stuff that only is needed by hlr routine (could/should be hlr.h) */

bool BBinthelper(float lA, float lB, float tA, float tB, float tC );

bool intersection_2d(Vector &LA, Vector &LB, Vector &TA, Vector &TB,
                     float &Cx, float &Cy, float &Czl, float &Czt);

float zvalbetween2pts(Vector LA, Vector LB, float Cx, float Cy);

bool is_within_angle(Vector LA, Vector TB, Vector TA, Vector TC);
bool is_within_or_on_angle(Vector LA, Vector TB, Vector TA, Vector TC);

bool rlte(float A, float B);
bool rgte(float A, float B);
bool req(float A, float B);

float Z_on_tri_from_xy(Tlist *T, float x, float y);

unsigned int piercepoint
      (Tlist *T, Vector A, Vector B, line_tri_int_values &t_l );

bool crosses_at_vertex(Vector LA, Vector LB, Vector TA, Vector TB, Vector TC,
                          float Cx, float Cy );

bool xnor(bool m, bool n);
