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

#include <simplexD2linked.h>

//uint * simplexD2linked::niFrompiInverse(uintc gpt)
//{ 
//  return & ni[ piInverse(gpt) ]; 
//}


simplexD2linked::operator string() const
{
  string s;
  for (uint i=0; i<3; ++i)
  {
    { stringstream ss; ss << pi[i]; s+=ss.str(); }
    s += " ";
  }

  s += "  ";

  for (uint i=0; i<3; ++i)
  {
    { stringstream ss; ss << ni[i]; s+=ss.str(); }
    s += " ";
  }

  return s;
}

simplexD2linked::simplexD2linked()
{
  for (uint i=0; i<3; ++i)
  {
    pi[i] = 0;
    ni[i] = 0;
  }
}

simplexD2linked::simplexD2linked
(
  uintc a,
  uintc b,
  uintc c,
  uintc na,
  uintc nb,
  uintc nc
) 
{ 
  construct(a,b,c,na,nb,nc); 
}


/*
uintc simplexD2linked::piInverse 
(
  bool & res,
  uintc gpt
) const
{
  assert(gpt!=0);

  res=true;

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

  res=false;
  return 3; // Return crap.
}
*/


boolc simplexD2linked::isonboundary() const
{
  if (ni[0]==0) return true;
  if (ni[1]==0) return true;
  if (ni[2]==0) return true;
  
  return false;
}


/*
uintc simplexD2linked::niInverse
(
  bool & res,
  uintc neib
) const
{  
  res=true;

  if (ni[0]==neib) return 0;
  if (ni[1]==neib) return 1;
  if (ni[2]==neib) return 2;

  res=false;
  return 3; // Return crap.
}
*/




/*
boolc simplexD2linked::isavertex( uintc gpt ) const
{
  if (gpt==pi[0]) return true;
  if (gpt==pi[1]) return true;
  if (gpt==pi[2]) return true;

  return false;
}
*/

void simplexD2linked::serializeInverse(stringc & s)
{  
  stringstream ss(s); 
  for (uint i=0; i<3; ++i)
    ss >> pi[i];

  for (uint i=0; i<3; ++i)
    ss >> ni[i];
}

istream & simplexD2linked::serializeInverse(istream & is)
{
  for (uint i=0; i<3; ++i)
    is >> pi[i];

  for (uint i=0; i<3; ++i)
    is >> ni[i];
  
  return is;
}



ostream & simplexD2linked::print(ostream& os) const
{
  for (uint i=0; i<3; ++i)
    os << pi[i] << " ";

  os << "  ";

  for (uint i=0; i<3; ++i)
    os << ni[i] << " ";

  return os;
}


void simplexD2linked::construct
(
  uintc a,
  uintc b,
  uintc c,
  uintc na,
  uintc nb,
  uintc nc
)
{
  pi[0] = a;
  pi[1] = b;
  pi[2] = c;
  ni[0] = na;
  ni[1] = nb;
  ni[2] = nc;
};


void simplexD2linked::getanticlockwiseface
(
  uint & a, 
  uint & b, 
  uintc face
) const 
{
  switch (face)
  {
    case 0:
      a=1; b=2; 
      break;

    case 1:
      a=2; b=0;
      break;

    case 2:
      a=0; b=1;
      break;

    default:
      assert(false);
  }
}

void simplexD2linked::getclockwiseface
(
  uint & a, 
  uint & b, 
  uintc face
) const 
{
  switch (face)
  {
    case 0:
      a=2; b=1; 
      break;

    case 1:
      a=0; b=2; 
      break;

    case 2:
      a=1; b=0; 
      break;

    default:
      assert(false);
  }
}

boolc simplexD2linked::isnull() const
{
  for (uint i=0; i<3; ++i)
  {
    if (pi[i]!=0)
      return false;

    if (ni[i]!=0)
      return false;
  }

  return true;
}

void simplexD2linked::setnull()
{
  for (uint i=0; i<3; ++i)
  {
    pi[i]=0;
    ni[i]=0;
  }
}

boolc simplexD2linked::operator == (simplexD2linked const & w) const
{
  if (pi[0]+pi[1]+pi[2] != w.pi[0]+w.pi[1]+w.pi[2])
    return false;

  for (uint i=0; i<3; ++i)
  {
    bool res(false);
    for (uint k=0; k<3; ++k)
    {
      if (w.pi[k]==pi[i])
      {
        res=true;
        k=3;
      }
    }
    if (res==false)
      return false;
  }

  return true;
}




ostream & operator << (ostream& os, simplexD2linked const & x)
{ 
  return x.print(os); 
}

istream & operator >> (istream & is, simplexD2linked & x)
{ 
  return x.serializeInverse(is); 
}




