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

#include <polytopeD2linked.h>
#include <print.h>

boolc polytopeD2linked::niInverseHas( uintc neib ) const
{
  // Let the client as if there are null neighbors.
  //assert(neib!=0);

  for (uint i=0; i<ni.size(); ++i)
  {
//    if (ni[i]==0)
//      continue;

    if (ni[i]==neib)
      return true;
  }

  return false;
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, 
  uintc n0, uintc n1
)
{
  pi.push_back(p0);
  pi.push_back(p1);

  ni.push_back(n0);
  ni.push_back(n1);
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2,
  uintc n0, uintc n1, uintc n2
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
}


polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2, uintc p3,
  uintc n0, uintc n1, uintc n2, uintc n3
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);
  pi.push_back(p3);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
  ni.push_back(n3);
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2, uintc p3, uintc p4,
  uintc n0, uintc n1, uintc n2, uintc n3, uintc n4
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);
  pi.push_back(p3);
  pi.push_back(p4);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
  ni.push_back(n3);
  ni.push_back(n4);
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2, uintc p3, uintc p4, uintc p5,
  uintc n0, uintc n1, uintc n2, uintc n3, uintc n4, uintc n5
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);
  pi.push_back(p3);
  pi.push_back(p4);
  pi.push_back(p5);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
  ni.push_back(n3);
  ni.push_back(n4);
  ni.push_back(n5);
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2, uintc p3, uintc p4, uintc p5, uintc p6,
  uintc n0, uintc n1, uintc n2, uintc n3, uintc n4, uintc n5, uintc n6
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);
  pi.push_back(p3);
  pi.push_back(p4);
  pi.push_back(p5);
  pi.push_back(p6);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
  ni.push_back(n3);
  ni.push_back(n4);
  ni.push_back(n5);
  ni.push_back(n6);
}

polytopeD2linked::polytopeD2linked
(
  uintc p0, uintc p1, uintc p2, uintc p3, uintc p4, uintc p5, uintc p6, uintc p7,
  uintc n0, uintc n1, uintc n2, uintc n3, uintc n4, uintc n5, uintc n6, uintc n7
)
{
  pi.push_back(p0);
  pi.push_back(p1);
  pi.push_back(p2);
  pi.push_back(p3);
  pi.push_back(p4);
  pi.push_back(p5);
  pi.push_back(p6);
  pi.push_back(p7);

  ni.push_back(n0);
  ni.push_back(n1);
  ni.push_back(n2);
  ni.push_back(n3);
  ni.push_back(n4);
  ni.push_back(n5);
  ni.push_back(n6);
  ni.push_back(n7);
}

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

  s += "  ";

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

  return s;
}


void polytopeD2linked::addpoint( uintc ptindex, uintc ptglobal )
{
//cout << SHOW(ptindex) << endl;
//cout << SHOW(ptglobal) << endl;
  uintc i0 = piInverse(ptindex);
//cout << SHOW(i0) << endl;
  uint sz = pi.size();
  pi.resize(sz+1);
  ni.resize(sz+1);
  
  uint k=sz;
  uintc imax = sz-i0;
  
  for (uint i=0; i<imax; ++i)
  {
    pi[k] = pi[k-1];
    ni[k] = ni[k-1];
    --k;
  }

  pi[(i0+1)%(sz+1)] = ptglobal;
}




