#include <applicat.h>
#include <msksheet.h>
#include <relation.h>
#include <sheet.h>
#include <utility.h>

#include "ef0.h"
#include "ef0101.h"
#include "ef0400.h"

/////////////////////////////////////////////////////////////////////////////
//Classe per l'eliminazione di effetti di effetti con selezione per gruppi //
/////////////////////////////////////////////////////////////////////////////
class TEliminazione_effetti: public TSkeleton_application
{
  TMask *_msk;
  TRelation *_rel;
  TRectype *_from, *_to;
  virtual bool create() ;
  virtual bool destroy() ;
  virtual void main_loop();
protected:
  static bool from_numero_handler(TMask_field& f, KEY k);
  static bool to_numero_handler(TMask_field& f, KEY k);
  static bool from_data_handler(TMask_field& f, KEY k);
  static bool to_data_handler(TMask_field& f, KEY k);
  static bool conferma_handler(TMask_field& f, KEY k);
  static bool annulla_handler(TMask_field& f, KEY k);
  static void elimina();
public:
  TEliminazione_effetti() {};
  virtual ~TEliminazione_effetti() {};
};

// restituisce un riferimento all' applicazione
inline TEliminazione_effetti& app(){return (TEliminazione_effetti&)main_app();}

// crea l'applicazione
bool TEliminazione_effetti::create()
{
  _msk = new TMask("ef0400a");
  _rel = new TRelation(LF_EFFETTI);
  _rel->first();
  _from = new TRectype(_rel->lfile().curr());
  _rel->last();
  _to = new TRectype(_rel->lfile().curr());
  _msk->set_handler(F_DA_RIBA, from_numero_handler);
  _msk->set_handler(F_A_RIBA, to_numero_handler);
  _msk->set_handler(F_DA_DATA, from_data_handler);
  _msk->set_handler(F_A_DATA, to_data_handler);
  _msk->set_handler(DLG_OK, conferma_handler);
  _msk->set_handler(DLG_CANCEL, annulla_handler);
  return TSkeleton_application::create();
}

// distrugge l'applicazione
bool TEliminazione_effetti::destroy()
{
  delete _msk;
  delete _rel;
  delete _from;
  delete _to;
  return TRUE;
}

//Carica maschera eliminazione effetti
void TEliminazione_effetti::main_loop()
{
  KEY key = K_ENTER;
  while (key != K_QUIT)//finch� non si chiude la maschera
  {
    _msk->reset();
    key = _msk->run();
  }
}

//Handler per la gestione della prima chiave (from) del cursore per numero
bool TEliminazione_effetti::from_numero_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_TAB)
  {
    if (!f.get().empty())// se il campo non � vuoto
    {
      TRectype* from = app()._from;
      long num = m.get_long(F_DA_RIBA);
      from->put(EFF_NPROGTR, num);
    }
  }
  return TRUE;
}

//Handler per la gestione della seconda chiave (to) del cursore per numero
bool TEliminazione_effetti::to_numero_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_TAB)
  {
    if (!f.get().empty())// se il campo non � vuoto
    {
      TRectype* to = app()._to;
      long num = m.get_long(F_A_RIBA);
      to->put(EFF_NPROGTR, num);
    }
  }
  return TRUE;
}

//Handler per la gestione della prima chiave (from) del cursore per data
bool TEliminazione_effetti::from_data_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_TAB)
  {
    if (!f.get().empty())// se il campo non � vuoto
    {
      TRectype* from = app()._from;
      TDate data = m.get(F_DA_DATA);
      long num = m.get_long(F_DA_RIBA);
      from->put(EFF_NPROGTR, num);
      from->put(EFF_DATASCAD, data);
    }
  }
  return TRUE;
}

//Handler per la gestione della seconda chiave (to) del cursore per numero
bool TEliminazione_effetti::to_data_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_TAB)
  {
    if (!f.get().empty())// se il campo non � vuoto
    {
      TRectype* to = app()._to;
      TDate data = m.get(F_A_DATA);
      long num = m.get_long(F_A_RIBA);
      to->put(EFF_NPROGTR, num);
      to->put(EFF_DATASCAD, data);
    }
  }
  return TRUE;
}

// Si effettua l'istanziazione del cursore e si eliminano gli effetti che vi
// appartengono
void TEliminazione_effetti::elimina()
{
  const TRectype *from = app()._from;
  const TRectype *to = app()._to;
  TMask *m = app()._msk;
  TRelation *rel = app()._rel;
  TString filter;
   
  int key;
  char op1 = m->get(F_TIPOSEL)[0];
  char op2 = m->get(F_TIPODIST)[0];
  char op3 = m->get(F_TIPOCANC)[0];
  switch (op1) //scelgo la chiave per il cursore
  {
   case 'N':  //selezione effetti per numero
        key = 1;
        break;
   case 'D':  //selezione effetti per data
        key = 3;
        break;
  }            
  //scelgo il filtro per il cursore
  filter << "(TIPOCF=\"" << op2 << "\")";
  if (op2 == 'C')
    filter << "||(TIPOCF=\"\")";
  switch (op3) 
  {
   case 'S':  //cancello effetti stampati
        filter << "&&(EFFSTAMP=\"X\")";
        break;
   case 'C':  //cancello effetti contabilizzati
        filter << "&&(EFFCONT=\"X\")";
        break;
   default :  //cancello tutti gli effetti
        break;
  }
  TCursor cur(rel,filter,key,from,to); // istanzio il cursore
  TLocalisamfile& delfile = cur.file();// prendo un riferimento al file
  long n = cur.items();// prendo il numero di elementi del cursore
  cur.freeze();// congelo lo stato del cursore
  for (cur=0; cur.pos() < n; ++cur)// scandisco tutti gli elementi del cursore
  {
    TEffetto eff(delfile.curr());// istanzio un effetto
    eff.remove(delfile);         // e lo cancello
  }
}

//Handler per gestire la conferma della cancellazione degli effetti
bool TEliminazione_effetti::conferma_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_SPACE)
  {
    if (yesno_box(TR("Si desidera veramente eliminare gli effetti selezionati")))
      elimina();
  }
  return TRUE;
}

// Handler per gestire la conferma dell'annullamento dei dati
// inseriti nella maschera
bool TEliminazione_effetti::annulla_handler(TMask_field& f, KEY k)
{
  TMask &m = f.mask();
  if (k == K_SPACE)
  {
    if (yesno_box(TR("Si desidera veramente annullare i dati inseriti")))
       m.reset();
  }
  return TRUE;
}

int ef0400(int argc, char* argv[])
{
  TEliminazione_effetti a ;
  a.run(argc, argv, TR("Eliminazione Effetti"));
  return 0;
}