#include <xvt.h>
#include <log.h>
#include <reprint.h>

class TError_set : public TRecordset
{
  struct TError_row : public TObject
  {
    TVariant _sev, _msg;
  };

  TRecnotype _cur;
  TArray _log;
  TRecordset_column_info _info[2];

public:
  virtual TRecnotype items() const;
  virtual bool move_to(TRecnotype pos);
  virtual TRecnotype current_row() const;
  virtual void requery();
  virtual unsigned int columns() const;
  virtual const TRecordset_column_info& column_info(unsigned int column) const;
  virtual const TVariant& get(unsigned int column) const;

  void reset(const char* header);
  void log(long sev, const char* msg);

  TError_set();
  virtual ~TError_set();
};

///////////////////////////////////////////////////////////
// TError_set
///////////////////////////////////////////////////////////

TRecnotype TError_set::items() const
{ return _log.items(); }

bool TError_set::move_to(TRecnotype pos)
{
  _cur = pos;
  return pos >= 0 && pos < items();
}

TRecnotype TError_set::current_row() const
{ return _cur; }

void TError_set::requery()
{ _cur = -1; }

unsigned int TError_set::columns() const
{ return 2; }

const TRecordset_column_info& TError_set::column_info(unsigned int i) const
{ return _info[i % columns()]; }

const TVariant& TError_set::get(unsigned int column) const
{
  if (_cur >= 0 && _cur < items())
  {
    const TError_row& row = (const TError_row&)_log[_cur];
    switch(column)
    {
    case  0: return row._sev;
    case  1: return row._msg;
    default: return NULL_VARIANT;
    }
  }
  return NULL_VARIANT;
}

void TError_set::reset(const char* header)
{ 
  set_var("#HEADER", header, true);
  _log.destroy(); 
}

void TError_set::log(long sev, const char* msg)
{
  TError_row* row = new TError_row;
  row->_sev = sev;
  row->_msg = msg;
  _log.add(row);
}

TError_set::TError_set() : _log(NULL)
{
  _info[0]._name = "SEVERITY";
  _info[0]._width = 1;
  _info[0]._type = _intfld;

  _info[1]._name = "MESSAGE";
  _info[1]._width = 80;
  _info[1]._type = _alfafld;
}

TError_set::~TError_set()
{
}

void TError_log::log(long sev, const char* msg)
{
	if (_log == NULL)
		_log = new TError_set;
	((TError_set*)_log)->log(sev, msg);
}

void TError_log::set_header(const char* header)
{
	if (_log == NULL)
		_log = new TError_set;
	((TError_set*)_log)->reset(header);
}

bool TError_log::show()
{
	bool ok = _log != NULL && _log->items() > 0 ;
	if (ok)
	{
		TReport rep;
		ok = rep.load(_rep);
		if (ok)
		{
			rep.set_recordset(_log);
			_log = NULL;
			TReport_book book;
			book.add(rep);
			book.preview();
		}
	}
	return ok;
}

TError_log::TError_log() : _rep("bagnerrlog"), _log(NULL)
{
}

TError_log::~TError_log()
{
	if (_log != NULL)
		delete _log;
}