
#include "xdart/x_at_reclist.h"

#include "xpace/index/reflist/reflist.h"

#include "retrieve/indexiter.h"

const AT_Record_List AT_Record_List::null(0);

AT_Record_List::AT_Record_List
  (uint32 numRecords) :
    x_RefList(0),
    db_records(numRecords)
{
}

AT_Record_List::AT_Record_List
  (AT_Index::Iter& iter) :
    x_RefList(iter.x_Iter->getRefList()),
    db_records(iter.db_records)
{
  x_RefList.getLength();
}


AT_Record_List::AT_Record_List
  (AT_Index::Iter& start,
   AT_Index::Iter& end) :
    x_RefList(start.x_Iter->getRefList(*end.x_Iter)),
    db_records(start.db_records)
{
  x_RefList.getLength();
}

AT_Record_List::AT_Record_List
  (const AT_Record_List& rhs) :
    x_RefList(rhs.x_RefList),
    db_records(rhs.db_records)
{
  x_RefList.getLength();
}

AT_Record_List::~AT_Record_List
  () 
{
}

AT_Record_List& AT_Record_List::operator=
  (const AT_Record_List &rhs)
{
  x_RefList = rhs.x_RefList;
  db_records = rhs.db_records;
  return *this;
}

bool AT_Record_List::operator==
  (const AT_Record_List &rhs)
  const
{
  assert(0);
  //return x_RefList == rhs.x_RefList;
  return false;
}
 
bool AT_Record_List::operator!=
  (const AT_Record_List &rhs)
  const
{
  assert(0);
  //return x_RefList != rhs.x_RefList;
  return false;
}

bool AT_Record_List::operator!
  ()
{
  return !x_RefList;
}

uint32 AT_Record_List::count
  ()
  const
{
  return uint32(x_RefList.getLength());
}

uint32 AT_Record_List::dbRecords
  ()
  const
{
  return db_records;
}

bool AT_Record_List::hasRecord
  (uint32 absRecNum,
   uint32 *relRecNum)
  const
{
  uint64 rrn;
  bool ret(x_RefList.hasRef(absRecNum, relRecNum ? &rrn : 0));
  if (relRecNum)
    *relRecNum = uint32(rrn);
  return ret;
}

AT_Record_List& AT_Record_List::operator+=
  (uint32 recNum)
{
  x_RefList.addRef(recNum);
  return *this;
}

AT_Record_List& AT_Record_List::operator-=
  (uint32 recNum)
{
  x_RefList.removeRef(recNum);
  return *this;
}

AT_Record_List& AT_Record_List::operator&=
  (const AT_Record_List& rhs)
{
  x_RefList.opAnd(const_cast<Xpace::RefListCursor*>(&rhs.x_RefList));
  return *this;
}

AT_Record_List& AT_Record_List::operator|=
  (const AT_Record_List& rhs)
{
  x_RefList.opOr(const_cast<Xpace::RefListCursor*>(&rhs.x_RefList));
  return *this;
}

AT_Record_List& AT_Record_List::operator^=
  (const AT_Record_List& rhs)
{
  assert(0);
  return *this;
}

AT_Record_List& AT_Record_List::invert
  (uint dbRecordCount)
{
  x_RefList.opNot(dbRecordCount ? dbRecordCount : db_records);
  return *this;
}

AT_Record_List& AT_Record_List::operator-=
  (const AT_Record_List& rhs)
{
  Xpace::RefListCursor r(rhs.x_RefList);
  r.opNot(db_records);
  x_RefList.opAnd(&r);
  return *this;
}

const AT_Record_List::Iter AT_Record_List::begin
  ()
  const
{
  Xpace::RefListCursor rlc(x_RefList);
  if (!!rlc)
    rlc.move(0, false);
  return Iter(rlc, db_records);
}
 
const AT_Record_List::Iter AT_Record_List::end
  ()
  const
{
  Xpace::RefListCursor rlc(x_RefList);
  if (!!rlc)
    rlc.move(x_RefList.getLength(), false);
  return Iter(rlc, db_records);
}

// ================================== RECORD LIST ITERATOR ====

AT_Record_List::Iter::Iter
  () :
    x_RefList(uint64(0))
{
}

AT_Record_List::Iter::Iter
  (const Iter& rhs) :
    x_RefList(rhs.x_RefList)
{
}
 
AT_Record_List::Iter::~Iter
  ()
{
}
  
AT_Record_List::Iter& AT_Record_List::Iter::operator=
  (const Iter& rhs)
{
  x_RefList = rhs.x_RefList;
  return *this;
}

uint32 AT_Record_List::Iter::operator*
  ()
  const
{
  return uint32(*x_RefList);
}

AT_Record_List::Iter& AT_Record_List::Iter::operator++
  ()
{
  x_RefList.move(1);
  return *this;
}

AT_Record_List::Iter AT_Record_List::Iter::operator++
  (int)
{
  Iter it(*this);
  x_RefList.move(1);
  return it;
}

AT_Record_List::Iter& AT_Record_List::Iter::operator--
  ()
{
  x_RefList.move(-1);
  return *this;
}

AT_Record_List::Iter AT_Record_List::Iter::operator--
  (int)
{
  Iter it(*this);
  x_RefList.move(-1);
  return it;
}

AT_Record_List::Iter& AT_Record_List::Iter::operator+=
  (int32 n)
{
  x_RefList.move(n);
  return *this;
}

AT_Record_List::Iter& AT_Record_List::Iter::operator-=
  (int32 n)
{
  x_RefList.move(-n);
  return *this;
}

AT_Record_List::Iter AT_Record_List::Iter::operator+
  (int32 n)
  const
{
  Iter it(*this);
  it += n;
  return it;
}

AT_Record_List::Iter AT_Record_List::Iter::operator-
  (int32 n)
  const
{
  Iter it(*this);
  it -= n;
  return it;
}

int32 AT_Record_List::Iter::operator-
  (const AT_Record_List::Iter& rhs)
{
  return int32(x_RefList.getPosition() - rhs.x_RefList.getPosition());
}
 
bool AT_Record_List::Iter::operator==
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() == rhs.x_RefList.getPosition();
}

bool AT_Record_List::Iter::operator!=
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() != rhs.x_RefList.getPosition();
}

bool AT_Record_List::Iter::operator<
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() < rhs.x_RefList.getPosition();
}

bool AT_Record_List::Iter::operator<=
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() <= rhs.x_RefList.getPosition();
}
 
bool AT_Record_List::Iter::operator>
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() > rhs.x_RefList.getPosition();
}

bool AT_Record_List::Iter::operator>=
  (const AT_Record_List::Iter& rhs)
  const
{
  return x_RefList.getPosition() >= rhs.x_RefList.getPosition();
}

uint32 AT_Record_List::Iter::operator[]
  (uint32 i)
{
  if (x_RefList.move(i))
  {
    uint32 ret((uint32)*x_RefList);
    x_RefList.move(-int(i));
    return ret;
  }
  return -1;
}

