#include <d4minoperator.h>

#include <d4tri.h>

#include <tetrahedron.h>

#include <d4tess.h>

double d4minoperator::delta = 0.1;

d4minoperator::d4minoperator(d4tess & _tess)
  : tess(_tess)
{

}

bool const d4minoperator::evalInvert(uint a, uintc index)
{
  assert(index<4);

  d4tri A(tess.vi[a]);
  uint n;

  for (uint i=0; i<4; ++i)
  {
    if (i==index)
      continue;

    n = A.ni[i];
    if (n==0)
      continue;

    if( this->eval(a,n) )
      return true;
  }

  return false;
}

bool const d4minoperator::twotetrahedronMInvert
(
  uintc a, 
  uintc ai, 
  uintc b, 
  uintc bi
)
{
  bool res(false);
  if ( evalInvert(a,ai) )
    res=true;
  if ( evalInvert(b,bi) )
    res=true;

  return res;
}



bool const d4minoperator::approximatelyequal
(
  double const a, 
  double const b
)
{
  double a2(a);
  if (a2<0.0)
    a2*=-1.0;
  double b2(b);
  if (b2<0.0)
    b2*=-1.0;

  double m(a);
  if (a<b)
    m=b;
  
  // res will look at the relative magnitude of the numbers.
  // If a == b in approximate sense res will be small.
  double res = (a-b);
  if (res<0.0)
    res *= -1.0;

  res /= m;

  return res<delta;
}


/*




bool const d4minoperator::isconnected
(
  uint & ai, 
  uint & bi,
  uintc a,
  uintc b
) const 
{
  uintc sz(tess->vi.size());
  assert(a<sz);
  assert(b<sz);

  if ((a==0)||(b==0))
    return false;

  d4tri const & A(tess->vi[a]);
  d4tri const & B(tess->vi[b]);

  bool res;

  ai = A.niInverse(res,b);
  if (res==false)
    return false;

  bi = B.niInverse(res,a);
  if (res==false)
    return false;

  return true;
}


bool const d4minoperator::isconvex( uintc a, uintc b ) const
{
  assert(a<tess->vi.size());
  assert(b<tess->vi.size());

  if ((a==0)||(b==0))
    return false;

  d4tri const & A(tess->vi[a]);
  d4tri const & B(tess->vi[b]);

  uint ai, bi;
  if (isconnected(ai,bi,a,b)==false)
    return false;

  tetrahedron<double> t
  ( 
    tess->pt[A.pi[0] ],
    tess->pt[A.pi[1] ],
    tess->pt[A.pi[2] ],
    tess->pt[A.pi[3] ]
  );

  pt4 p(tess->pt[B.pi[ai]]);

  for (uint i=0; i<4; ++i)
  {
    if (i==ai)
      continue;

    if ( t.hi[i].eval(p)==true )
      return false;
  }

  return true;
}


*/








