#ifndef SIMPLEXD1LINKED_H
#define SIMPLEXD1LINKED_H


#include <cassert>
#include <sstream>
using namespace std;

#include <typedefs.h>

/**
\brief A instance of a generalized simplex in 1D.

The neighbor link is defined : given neighbor k,
 the point opposite and hence not in contact with the neighboring 
 simplex k has a local index which is the index to neigbor k. 

This definition was choosen because it generalized to simplexes
 in any dimension, and is useful in algorithms. ie piInverse.

*/
template< typename INDX=uint>
class simplexD1linked
{
public:

  /** Indexes to points or verticies. */
  INDX pi[2];
  /** Indexes to neighboring simplexes. 
      If ni[k] is 0 this is a boundary/endpoint. */
  INDX ni[2];

  /** Default Constructor: all fields set to 0. */
  simplexD1linked() {};
  /** Construct a line. */
  simplexD1linked
  (
    INDX const a, INDX const b, INDX const na=0, INDX const nb=0
  );

  /** Construct this line. */
  void construct 
  (
    INDX const a, INDX const b, INDX const na=0, INDX const nb=0
  );

  /** Swap the line direction. */
  void togglelinedirection()
  {
    INDX p0 = pi[0];
    INDX n0 = ni[0];
    pi[0] = pi[1];
    ni[0] = ni[1];
    pi[1] = p0;
    ni[1] = n0;
  }

  // Query Functions

  /** Get the local point index. */
  INDX const piInverse( INDX const gpt ) const
  {
    assert(gpt!=0);

    if (pi[0]==gpt) return 0;
    if (pi[1]==gpt) return 1;

    assert(false);
    return 3; // Return crap.
  }

  /** Does the line have end points? */
  boolc isonboundary() const
  {
    if (ni[0]==0) return true;
    if (ni[1]==0) return true;
    return false;
  }
  
  /** Set all fields to 0. */
  void setnull()
    { pi[0] = pi[1] = ni[0] = ni[1] = 0; }

  /** Are all the fields set to zero? */
  boolc isnull() const
  {
    if (pi[0]!=0) return false;
    if (pi[1]!=0) return false;
    if (ni[0]!=0) return false;
    if (ni[1]!=0) return false;
    return true;
  }

  /** Serialize this object. */
  operator stringc () const;

  /** Read in/construct an object. */
  void serializeInverse(stringc & s)
  {
    stringstream w(s);
    w >> pi[0];
    w >> pi[1];
    w >> ni[0];
    w >> ni[1];
  }
};


//---------------------------------------------------------
// Implementation

template< typename INDX >
simplexD1linked<INDX>::operator stringc () const
{
  stringstream ss;
  ss << pi[0] << " " << pi[1] << " " << ni[0] << " " << ni[1];
  return ss.str();
}

template< typename INDX >
simplexD1linked<INDX>::simplexD1linked
(
  INDX const a, INDX const b, INDX const na, INDX const nb
)
{
  pi[0] = a;
  pi[1] = b;
  ni[0] = na;
  ni[1] = nb;
}

template< typename INDX >
void simplexD1linked<INDX>::construct
(
  INDX const a, INDX const b, INDX const na, INDX const nb
)
{
  pi[0] = a;
  pi[1] = b;
  ni[0] = na;
  ni[1] = nb;
}




#endif


