#include <applicat.h>
#include <assoc.h>
#include <isam.h>
#include <mask.h>
#include <prefix.h>
#include <urldefid.h>
#include <utility.h>

#include "cg4.h"
#include "cg4200.h"

#include <pconti.h>

class TCopia_archivi : public TApplication
{
  TMask* _msk;
  long _default_firm;

  virtual bool create() ;                         
  virtual bool destroy() ;                        
  bool menu(MENU_TAG);
  bool copyfile(int logicnum, long from, long to);
  bool check_comfile(int logicnum);
  void clearivd(long to);
  void copyivd(long from, long to);

public:
  TCopia_archivi() : _msk(NULL) {}
};    

bool TCopia_archivi::check_comfile(int logicnum)
{                    
  TDir dir;
  
  dir.get(logicnum, _nolock, _comdir);
  
  if (fexist(dir.filename())) 
    return TRUE;
  else
    return error_box("Non esiste il file sorgente : archivi comuni - %s",  dir.filename());
}    

bool TCopia_archivi::copyfile(int logicnum, long from, long to)
{    
  TDir dir;

  set_firm(to);
  dir.get(logicnum, _nolock, _nordir, _sysdirop);
  if (dir.is_com())   
  {
    dir.get(logicnum);
    return error_box("Non posso copiare su un'archivio comune : ditta %ld - archivio %s", to, dir.filename());
  }
  if (from > 0) set_firm(from);
  else
    prefix().set("com");
  TSystemisamfile file(logicnum);
  TFilename t; t.tempdir(); t << "/tr" << logicnum;
  
  if (file.dump(t) != NOERR)
    return error_box("Impossibile leggere i dati da copiare errore n. %d", file.status());
  set_firm(to);
  
  TFilename s; s.tempdir(); s << "/sv" << logicnum;

  if (file.dump(s) != NOERR)
    return error_box("Impossibile salvare i dati originali errore n. %d", file.status());


  dir.get(logicnum, _lock, _nordir, _sysdirop);
  dir.eod() = 0L;
  dir.put(logicnum, _nordir, _sysdirop);       
  file.packfile();
  file.packindex();
  if (file.load(t) != NOERR)
  {
    error_box("Impossibile scrivere i dati errore n. %d. Cerco di ripristinare i dati originali.", file.status());
    dir.get(logicnum, _lock, _nordir, _sysdirop);
    dir.eod() = 0L;
    dir.put(logicnum, _nordir, _sysdirop);
    file.packindex();
    if (file.load(s))
      error_box("Impossibile scrivere i dati originali errore n. %d", file.status());
    return FALSE;
  }
  return TRUE;
}

void TCopia_archivi::clearivd(long to)
{
  TLocalisamfile pcon(LF_PCON);

  for (pcon.first(); pcon.good(); pcon.next())
  {
    pcon.put(PCN_SEZIVD, "0");
    pcon.zero(PCN_LETTIVD);
    pcon.zero(PCN_NUMRIVD);
    pcon.zero(PCN_NUMIVD);
    pcon.put(PCN_SEZIVDOPP, "0");
    pcon.zero(PCN_LETTIVDOPP);
    pcon.zero(PCN_NUMRIVDOPP);
    pcon.zero(PCN_NUMIVDOPP);
    pcon.rewrite();
  }
}

void TCopia_archivi::copyivd(long from, long to)
{
  if (from > 0) set_firm(from);
  else prefix().set("com");
  TLocalisamfile pcon(LF_PCON);
  TAssoc_array riclass;

  for (pcon.first(); pcon.good(); pcon.next())
  {
    TString16 key;
    TToken_string data;
    
    key.format("%03d%03d%06ld", pcon.get_int(PCN_GRUPPO),
               pcon.get_int(PCN_CONTO), pcon.get_long(PCN_SOTTOCONTO));
    data.add(pcon.get(PCN_SEZIVD));
    data.add(pcon.get(PCN_LETTIVD));
    data.add(pcon.get(PCN_NUMRIVD));
    data.add(pcon.get(PCN_NUMIVD));
    data.add(pcon.get(PCN_SEZIVDOPP));
    data.add(pcon.get(PCN_LETTIVDOPP));
    data.add(pcon.get(PCN_NUMRIVDOPP));
    data.add(pcon.get(PCN_NUMIVDOPP));
    riclass.add(key, data);
  }
  set_firm(to);
  for (pcon.first(); pcon.good(); pcon.next())
  {
    TString16 key;
    
    key.format("%03d%03d%06ld", pcon.get_int(PCN_GRUPPO),
               pcon.get_int(PCN_CONTO), pcon.get_long(PCN_SOTTOCONTO));

    TToken_string * data = (TToken_string *) riclass.objptr(key);

    if (data == NULL)
    {
      pcon.put(PCN_SEZIVD, "0");
      pcon.zero(PCN_LETTIVD);
      pcon.zero(PCN_NUMRIVD);
      pcon.zero(PCN_NUMIVD);
      pcon.put(PCN_SEZIVDOPP, "0");
      pcon.zero(PCN_LETTIVDOPP);
      pcon.zero(PCN_NUMRIVDOPP);
      pcon.zero(PCN_NUMIVDOPP);
    }
    else
    {
      pcon.put(PCN_SEZIVD, data->get(0));
      pcon.put(PCN_LETTIVD, data->get());
      pcon.put(PCN_NUMRIVD, data->get());
      pcon.put(PCN_NUMIVD, data->get());
      pcon.put(PCN_SEZIVDOPP, data->get());
      pcon.put(PCN_LETTIVDOPP, data->get());
      pcon.put(PCN_NUMRIVDOPP, data->get());
      pcon.put(PCN_NUMIVDOPP, data->get());
    }
    pcon.rewrite();
  }
}

bool TCopia_archivi::create()
{
  TApplication::create();
  _msk = new TMask("cg4200a") ;
  _default_firm = get_firm();
  dispatch_e_menu(BAR_ITEM(1));
  return TRUE;
}

bool TCopia_archivi::destroy()
{
  if (_msk != NULL) delete  _msk;
  return TApplication::destroy();
}

bool TCopia_archivi::menu(MENU_TAG)
{
  while (_msk->run() == K_ENTER)
  {
    const long from_firm = _msk->get_long(F_FROMFIRM);
    const long to_firm = _msk->get_long(F_TOFIRM);
    if (from_firm == to_firm)
      error_box("La copia si puo' effettuare solo tra due ditte diverse");
    else
    {
      const bool copy_pcon = _msk->get_bool(F_PCON);
      const bool copy_causali = _msk->get_bool(F_CAUS);
      const bool copy_clifo = _msk->get_bool(F_CLIFO);
      const bool copy_ivd = _msk->get_bool(F_IVD);
      if (copy_pcon || copy_causali || copy_clifo || copy_ivd) 
      {
        bool ok = TRUE;
        if (copy_pcon) ok = check_comfile(LF_PCON);
        if (ok && copy_causali) ok = check_comfile(LF_CAUSALI) && check_comfile(LF_RCAUSALI);
        if (ok && copy_clifo) ok = check_comfile(LF_CLIFO);
        if (ok && prefix().exist(to_firm))
        {
          set_firm(to_firm);
        {
          TLocalisamfile mov(LF_MOV);
          ok = (mov.eod() == 0);
        }
          
          if (ok || (!copy_pcon && !copy_causali && !copy_clifo)) 
          {
            TString256 mess("Attenzione \n");
            int count = 0;
            
            if (copy_pcon)
            {
              mess << "il piano dei conti";
              count++;
            }
            if (copy_causali)
            {
              if (count > 0) mess << ",\n"; 
              mess << " le causali";
              count++;
            }
            if (copy_clifo)
            {
              if (count > 0) mess << ",\n"; 
              mess << " i clienti e fornitori";
              count++;
            }
            if (copy_ivd) 
            {
              if (count > 0) mess << ",\n"; 
              mess << " la riclassificazione IV direttiva";
              count++;
            }
            mess << "\n della ditta " << to_firm;
            if (count > 1)
              mess <<  " saranno sovrascritti";
            else
              mess <<  " sara' sovrascritto";
            mess << ". Devo continuare"; 
            if (yesno_box((const char *) mess))
            {
              mess.rtrim(16); mess << " Devo veramente continuare";
              if (yesno_box((const char *) mess))
              {
                if (copy_pcon)
                {
                  if (copyfile(LF_PCON, from_firm, to_firm) && !copy_ivd)
                    clearivd(to_firm);
                }
                if (copy_causali)
                {
                  if (copyfile(LF_CAUSALI, from_firm, to_firm))
                    copyfile(LF_RCAUSALI, from_firm, to_firm);
                }
                if (copy_clifo)
                  copyfile(LF_CLIFO, from_firm, to_firm);
                if (!copy_pcon && copy_ivd)
                  copyivd(from_firm, to_firm);
              }
            }
          }
          else error_box("La copia si puo' effettuare solo se non sono stati registrati movimenti");
          set_firm(_default_firm);
        }
        else error_box("Gli archivi della ditta %ld non sono stati ancora generati",to_firm);
        _msk->reset();
      }
    }
  }
  return FALSE;
}

int cg4200(int argc, char* argv[])
{
  TCopia_archivi a ;
  a.run(argc, argv, "Copia archivi");
  return 0;
}
