#include <direct.h>
#include <applicat.h>
#include <archives.h>
#include <assoc.h>
#include <mask.h>    
#include <progind.h>
#include <relation.h>
#include <tabutil.h>
#include <urldefid.h>
#include <utility.h>

#include "ve5100a.h"    

#include "velib01.h"

class TDeletedoc_app : public TApplication
{                                     
  TArchive       _arc;      
  TArray         _to_zap;    // Array contenente le chiavi dei documenti da eliminare
  TString        _desc, _last_std;
  char           _unit;
  TFilename      _tmp_dir;
  TIsamtempfile  *_tdoc,*_trdoc;
  
protected:

  void backup_delete_doc();    // Backup e cancellazione dei documenti da eliminare
  void restore_doc();          // Ripristino documenti da disco
  void create_tmp_files(bool create=TRUE);
  void delete_tmp_files(bool remove=TRUE);
  virtual bool create();
  virtual bool destroy();
  virtual bool menu(MENU_TAG m);  

static bool state_handler(TMask& m, KEY k);
  
public:

  TDeletedoc_app() {};  
  ~TDeletedoc_app() {};  
};

bool TDeletedoc_app::state_handler(TMask& m, KEY k)
{
  if (k == K_SHIFT + K_F7)
    m.enable(F_STATUS);
  
  return TRUE;
}

void TDeletedoc_app::backup_delete_doc()
{
  TRecnotype total = 0;   
  TDocumento documento;
  
  TIsamfile doc(LF_DOC,FALSE);
  TLocalisamfile rdoc(LF_RIGHEDOC);
  
  doc.open();
  int err = doc.lock();
  if (err != NOERR) 
  {
    error_box("Il file documenti non puo' essere bloccato in modo esclusivo."
              " Nessun documento cancellato. Errore %d.",err);
    return;
  }
  create_tmp_files();
  doc.zero();                                        
  // Scorre il file dei documenti
  {
    TProgind p(10, "Ricerca e copia dei documenti da eliminare...", TRUE, FALSE, 10);
    for (doc.first();doc.good() && !p.iscancelled();doc.read(_isgreat))
    {
      documento.read(doc.curr());
      bool to_delete = TRUE;
      
      if (doc.get("STATO") != _last_std) to_delete = FALSE;
  
      if (to_delete && !p.iscancelled()) // Se TRUE il puo' essere eliminato!
      {              // Memorizza la chiave 1 del documento in un array
        TToken_string id(30);
        id = doc.get("PROVV");
        id.add(doc.get("ANNO"));
        id.add(doc.get("CODNUM"));
        id.add(doc.get("NDOC"));
        _to_zap.add(id);
        err = _tdoc->write(doc.curr());
        const int rows = documento.rows();
        // Memorizza le righe del documento sui file temporanei
        for (int x=1;err==NOERR && x<=rows;x++)
            err=_trdoc->write(documento[x]);                            
        total++;
      }       
    }  // end of for
    if (p.iscancelled()) total=0;
  }
  
  if (total != 0)                                        
    if (err==NOERR)           
  {
    const char * dir = &_tmp_dir[1];
    delete_tmp_files(FALSE); //Close tmp files only
    bool rt = _arc.backup(dir,_unit,_desc,FALSE);// Backup dei documenti da eliminare, prefix unnecessary
    create_tmp_files(FALSE); // Reopen tmp files.
    if (rt) 
    {
      // Effettiva cancellazione dei documenti
      TString80 caption("Cancellazione di ");
      caption.add_plural(total, "documento");
      if (!yesno_box(caption))
        _to_zap.destroy();
      else
      {
        TProgind pi(total, caption, FALSE, TRUE, 10);
        const int items = _to_zap.items();
        for (int i = 0; i < items; i++)
        {          
          TToken_string& id = (TToken_string&)_to_zap[i];        
          id.restart();
          const char provv = id.get_char();
          const int  anno  = id.get_int();
          const TString16 codnum = id.get();
          const long numdoc = id.get_int();
          documento.read(provv,anno,codnum,numdoc);
          documento.remove();
          pi.addstatus(1);
        }   
      }
    }                                          
  }
  else
    error_box("Errore %d scrivendo sui files temporanei."
              " La cancellazione dei documenti chiuse non verra' effettuata.",err);
  delete_tmp_files();    // Physical remove of tmp files
  doc.close();
}

void TDeletedoc_app::restore_doc()
{
  TIsamfile doc(LF_DOC,FALSE);
  TLocalisamfile rdoc(LF_RIGHEDOC);

  doc.open();
  int err = doc.lock();
  if (err != NOERR)  
  {
    error_box("Il file documenti non puo' essere bloccato in modo esclusivo."
              " Nessuna documento ripristinato. Errore %d.",err);
    return ;
  }
  const char* dir =& _tmp_dir[1]; // Cut out % sign
  if (_arc.restore(dir,_unit,FALSE,FALSE))
  {
    create_tmp_files(FALSE);  // In realta' ci sono gia'
    const TRecnotype items = _tdoc->items() + _trdoc->items();
    TProgind pi(items, "Ripristino documenti eliminati", FALSE, TRUE, 10);

    for (_tdoc->first();_tdoc->good() && err==NOERR;_tdoc->next())
    {
      if ((err=doc.write(_tdoc->curr())) == _isreinsert)
        err=doc.rewrite(_tdoc->curr());
      pi.addstatus(1);
    }
    if (err != NOERR) 
      error_box("Errore %d ripristinando il file DOCUMENTI.",err);  
    else
    {
      for (_trdoc->first();_trdoc->good() && err==NOERR;_trdoc->next())
      {
        if ((err=rdoc.write(_trdoc->curr())) == _isreinsert)
          err=rdoc.rewrite(_trdoc->curr());
        pi.addstatus(1);
      }
      if (err != NOERR)
        error_box("Errore %d ripristinando il file RIGHE DOCUMENTI.",err);  
    }
    delete_tmp_files();  // Removes tmp files!
  } 
  else
    error_box("Errore nel ripristino dei file da dischetto. Nessuna documento ripristinato.");
  doc.close();
}

void TDeletedoc_app::create_tmp_files(bool create)
{
  TFilename tf(_tmp_dir);
  tf << "/" << "f1";
  _tdoc   = new TIsamtempfile(LF_DOC,tf,create);
  tf.rtrim(1);tf << "2";
  _trdoc   = new TIsamtempfile(LF_RIGHEDOC,tf,create);
}                     

void TDeletedoc_app::delete_tmp_files(bool remove)
{
  if (remove)        // Cosi' posso forzare la cancellazione in chiusura
  {
    _tdoc->set_autodel();
    _trdoc->set_autodel();
  }
  delete _tdoc;
  delete _trdoc;
}

bool TDeletedoc_app::create()
{
  TApplication::create();
  _tmp_dir.temp();
  _tmp_dir = _tmp_dir.path();
  _tmp_dir << "VE";
  if (!fexist(_tmp_dir)) make_dir(_tmp_dir);
  _tmp_dir.insert("%");  // Add % sign 
  dispatch_e_menu(BAR_ITEM(1));
  return TRUE;
}

bool TDeletedoc_app::destroy()
{                
  _tmp_dir=_tmp_dir.sub(1); // Cut out % sign
  if (fexist(_tmp_dir)) rmdir(_tmp_dir);      
  return TApplication::destroy();
}

bool TDeletedoc_app::menu(MENU_TAG)
{               
  TMask m("ve5100a");
  
  TTable std("%STD");
  
  std.last(); // Reperisce lo stato eliminabile
  
  _last_std = std.get("CODTAB");
  
  m.set(F_STATUS,_last_std);
  m.set(F_STADESC,std.get("S0"));
  m.set_handler(state_handler);
  
  while (m.run() != K_QUIT) 
  {                 
    _unit       = m.get(F_UNIT)[0];
    _desc       = m.get(F_DESC);
    const int scelta = m.get_int(F_OPERAZIONE);
    if (scelta == 1)
      backup_delete_doc(); 
    else
      restore_doc();
  }
  return FALSE;
}


int ve5100(int argc, char** argv)
{
  TDeletedoc_app a;
  a.run(argc, argv, "Eliminazione documenti");
  return 0;
}

