/* $Id: boxdefs.h,v 1.1.1.1 1996/10/02 10:35:48 roitzsch Exp $ */

#ifndef BOXDEFS_H
#define BOXDEFS_H


#define ZERO 0.0
#define ONE 1.0

#define REALPI  (3.14159265358979323846)
#define REALPI2  (1.57079632679489661923)

#define eps 1.0e-5

typedef char* ptr;

/*-------------------------------------------------------------------------*/
#include "boxeslists.h"
/*-------------------------------------------------------------------------*/


#define INTERIOR 0
#define DIRICHLET 1
#define NEUMANN 2
#define CAUCHY 3
#define NOTHING -1

#define WHITE_REFINED 0
#define RED_REFINED 1
#define BLUE_REFINED 2
#define GREEN_REFINED 3

#define LEFT_BOTTOM 1   
#define RIGHT_BOTTOM 2  
#define RIGHT_TOP 3     
#define LEFT_TOP 4      

#define LBRT 0  
#define LTRB 1  


#define MAX_BOX_LIST 5

#define POINT_GROUP 100
#define EDGE_GROUP 100
#define TRIANGLE_GROUP 100
#define BOX_GROUP 100


typedef struct _PT
{
    xreal x,y,sol;
    int id,boundary_type,point_class,valid;
    struct _BX*b1,*b2,*b3,*b4;
    struct _EDG*e1,*e2,*e3,*e4;
    struct _PT*next,*last;
} point;


typedef struct _EDG
{
    point*p1,*p2,*pm,*circle_midpoint;
    int id,boundary_type,edge_class,blue_diagonal,
    unvalid,is_green_father,is_first_green_son,
    inner_boundary,dummy;
    struct _BX*b1,*b2;
    xreal div_factor,lng;
    struct _EDG*next,*last,*father,*son1,*son2;
} edge;


typedef struct _TR 
{
    point*p1,*p2,*p3;
    edge*e1,*e2,*e3;
    int id,area_class,refinement_type,level;
    xreal area,a1,a2,a3;
    struct _TR*next,*last,*partner,*father,*s1,*s2,*s3,*s4;
} triangle;


typedef struct _BX
{
    point*p1,*p2,*p3,*p4,*pm1,*pm2,*pm3,*pm4;
    edge*e1,*e2,*e3,*e4;
    triangle*t1,*t2,*t3;
    int id,area_class,second_area_class,coarse_type,quarter_circle;
    struct _BX*b11,*b21,*b31,*b41,*b12,*b22,*b32,*b42;
    struct _BX*next,*last;
} box;

/*------------------------    macros   -------------------------*/

#define EDGES_OF_POINT(P) (&((P)->e1))
#define POINTS_OF_BOX(B) (&((B)->p1))
#define EDGES_OF_BOX(B) (&((B)->e1))
#define NEIGHBORS_OF_BOX(B) (&((B)->b11))
#define EDGES_OF_TRIANGLE(T) (&((T)->e1))
#define POINTS_OF_TRIANGLE(T) (&((T)->p1))


#define EDGE_LENGTH(ED) sqrt(((((ED)->p1)->x-((ED)->p2)->x)*\
(((ED)->p1)->x-((ED)->p2)->x))+\
((((ED)->p1)->y-((ED)->p2)->y)*\
(((ED)->p1)->y-((ED)->p2)->y)))

#define PTS_LEN(P1,P2) sqrt((((P1)->x-(P2)->x)*\
((P1)->x-(P2)->x))+\
(((P1)->y-(P2)->y)*\
((P1)->y-(P2)->y)))


#define SON_AT(E,P,P_ALT)\
((((E)->p1)==(P))?(E)->son1:(((E)->p2)==(P))?(E)->son2:\
(((E)->p1)==(P_ALT))?(E)->son2:(((E)->p2)==(P_ALT))?(E)->son1:(E)->son1)

#define NOT_IN_TRIANGLE(P,T) (((T->p1)!=(P))&&(((T)->p2)!=(P))&&(((T)->p3)!=(P)))
#define IN_TRIANGLE(P,T) (((T->p1)==(P))||(((T)->p2)==(P))||(((T)->p3)==(P)))

#define OPPO_EDG(T,ED) ((((T)->e1)==(ED))?(T)->p1:((((T)->e2)==(ED))?(T)->p2:(T)->p3))
#define OPPO_PT(T,P) ((((T)->p1)==(P))?(T)->e1:((((T)->p2)==(P))?(T)->e2:(T)->e3))

#define EDG_NO_IN_TRIANGLE(ED,T) ((((T)->e1)==(ED))?0:(((T)->e2)==(ED))?1:2)

#define REPLACE_EDGE_IN_BOX(E1,B,E2) if(((B)->e1)==(E1))(B)->e1= (E2);\
else if(((B)->e2)==(E1))(B)->e2= (E2);\
else if(((B)->e3)==(E1))(B)->e3= (E2);\
else if(((B)->e4)==(E1))(B)->e4= (E2);



#define GET_POINT ((point*) Get_Elem((int) point_list))
#define RETURN_POINT(P) Return_Elem((int) point_list, P)

#define GET_EDGE ((edge*) Get_Elem((int) edge_list))
#define RETURN_EDGE(ED) Return_Elem((int) edge_list, (ptr*) ED)

#define GET_TRIANGLE ((triangle*) Get_Elem((int) triangle_list))
#define RETURN_TRIANGLE(T) Return_Elem((int) triangle_list,T)

#define GET_BOX ((box*) Get_Elem((int) box_list))
#define RETURN_BOX(B) Return_Elem((int) box_list, B)

#endif
