//=======================================================================
// Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#ifndef BOOST_SELF_AVOIDING_WALK_HPP
#define BOOST_SELF_AVOIDING_WALK_HPP

/*
  This file defines necessary components for SAW. 

  mesh language: (defined by myself to clearify what is what)
  A triangle in mesh is called an triangle.
  An edge in mesh is called an line. 
  A vertex in mesh is called a point.

  A triangular mesh corresponds to a graph in which a vertex is a
  triangle and an edge(u, v) stands for triangle u and triangle v 
  share an line.

  After this point, a vertex always refers to vertex in graph,
  therefore it is a traingle in mesh. 

 */

#include <utility>
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>

#define SAW_SENTINAL -1

namespace boost {

  template <class T1, class T2, class T3>
  struct triple {
    T1 first;
    T2 second;
    T3 third;
    triple(const T1& a, const T2& b, const T3& c) : first(a), second(b), third(c) {}
    triple() : first(SAW_SENTINAL), second(SAW_SENTINAL), third(SAW_SENTINAL) {}
  };
 
  typedef triple<int, int, int> Triple;

  /* Define a vertex property which has a triangle inside. Triangle is
    represented by a triple.  */
  struct triangle_tag { enum { num = 100 }; };
  typedef property<triangle_tag,Triple> triangle_property;

  /* Define an edge property with a line. A line is represented by a
    pair.  This is not required for SAW though.
  */
  struct line_tag { enum { num = 101 }; };
  template <class T> struct line_property
    : public property<line_tag, std::pair<T,T> > { };

  /*Precondition: Points in a Triangle are in order */
  template <class Triangle, class Line>
  inline void get_sharing(const Triangle& a, const Triangle& b, Line& l)
  {
    l.first = SAW_SENTINAL;
    l.second = SAW_SENTINAL;

    if ( a.first == b.first ) {
      l.first = a.first;
      if ( a.second == b.second || a.second == b.third )
        l.second = a.second;
      else if ( a.third == b.second || a.third == b.third )
        l.second = a.third; 

    }  else if ( a.first == b.second ) {
      l.first = a.first;
      if ( a.second == b.third )
        l.second = a.second;
      else if ( a.third == b.third )
        l.second = a.third; 

    } else if ( a.first == b.third ) {
      l.first = a.first;


    } else if ( a.second == b.first ) {
      l.first = a.second;
      if ( a.third == b.second || a.third == b.third )
        l.second = a.third;

    } else if ( a.second == b.second ) {
      l.first = a.second;
      if ( a.third == b.third ) 
        l.second = a.third;

    } else if ( a.second == b.third ) {
      l.first = a.second;


    } else if ( a.third == b.first 
                || a.third == b.second  
                || a.third == b.third )
      l.first = a.third; 

    /*Make it in order*/
    if ( l.first > l.second ) {
      typename Line::first_type i = l.first;
      l.first = l.second;
      l.second = i;
    }

  }

  template <class TriangleDecorator, class Vertex, class Line>
  struct get_vertex_sharing {
    typedef std::pair<Vertex, Line> Pair;
    get_vertex_sharing(const TriangleDecorator& _td) : td(_td) {}
    inline Line operator()(const Vertex& u, const Vertex& v) const {
      Line l;
      get_sharing(td[u], td[v], l);
      return l;
    }
    inline Line operator()(const Pair& u, const Vertex& v) const {
      Line l;
      get_sharing(td[u.first], td[v], l);
      return l;
    }
    inline Line operator()(const Pair& u, const Pair& v) const {
      Line l;
      get_sharing(td[u.first], td[v.first], l);
      return l;
    }
    TriangleDecorator td;
  };
  
  /* HList has to be a handle of data holder so that pass-by-value is
   * in right logic.
   *
   * The element of HList is a pair of vertex and line. (remember a
   * line is a pair of two ints.). That indicates the walk w from
   * current vertex is across line. (If the first of line is -1, it is
   * a point though.
   */
  template < class TriangleDecorator, class HList, class IteratorD>
  class SAW_visitor
    : public bfs_visitor<>, public dfs_visitor<>
  {
    typedef typename boost::property_traits<IteratorD>::value_type iter;
    /*use boost shared_ptr*/
    typedef typename HList::element_type::value_type::second_type     Line;
  public:

    typedef tree_edge_tag category;

    inline SAW_visitor(TriangleDecorator _td, HList _hlist, IteratorD ia)
      : td(_td), hlist(_hlist), iter_d(ia) {}

    template <class Vertex, class Graph>
    inline void start_vertex(Vertex v, Graph&) {
      Line l1;
      l1.first = SAW_SENTINAL;
      l1.second = SAW_SENTINAL;
      hlist->push_front(std::make_pair(v, l1));
      iter_d[v] = hlist->begin();
    }

    /*Several symbols:
      w(i): i-th triangle in walk w
      w(i) |- w(i+1): w enter w(i+1) from w(i) over a line
      w(i) ~> w(i+1): w enter w(i+1) from w(i) over a point
      w(i) -> w(i+1): w enter w(i+1) from w(i)
      w(i) ^ w(i+1): the line or point w go over from w(i) to w(i+1)
    */
    template <class Edge, class Graph>
    bool tree_edge(Edge e, Graph& G) {
          using std::make_pair;
      typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
      Vertex tau = target(e, G);
      Vertex i   = source(e, G); 

      get_vertex_sharing<TriangleDecorator, Vertex, Line> get_sharing_line(td);
      
      Line tau_i = get_sharing_line(tau, i);
      
      iter w_end = hlist->end();

      iter w_i = iter_d[i];

      iter w_i_m_1 = w_i;
      iter w_i_p_1 = w_i;

      /*----------------------------------------------------------
       *             true             false
       *==========================================================
       *a       w(i-1) |- w(i)    w(i-1) ~> w(i) or w(i-1) is null
       *----------------------------------------------------------
       *b       w(i) |- w(i+1)    w(i) ~> w(i+1) or no w(i+1) yet
       *----------------------------------------------------------
       */
      
      bool a = false, b = false;

      --w_i_m_1;
      ++w_i_p_1;
      b = ( w_i->second.first != SAW_SENTINAL );

      if ( w_i_m_1 != w_end ) {
        a = ( w_i_m_1->second.first != SAW_SENTINAL );
      }      
      
      if ( a ) {
        
        if ( b ) {
          /*Case 1: 
            
            w(i-1) |- w(i) |- w(i+1)
          */
          Line l1 = get_sharing_line(*w_i_m_1, tau);

          iter w_i_m_2 = w_i_m_1;
          --w_i_m_2;

          bool c = true;
          
          if ( w_i_m_2 != w_end ) {
            c = w_i_m_2->second != l1;
          }

          if ( c ) {  /* w(i-1) ^ tau != w(i-2) ^ w(i-1)  */
            /*extension: w(i-1) -> tau |- w(i) */
            w_i_m_1->second = l1;
            /*insert(pos, const T&) is to insert before pos*/
            iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));  
            
          } else {  /* w(i-1) ^ tau == w(i-2) ^ w(i-1)  */
            /*must be w(i-2) ~> w(i-1) */
            
            bool d = true;
            //need to handle the case when w_i_p_1 is null
            Line l3 = get_sharing_line(*w_i_p_1, tau);
            if ( w_i_p_1 != w_end )
              d = w_i_p_1->second != l3;
            if ( d ) { /* w(i+1) ^ tau != w(i+1) ^ w(i+2) */
              /*extension: w(i) |- tau -> w(i+1) */
              w_i->second = tau_i;
              iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l3));
            } else { /* w(i+1) ^ tau == w(i+1) ^ w(i+2) */
              /*must be w(1+1) ~> w(i+2) */
              Line l5 = get_sharing_line(*w_i_m_1, *w_i_p_1);
              if ( l5 != w_i_p_1->second ) { /* w(i-1) ^ w(i+1) != w(i+1) ^ w(i+2) */
                /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1) */
                w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
                iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
                w_i->second = w_i_m_1->second;
                w_i_m_1->second = l5;
                iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
                hlist->erase(w_i_m_1);
              } else {
                /*mesh is tetrahedral*/
                // dont know what that means.
                ;
              }
            }
            
          }
        } else { 
          /*Case 2:
            
            w(i-1) |- w(i) ~> w(1+1)
          */
          
          if ( w_i->second.second == tau_i.first 
               || w_i->second.second == tau_i.second ) {  /*w(i) ^ w(i+1) < w(i) ^ tau*/
            /*extension: w(i) |- tau -> w(i+1) */
            w_i->second = tau_i;
            Line l1 = get_sharing_line(*w_i_p_1, tau);
            iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
          } else { /*w(i) ^ w(i+1) !< w(i) ^ tau*/
            Line l1 = get_sharing_line(*w_i_m_1, tau);
            bool c = true;
            iter w_i_m_2 = w_i_m_1;
            --w_i_m_2;
            if ( w_i_m_2 != w_end )
              c =  l1 != w_i_m_2->second;
            if (c) { /*w(i-1) ^ tau != w(i-2) ^ w(i-1)*/
              /*extension: w(i-1) -> tau |- w(i)*/
              w_i_m_1->second = l1;
              iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
            } else { /*w(i-1) ^ tau == w(i-2) ^ w(i-1)*/
              /*must be w(i-2)~>w(i-1)*/
              /*extension: w(i-2) -> tau |- w(i) |- w(i-1) -> w(i+1)*/
              w_i_m_2->second = get_sharing_line(*w_i_m_2, tau);
              iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
              w_i->second = w_i_m_1->second;
              w_i_m_1->second = get_sharing_line(*w_i_m_1, *w_i_p_1);
              iter_d[w_i_m_1->first] = hlist->insert(w_i_p_1, *w_i_m_1);
              hlist->erase(w_i_m_1);
            }
            
          }    
          
        }
        
      } else {
        
        if ( b ) {
          /*Case 3:
            
            w(i-1) ~> w(i) |- w(i+1)
          */
          bool c = false;
          if ( w_i_m_1 != w_end )
            c = ( w_i_m_1->second.second == tau_i.first)
              || ( w_i_m_1->second.second == tau_i.second);
          
          if ( c ) {  /*w(i-1) ^ w(i) < w(i) ^ tau*/
            /* extension: w(i-1) -> tau |- w(i) */
            if ( w_i_m_1 != w_end )
              w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
            iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
          } else {
            bool d = true;
            Line l1;
            l1.first = SAW_SENTINAL;
            l1.second = SAW_SENTINAL;
            if ( w_i_p_1 != w_end ) {
              l1 = get_sharing_line(*w_i_p_1, tau);
              d = l1 != w_i_p_1->second;
            }
            if (d) { /*w(i+1) ^ tau != w(i+1) ^ w(i+2)*/
              /*extension: w(i) |- tau -> w(i+1) */
              w_i->second = tau_i;
              iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
            } else {
              /*must be w(i+1) ~> w(i+2)*/
              /*extension: w(i-1) -> w(i+1) |- w(i) |- tau -> w(i+2) */
              iter w_i_p_2 = w_i_p_1;
              ++w_i_p_2;
              
              w_i_p_1->second = w_i->second;
              iter_d[i] = hlist->insert(w_i_p_2, make_pair(i, tau_i));
              hlist->erase(w_i);
              Line l2 = get_sharing_line(*w_i_p_2, tau);
              iter_d[tau] = hlist->insert(w_i_p_2, make_pair(tau, l2));
            }
          }
          
        } else {
          /*Case 4:
            
            w(i-1) ~> w(i) ~> w(i+1)
            
          */
          bool c = false;
          if ( w_i_m_1 != w_end ) {
            c = (w_i_m_1->second.second == tau_i.first) 
              || (w_i_m_1->second.second == tau_i.second);
          }
          if ( c ) {   /*w(i-1) ^ w(i) < w(i) ^ tau */
            /*extension: w(i-1) -> tau |- w(i) */
            if ( w_i_m_1 != w_end )
              w_i_m_1->second = get_sharing_line(*w_i_m_1, tau);
            iter_d[tau] = hlist->insert(w_i, make_pair(tau, tau_i));
          } else { 
            /*extension: w(i) |- tau -> w(i+1) */
            w_i->second = tau_i;
            Line l1;
            l1.first = SAW_SENTINAL;
            l1.second = SAW_SENTINAL;
            if ( w_i_p_1 != w_end ) 
              l1 = get_sharing_line(*w_i_p_1, tau);
            iter_d[tau] = hlist->insert(w_i_p_1, make_pair(tau, l1));
          }
        }
        
      }

      return true;
    }
    
  protected:
    TriangleDecorator td; /*a decorator for vertex*/
    HList             hlist;
    /*This must be a handle of list to record the SAW
      The element type of the list is pair<Vertex, Line>
     */
   
    IteratorD         iter_d; 
    /*Problem statement: Need a fast access to w for triangle i.
     *Possible solution: mantain an array to record. 
     iter_d[i] will return an iterator 
     which points to w(i), where i is a vertex
     representing triangle i.
    */
  };

  template <class Triangle, class HList, class Iterator>
  inline 
  SAW_visitor<Triangle, HList, Iterator>
  visit_SAW(Triangle t, HList hl, Iterator i) {
    return SAW_visitor<Triangle, HList, Iterator>(t, hl, i);
  }

  template <class Tri, class HList, class Iter>
  inline 
  SAW_visitor< random_access_iterator_property_map<Tri*,Tri,Tri&>,
    HList, random_access_iterator_property_map<Iter*,Iter,Iter&> >
  visit_SAW_ptr(Tri* t, HList hl, Iter* i) {
    typedef random_access_iterator_property_map<Tri*,Tri,Tri&> TriD;
    typedef random_access_iterator_property_map<Iter*,Iter,Iter&> IterD;
    return SAW_visitor<TriD, HList, IterD>(t, hl, i);
  }

  // should also have combo's of pointers, and also const :(
  
}

#endif /*BOOST_SAW_H*/
