#ifndef EDGET_H
#define EDGET_H

#include <sstream>
using namespace std;

#include <typedefs.h>

/*!
\brief 2D indexed edge data structure.

The two point indexes of the edge are ordered.

\par Example
\verbatim
  typedef edgeT<double> ed;
  ed ei[] = 
  { 
    ed(1,7,0.6),ed(4,3,2.7),ed(2,1,9.7),ed(6,2,-2.4)
  };
  set<ed> s;
  s.insert(ei,ei+4);
  ... Now have ordered edges.
  set<ed>::iterator i=s.find(ed(2,5));
  if (i!=s.end()) 
  ...
\endverbatim
*/
template< typename T >
class edgeT
{
public:

  /** Ordered integer points. */
  uint pi[2];
  /** Whatever the edge link is holding. */
  T data;

  /** Construct an edge entry. */
  edgeT(uint i, uintc k, T const data_);
  /** Construct an edge entry. */
  edgeT(uint i, uintc k);

  /** Is this edge before x edge? */
  boolc operator < (edgeT const & x) const;
  /** Are two edges equal? */
  boolc operator == (edgeT const & x) const;

  /** Serialize this data structure. */
  operator stringc() const;
    
};

template< typename T >
ostream & operator << (ostream & os, edgeT<T> const & x)
  { return os << (stringc)x; }

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

template< typename T >
edgeT<T>::operator stringc() const
{
  stringstream targ;
  targ << pi[0] << " " << pi[1] << " " << data;

  return targ.str();
}

template< typename T >
boolc edgeT<T>::operator == (edgeT const & x) const
{
  if (pi[0]!=x.pi[0])
    return false;
  return (pi[1]==x.pi[1]);
}

template< typename T >
boolc edgeT<T>::operator < (edgeT const & x) const
{
  if (pi[0]<x.pi[0])
    return true;

  if (pi[0]==x.pi[0])
    return (pi[1]<x.pi[1]);

  return false;
}


template< typename T >
edgeT<T>::edgeT(uint i, uintc k, T const data_)
  : data(data_)
{
  if (i<k)
  {
    pi[0]=i;
    pi[1]=k;
  }
  else
  {
    pi[0]=k;
    pi[1]=i;
  }
}

template< typename T >
edgeT<T>::edgeT(uint i, uintc k)
{
  if (i<k)
  {
    pi[0]=i;
    pi[1]=k;
  }
  else
  {
    pi[0]=k;
    pi[1]=i;
  }
}

  


#endif


