#include <applicat.h>
#include <automask.h>
#include <browfile.h>
#include <dongle.h>
#include <execp.h>
#include <modaut.h>
#include <prefix.h>
#include <progind.h>
#include <relation.h>

#include <nditte.h>
#include <partite.h>
#include <scadenze.h>
#include <pagsca.h>
#include <saldi.h>

#include "ceeur.h"
#include "ceeur10.h"
#include "ceeur11.h"

#include "movce.h"

#include "../cg/cglib01.h"
#include "../mg/mag.h"
#include "../mg/movmag.h"
#include "../mg/rmovmag.h"
#include "../mg/mglib.h"

///////////////////////////////////////////////////////////
// Main app
///////////////////////////////////////////////////////////

class TEuro01_app : public TEuro_app
{ 
  TEsercizi_contabili _esc;

protected:
  virtual bool create();
  virtual void main_loop();

public:
  TEsercizi_contabili& esc() { return _esc; }

  void copy_cespi();

  void convert_saldi(int codes);
  void convert_saldi_file(int lf, int codes);

  void convert_mov(int codes, bool infra);
  void convert_mov_file(int lf, int codes);

  KEY convert_firm(long ditta);
};

inline TEuro01_app& app() { return (TEuro01_app&)main_app(); }

///////////////////////////////////////////////////////////
// Step 1
///////////////////////////////////////////////////////////

class TEuro03_mask : public TAutomask
{ 
  void fill_ditte();
  
public:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  TEuro03_mask() : TAutomask("ceeur10") { }
};

void TEuro03_mask::fill_ditte()
{
  TFilename lit, eur;
  app().get_aree_dati(lit, eur);

  TRelation rel(LF_NDITTE);
  TCursor cur(&rel); 
  const TRectype& curr = rel.curr();
  const long items = cur.items();
  cur.freeze();
  
  TSheet_field& ditte = sfield(F10_DITTE);
  ditte.destroy();
  
  for (cur = 0L; cur.pos() < items; ++cur)
  {
    const long ditta = curr.get_long(NDT_CODDITTA);
    if (prefix().exist(ditta))
    {
      TToken_string& row = ditte.row(-1);
      row.add(ditta);
      row.add(curr.get(NDT_RAGSOC));
      
      TFilename firm; 
      firm.format("%s/%05ldA", (const char*)eur, ditta);
      
      if (firm.exist())
      {           
        row.add("X");
        firm.add("prassid.ini");
        TConfig ini(firm, "Euro");
        TString16 dde = ini.get("DataAdozione");
        if (dde.empty()) dde = "01-01-2002";
        row.add(dde);
        
        if (ini.get_bool("Cespiti"))
          row.add("X");

        if (field(F10_DITTA).empty())
        {
          set(F10_DITTA, ditta);
          set(F10_RAGSOC, row.get(1));
        }
      }
      else
      {
        ditte.disable_row(ditte.items()-1);
      }
    }
  }
  
  ditte.force_update();
}

bool TEuro03_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {              
  case F10_DITTA:
    if (e == fe_modify || e == fe_close)
    {
      TSheet_field& s = sfield(F10_DITTE);
      TEdit_field& f = efield(F10_DITTA);
      const long ditta = atol(o.get());
      for (int r = s.items()-1; r >= 0; r--)
      {
        TToken_string& row = s.row(r);
        const long d = row.get_long(0);
        if (d == ditta)
        {
          set(F10_RAGSOC, row.get());
          break;
        }
      }
      if (r < 0)
        return error_box(f.get_warning());
    }
    break;
  case F10_DITTE:
    if (e == fe_init)
      fill_ditte();
    if (e == se_query_add || e == se_query_del)
      return FALSE;
    if (e == se_enter)  
    {
      TSheet_field& s = sfield(F10_DITTE);
      TToken_string& r = s.row((int)jolly);
      set(F10_DITTA, r.get(0));
      set(F10_RAGSOC, r.get());
    }
    break;
  default: 
    break;
  }
  return TRUE;
} 

///////////////////////////////////////////////////////////
// Step 2 - Conversione ditta
///////////////////////////////////////////////////////////

class TEuro11_mask : public TAutomask
{ 
public:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  TEuro11_mask();
};

TEuro11_mask::TEuro11_mask() : TAutomask("ceeur11") 
{ 
  disable(F11_ADOZIONE);
}

bool TEuro11_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  return TRUE;
}

///////////////////////////////////////////////////////////
// Conversione ditta
///////////////////////////////////////////////////////////

KEY TEuro01_app::convert_firm(long ditta)
{          
  TFilename lit, eur;
  get_aree_dati(lit, eur);
  prefix().set_studio(lit, ditta);

  TString16 firm; firm.format("%05ldA", ditta);
  TFilename litf = lit; litf.add(firm);
  TFilename eurf = eur; eurf.add(firm);
  
  TFilename europrassid;
  europrassid = eurf; europrassid.add("prassid.ini");
  
  TDate adozione;
  bool already_present = FALSE;
  if (!adozione.ok())
  {
    TConfig prassid(europrassid, "Euro");
    already_present = prassid.get_bool("Cespiti");
    adozione = prassid.get("DataAdozione");
  }
  
  bool do_copy = TRUE;
  bool do_saldi = TRUE;
  bool do_movim = TRUE;

  TEuro11_mask m;
  m.set(F11_DITTA, ditta, TRUE);
  m.set(F11_DATI, lit);
  m.set(F11_DATIE, eur);
  m.set(F11_ADOZIONE, adozione);
    
  m.enable(F11_COPY, already_present);
  m.set(F11_COPY, do_copy ? "X" : "");

  m.enable(F11_SALDI, already_present);
  m.set(F11_SALDI, do_saldi ? "X" : "");

  m.enable(F11_MOVIM, already_present);
  m.set(F11_MOVIM, do_movim ? "X" : "");
    
  KEY k = m.run();
  if (k == K_ENTER)
  {
    if (already_present && !yesno_box(FR("Si conferma la sovrascrittura dei cespiti della ditta %ld in Euro?"), ditta))
      return K_ESC;
      
    do_copy = m.get_bool(F11_COPY);
    do_saldi = m.get_bool(F11_SALDI);
    do_movim = m.get_bool(F11_MOVIM);

    const bool infra = adozione.day() != 1 || adozione.month() != 1;
    const int codes = infra ?  _esc.date2esc(adozione) : _esc.date2prevesc(adozione);
    if (do_copy)
      copy_cespi();
    if (do_saldi)
      convert_saldi(codes);
    if (do_movim)
      convert_mov(codes, infra);
    if (!already_present)
    {
      TConfig prassid(europrassid, "Euro");
      prassid.set("Cespiti", "X");
    }
  }  
  return k;
}

///////////////////////////////////////////////////////////
// Copia cespiti
///////////////////////////////////////////////////////////

struct TCespi_data
{ 
  int _codes;
  TEsercizi_contabili _esc;      
  TLocalisamfile* _movcelit;
  TEuroisamfile* _movce;
  
public:
  TCespi_data(int codes, bool movce = FALSE);
  ~TCespi_data();
};

TCespi_data::TCespi_data(int codes, bool movce) 
           : _codes(codes), _movce(NULL)
{ 
  if (movce)     
  {
    _movcelit = new TLocalisamfile(LF_MOVCE);
    _movce = new TEuroisamfile(LF_MOVCE, TRUE);
  }
}

TCespi_data::~TCespi_data() 
{
  if (_movce) 
  {
    delete _movce;
    delete _movcelit;
  }
}

void TEuro01_app::copy_cespi()
{
  convert_file(LF_CESPI, NULL, NULL);
}

///////////////////////////////////////////////////////////
// Conversione saldi
///////////////////////////////////////////////////////////

HIDDEN bool codes_filter(TRectype& rec, void* jolly)
{
  const TCespi_data* data = (const TCespi_data*)jolly;
  const int codrec = rec.get_int("CODES");
  return data->_codes == codrec;
}

void TEuro01_app::convert_saldi_file(int lf, int codes)
{
  TToken_string fields;
  TString desc;
  if (lf > LF_TAB)
  {
    TLocalisamfile file(lf);
    const TRectype& rec = file.curr();
    for (int i = rec.items()-1; i >= 0; i--)
    {
      const char* name = rec.fieldname(i);
      const int length = rec.length(name);
      const int ndec = rec.ndec(name);
      if (length >= 9 && ndec >= 2)
        fields.add(name);
    }
    desc << "Conversione " << file.description();
  }
  
  TCespi_data data(codes); 
  convert_file(lf, fields, NULL, codes_filter, (void*)&data);
}

void TEuro01_app::convert_saldi(int codes)
{
  convert_saldi_file(LF_SALCE, codes);
  convert_saldi_file(LF_AMMCE, codes);
}

///////////////////////////////////////////////////////////
// Conversione movimenti cespiti
///////////////////////////////////////////////////////////

HIDDEN bool mov_filter(TRectype& rec, void* jolly)
{ 
  TCespi_data* data = (TCespi_data*)jolly;
  TDate dtmov;
  switch (rec.num())
  {
  case LF_MOVCE:    
    dtmov = rec.get(MOVCE_DTMOV); 
    break;
  default: 
    {
      CHECK(data->_movce, "Bad TCespi_data");
      const TString16 idmov = rec.get(MOVCE_IDMOV);
      TRectype& head = data->_movce->curr();
      head.zero();
      head.put(MOVCE_IDMOV, idmov);
      if (data->_movce->read(_isgteq) == NOERR)
      {    
        if (head.get(MOVCE_IDMOV) == idmov)
          dtmov = head.get(MOVCE_DTMOV);
      }
    }
    break;
  } 
  const int codrec = data->_esc.date2esc(dtmov);
  return data->_codes == codrec;                      
}

void TEuro01_app::convert_mov_file(int lf, int codes)
{
  TToken_string fields;
  
  if (lf > LF_TAB)
  {
    TLocalisamfile file(lf);
    const TRectype& rec = file.curr();
    for (int i = rec.items()-1; i >= 0; i--)
    {
      const char* name = rec.fieldname(i);
      const int length = rec.length(name);
      const int ndec = rec.ndec(name);
      if (length >= 9 && ndec >= 2)
        fields.add(name);
    }
  }
  
  TCespi_data data(codes, lf != LF_MOVCE);
  convert_file(lf, fields, NULL, mov_filter, (void*)&data);
}

void TEuro01_app::convert_mov(int codes, bool infra)
{
  if (infra)
  {
    convert_mov_file(LF_MOVCE, codes);
    convert_mov_file(LF_MOVAM, codes);
    convert_mov_file(LF_AMMMV, codes);
  }
  else
  {
    zap_file(LF_MOVCE);
    zap_file(LF_MOVAM);
    zap_file(LF_AMMMV);
  }
}

///////////////////////////////////////////////////////////
// Main 
///////////////////////////////////////////////////////////

bool TEuro01_app::create()
{                
  TFilename lit, eur;
  if (!app().get_aree_dati(lit, eur))
    return error_box(TR("Non esiste lo studio in Euro di destinazione"));
  return TEuro_app::create();  
}

void TEuro01_app::main_loop()
{ 
  long ditta = 0L;
  if (goto_lire())
  {
    TEuro03_mask m;
    if (m.run() == K_ENTER)
      ditta = m.get_long(F10_DITTA);
  }
  if (ditta > 0L)
    convert_firm(ditta);
}

int ceeur01(int argc, char* argv[])
{  
  TEuro01_app ma;
  ma.run(argc, argv, TR("Conversione Cespiti Euro"));
  
  return 0;
}