MODULE QuadEdge;

IMPORT Octf, Stdio, Wr, Thread;

FROM Octf IMPORT Fnext, Spin, Clock, Enext_1, SpliceEdges, SpliceFacets,
                 MakeFacetEdge;


(* ================= Function's QuadEdge ========= *)

PROCEDURE Flip(s : Arc) : Arc =
  BEGIN
    IF s.d = 0 THEN RETURN Arc{pair := Spin(Fnext(s.pair)), d := 0};
               ELSE RETURN Arc{pair := Clock(Spin(s.pair)), d := 1};
    END;
  END Flip;

PROCEDURE Sym(s : Arc): Arc =
  BEGIN
    IF s.d = 0 THEN RETURN Arc{pair := Clock(Fnext(s.pair)), d := 0};
               ELSE RETURN Arc{pair := Clock(Fnext(s.pair)), d := 1};
    END;
  END Sym;

PROCEDURE Sym_(s : Arc): Arc =
  BEGIN
    IF s.d = 0 THEN RETURN Arc{pair := Fnext(s.pair), d := 0};
               ELSE RETURN Arc{pair := Fnext(s.pair), d := 1};
    END;
  END Sym_;

PROCEDURE Onext(s : Arc): Arc =
  BEGIN
    IF s.d = 0 THEN
                 RETURN Arc{pair := Clock(Fnext(Enext_1(s.pair))), d := 0};
               ELSE
                 RETURN Arc{pair := Enext_1(s.pair), d := 1};
    END;
  END Onext;

PROCEDURE Dual(s : Arc): Arc =
  BEGIN
    RETURN Arc{pair := s.pair, d := 1-s.d};
  END Dual;

PROCEDURE Rot(s : Arc): Arc =
  BEGIN
    RETURN Dual(Flip(s));
  END Rot;

PROCEDURE Oprev(s : Arc): Arc =
  BEGIN
    RETURN Rot(Onext(Rot(s)));
  END Oprev;


PROCEDURE Lnext(s : Arc): Arc =
  BEGIN
    RETURN Oprev(Sym(s));
  END Lnext;

PROCEDURE Rprev(s : Arc): Arc =
  BEGIN
    RETURN Onext(Sym(s));
  END Rprev;

(* =================== Operator's QuadEdge ========== *)

VAR FacetEdgeCount : CARDINAL := 1;

PROCEDURE MakeEdge() : Arc =
<* FATAL Wr.Failure, Thread.Alerted *>
  VAR a,b: Pair;
  BEGIN
    a := MakeFacetEdge();
    a.facetedge.num := FacetEdgeCount; INC(FacetEdgeCount);
  (*Octf.PrintPair(Stdio.stdout, a);
    Wr.PutText(Stdio.stdout, "\n");
  *)
    b := MakeFacetEdge();
  (*b.facetedge.num := FacetEdgeCount; INC(FacetEdgeCount); 
    Octf.PrintPair(Stdio.stdout, b);
    Wr.PutText(Stdio.stdout, "\n");
  *)
    SpliceFacets(a, b);
    SpliceEdges(a, Clock(b)); 
    RETURN Arc{pair := a, d := 0};
  END MakeEdge;


PROCEDURE MakeLoop() : Arc =
<* FATAL Wr.Failure, Thread.Alerted *>
  VAR a,b: Pair;
  BEGIN
    a := MakeFacetEdge();
    a.facetedge.num := FacetEdgeCount; INC(FacetEdgeCount);
    Octf.PrintPair(Stdio.stdout, a);
    Wr.PutText(Stdio.stdout, "\n");
    b := MakeFacetEdge();
    b.facetedge.num := FacetEdgeCount; INC(FacetEdgeCount);
    Octf.PrintPair(Stdio.stdout, b);
    Wr.PutText(Stdio.stdout, "\n");
    SpliceFacets(a, b);
    RETURN Arc{pair := a, d := 0};
  END MakeLoop;


PROCEDURE Splice(s1,s2 : Arc) =
<* FATAL Wr.Failure, Thread.Alerted *>
  BEGIN
    IF (s1.d = 0 AND s2.d = 0)
      THEN
        Octf.PrintPair(Stdio.stdout, Spin(Clock(s1.pair)),1);
        Wr.PutText(Stdio.stdout, "\n");
        Octf.PrintPair(Stdio.stdout, Spin(Clock(s2.pair)),1);
        Wr.PutText(Stdio.stdout, "\n"); 
        SpliceEdges(Spin(Clock(s1.pair)), Spin(Clock(s2.pair)));
      ELSE
        SpliceEdges(Enext_1(s1.pair), Enext_1(s2.pair)); 
    END; 
  END Splice;

PROCEDURE Splice_(s1,s2 : Arc) =
<* FATAL Wr.Failure, Thread.Alerted *>
  BEGIN
    IF (s1.d = 0 AND s2.d = 0)
      THEN
        Octf.PrintPair(Stdio.stdout, Spin(Clock(s1.pair)),10);
        Wr.PutText(Stdio.stdout, "\n");
        Octf.PrintPair(Stdio.stdout, Spin(Clock(s2.pair)),10);
        Wr.PutText(Stdio.stdout, "\n");
        SpliceEdges(Spin(Clock(s1.pair)), Spin(Clock(s2.pair)));
      ELSE
        SpliceEdges(Enext_1(s1.pair), Enext_1(s2.pair));
    END;
  END Splice_;

BEGIN
END QuadEdge.






