#include <checks.h>

#define __TABUTIL_CPP
#include <tabutil.h>
#include <extcdecl.h>
#include <utility.h>

int TTable::name2log(const char* n)
{
  return *n == '%' ? LF_TABCOM : (*n == '#' ? LF_TABGEN : LF_TAB);
}


TTable::TTable(const char* tabname, bool linkrecinst)
: TLocalisamfile(name2log(tabname), linkrecinst), _cod(curr(), "COD")
{
  if ((*tabname == '%') || (*tabname == '#')) tabname++;
  _tabname = tabname;
  _tabname.upper();
  curr().settab(_tabname);
}

TTable::~TTable()
{}

int TTable::first(word lockop)

{

  zero();
  TBaseisamfile::read(_isgteq, lockop);
  if (good())
    if (_tabname != (const char *)_cod) setstatus(_isemptyfile);
  if (bad()) zero();
  return status();
}


int TTable::last(word lockop)

{                    
  zero();
  put("CODTAB", "\xFF");
  TBaseisamfile::read(_isgteq);
  if (!eof()) TBaseisamfile::prev(lockop);
  else setstatus(NOERR);
  if (bof()) setstatus(NOERR);
  if (good())
    if (_tabname != (const char *)_cod) setstatus(_isemptyfile);
  if (bad()) zero();
  return status();
}


int TTable::next(word lockop)
{
  const TRecnotype nrec = recno();

  if (nrec != filehnd()->RecNo)
  {         
    read();
    if (bad()) return status();
  } 

  TBaseisamfile::next(lockop);
  if (_tabname != (const char *)_cod)
  {
    if (lockop == _lock) TBaseisamfile::reread(_unlock);
    TBaseisamfile::readat(nrec, lockop);
    setstatus(_iseof);
  }
  return status();
}


int TTable::prev(word lockop)
{
  read();
  if (bad()) return status();

  TRecnotype nrec = recno();

  TBaseisamfile::prev(lockop);
  if (_tabname != (const char *)_cod)
  {
    if (lockop == _lock) TBaseisamfile::reread(_unlock);
    TBaseisamfile::readat(nrec, lockop);
    setstatus(_isbof);
  }
  return status();
}


int TTable::skip(TRecnotype nrec, word lockop)

{
  if (!nrec) return NOERR;
  TBaseisamfile::skip(nrec, lockop);
  if (_tabname != (const char *)_cod)
  {
    if (nrec > 0)
    {
      if (lockop == _lock) TBaseisamfile::reread(_unlock);
      last(lockop);
      setstatus(_iseof);
    }
    else
    {
      if (lockop == _lock) TBaseisamfile::reread(_unlock);
      first(lockop);
      setstatus(_isbof);
    }
  }
  return status();
}


int TTable::read(word op, word lockop, TDate&)

{
  CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op);
  TBaseisamfile::read(op, lockop);
  if (_tabname != (const char *)_cod)
  {
    if (lockop == _lock) TBaseisamfile::reread(_unlock);
    last(lockop);
    setstatus(_iseof);
  }
  return status();
}


int TTable::read(TRectype& rec, word op, word lockop, TDate&)

{
  CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op);
  TBaseisamfile::read(rec, op, lockop);
  if (_tabname != (const char *)_cod)
  {
    setstatus(_iseof);
    if (lockop == _lock) TBaseisamfile::reread(_unlock);
    last(lockop);
  }
  return status();
}


int TTable::readat(TRecnotype nrec, word lockop)

{
  TBaseisamfile::readat(nrec, lockop);

  CHECKS(_tabname == (const char * )_cod, "Invalid position : Table ", (const char *)_tabname);
  return status();
}


int TTable::readat(TRectype& rec ,TRecnotype nrec, word lockop)

{
  TBaseisamfile::readat(rec, nrec, lockop);

  CHECKS(_tabname == (const char *)_cod, "Invalid position : Table ", (const char *)_tabname);
  return status();
}