#include <time.h>

#include <applicat.h>
#include <mask.h>
#include <progind.h>
#include <urldefid.h>

#include <relapp.h>

///////////////////////////////////////////////////////////
// Test Relapp
///////////////////////////////////////////////////////////

class TTestrel_application : public TRelation_application
{
  const char* _maskname;
  const char* _num;

  TRelation* _rel;
  TMask* _msk;

protected:
  virtual bool user_create();
  virtual bool user_destroy();
  virtual TMask* get_mask(int) { return _msk; }
  virtual bool changing_mask(int) { return FALSE;}
  virtual TRelation* get_relation() const { return _rel; }
  virtual int read(TMask& m) { m.autoload(*_rel); return NOERR; }
  virtual int write(const TMask&) { return NOERR; }
  virtual int rewrite(const TMask&) { return NOERR; }

public:
  TTestrel_application(const char* name, const char* num);
};

TTestrel_application::TTestrel_application(const char* name, const char* num)
: _maskname(name), _num(num),
  _msk(NULL), _rel(NULL)
{}


bool TTestrel_application::user_create()
{
  _msk = new TMask(_maskname);

  int id = atoi(_num);
  if (id > 0) _rel = new TRelation(id);
  else _rel = new TRelation(_num);

  return TRUE;
}

bool TTestrel_application::user_destroy()
{
  delete _msk;
  delete _rel;
  return TRUE;
} 

///////////////////////////////////////////////////////////
// Testmask
///////////////////////////////////////////////////////////

class TTest_application : public TApplication
{
  TFilename _maskname;

protected:
  bool create() { dispatch_e_menu(BAR_ITEM(1)); return TRUE; }
  bool destroy() { return TRUE; }
  bool menu(MENU_TAG);

public:
  TTest_application(const char* name) : _maskname(name) {}
};

bool TTest_application::menu(MENU_TAG)
{ 
  TMask m(_maskname);
  KEY k = m.run();
  if (k == K_QUIT) stop_run();

  return k != K_QUIT;
}

///////////////////////////////////////////////////////////

class TBenchmark_application : public TApplication
{          
  TIndwin* _iw;
  clock_t _timer;
  
protected:
  virtual bool create();
  virtual bool destroy();
  virtual bool menu(MENU_TAG);
  
  void initializing();
  void start_test(const char* msg);
  void stop_test();
  
  void test_relation_scan();

public:
  TBenchmark_application() : _iw(NULL) { } 
  virtual ~TBenchmark_application() { }
};

bool TBenchmark_application::create()
{                               
  dispatch_e_menu(MENU_ITEM(1));
  return TRUE;
}

bool TBenchmark_application::destroy()
{                               
  if (_iw) 
  { 
    delete _iw;
    _iw = NULL;
  }  
  return TRUE;
}


bool TBenchmark_application::menu(MENU_TAG)
{
  TString test = argv(1); test.upper();
  const bool test_all = test.find('A') >= 0;
  
  if (test_all || test.find('R') >= 0)
    test_relation_scan();
    
  return TRUE;  
} 

void TBenchmark_application::initializing()
{
  CHECK(_iw == NULL, "Benchmark already in progress");
  _iw = new TIndwin(48, "Initializing ...", FALSE, TRUE, 48);
}

void TBenchmark_application::start_test(const char* text)
{
  CHECK(_iw != NULL, "Benchmark not started yet");
  _iw->set_text(text);
  
  clock_t _timer = clock(), t;
  do
  { 
    t = clock(); 
  } while (t == _timer);
  _timer = t;
}

void TBenchmark_application::stop_test()
{
  CHECK(_iw != NULL, "Benchmark not started yet");
  const clock_t t = clock() - _timer; 
  const double s = t / CLOCKS_PER_SEC;
  TString80 msg;
  msg.format("Time to complete: %.1lf s", s);
  _iw->set_text(msg);
  
  while (!_iw->is_cancelled())
    do_events();
  
  delete _iw;  
  _iw = NULL;
}

void TBenchmark_application::test_relation_scan()
{ 
  initializing();
  
  TRelation comuni(LF_COMUNI);
  comuni.add("%UID", "CODTAB=UFFIIDD1");
  comuni.first();
  
  start_test("Scansione COMUNI+%UID");
  
  while (!comuni.eof())
    comuni.next();
  
  stop_test();
}

///////////////////////////////////////////////////////////

int main(int argc, char** argv)
{
  TApplication::check_parameters(argc, argv);
  
  if (argc > 1 && *argv[0] == '-')
  {
    TBenchmark_application bma;
    bma.run();
    return 0;
  }
  
  if (argc < 3)
  { 
    TFilename n;
    if (argc == 1)
    {
      TMask m("Inserire il nome della maschera", 1, 42, 4);
      m.add_string(101, 0, "", 1, 1, 40);
      m.field(101).check_type(CHECK_REQUIRED);
      m.add_button(DLG_OK, 0, "", -12, -1, 10, 2);
      m.add_button(DLG_CANCEL, 0, "", -22, -1, 10, 2);
      if (m.run() == K_ENTER)
        n = m.get(101);
    } 
    else 
      n = argv[1];
    
    if (n.not_empty())
    {
      TTest_application a(n);
      n = n.name(); n.insert("Test Mask ", 0);
      a.run(argc, argv, n);
    }  
  }
  else
  {
    TTestrel_application a(argv[1], argv[2]);
    a.run(argc, argv, "Test Relation Application");
  }

  return 0;
}

