#include <automask.h>
#include <execp.h>

#include <saldi.h>

#include "baeur.h"
#include "baeur11.h"

#include "../cg/cglib01.h"


///////////////////////////////////////////////////////////
// Main app declaration
///////////////////////////////////////////////////////////

class TApertura_saldi_euro : public TEuro_app
{          
protected:      
  bool has_movs() const;
  void convert_saldi(const TDate& adozione, const TBill& arrotino);

public:
  virtual void main_loop();
};

TApertura_saldi_euro& app() { return (TApertura_saldi_euro&)main_app(); }


///////////////////////////////////////////////////////////
// Main mask
///////////////////////////////////////////////////////////

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

bool TEuro90_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  switch (o.dlg())
  {
  case F11_ADOZIONE:
    if (e == fe_modify || e == fe_close)
    {
      TEsercizi_contabili esc;
      TDate d = o.get();
      if (!d.ok())
        return error_box("E' necessario specificare la data di adozione dell'Euro");
      const int codesc = esc.date2esc(d);
      if (codesc <= 0)
        return error_box("E' necessario aprire l'esercizio per l'anno %d", d.year());
      if (d.day() != 1)
        warning_box("Si consiglia di specificare una data di inizio mese/trimestre");
    }
    break;
  default: break;
  }
  return TRUE;
}

void TEuro90_mask::on_firm_change()
{
  TAutomask::on_firm_change();

  TDate adozione;
  bool inizio;
  app().data_adozione_euro(0, adozione, inizio);
  set(F11_ADOZIONE, adozione);

  TBill arrotino;
  if (app().load_round_bill(arrotino))
  {
    arrotino.set(*this, F11_DIFF_G, F11_DIFF_C, F11_DIFF_S);
    field(F11_DIFF_S).check(STARTING_CHECK);
  }
}

TEuro90_mask::TEuro90_mask() : TAutomask("baeur11") 
{ 
  for (int i = fields()-1; i > 0; i--)
  {  
    TMask_field& f = fld(i);
    if (f.in_group(1))
    {
      if (f.dlg() == F11_SALDI)
      {
        f.set("X");
        f.disable();
      }
      else
        f.hide();
    }
  }
}

///////////////////////////////////////////////////////////
// Main app implementation
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
// Conversione saldi copiata pari pari da baeur01
///////////////////////////////////////////////////////////

struct TSaldi_data
{  
  int _annoes;
  TBill _arrot;
  TImporto _sld;
};

static bool saldi_handler(TRectype& rec, void* jolly)
{ 
  TSaldi_data& sld = *(TSaldi_data*)jolly;
  const int annoes = rec.get_int(SLD_ANNOES);
  if (annoes == sld._annoes)
  {
    const TImporto iniz(rec.get_char(SLD_FLAGSALINI), rec.get_real(SLD_SALDO));
    const TImporto pdare('D', rec.get_real(SLD_PDARE));
    const TImporto pavere('A', rec.get_real(SLD_PAVERE));
    TImporto saldo = iniz; saldo += pdare; saldo += pavere; 
    if (!saldo.is_zero())
    {
      saldo.normalize();
      rec.put(SLD_FLAGSALINI, saldo.sezione());
      rec.put(SLD_SALDO, saldo.valore());
      convert_import(rec, "SALDO");
      zero_import(rec, "PDARE|PAVERE|PDAREPRO|PAVEREPRO|FLAGSALFIN|SALDOFIN|DATAULMOV|NUMULTMOV");
      sld._sld += TImporto(saldo.sezione(), rec.get_real(SLD_SALDO));  // Somma saldo in euro
      return TRUE;
    }
  }  
  
  return FALSE;           
}

void TApertura_saldi_euro::convert_saldi(const TDate& adozione, const TBill& arrotino)
{
  TEsercizi_contabili esc;

  TSaldi_data sld;
  sld._annoes = esc.date2prevesc(adozione);
  sld._arrot = arrotino;
  convert_file(LF_SALDI, NULL, NULL, NULL, saldi_handler, &sld);
  
  TImporto& saldo = sld._sld;
  saldo.valore().round(-2);
  if (!saldo.is_zero())
  {       
    TLocalisamfile saldi_lire(LF_SALDI); // Open trc
    TEuroisamfile saldi(LF_SALDI, TRUE);
  
    TRectype& curr = saldi.curr();
    curr.zero();
    curr.put(SLD_ANNOES, sld._annoes);
    curr.put(SLD_GRUPPO, arrotino.gruppo());
    curr.put(SLD_CONTO, arrotino.conto());
    curr.put(SLD_SOTTOCONTO, arrotino.sottoconto());
    
    saldo.normalize();
    saldo.swap_section();
    curr.put(SLD_FLAGSALINI, saldo.sezione());
    curr.put(SLD_SALDO, saldo.valore());
    saldi.write();
  }
}

bool TApertura_saldi_euro::has_movs() const
{
  TEuroisamfile s(LF_MOV, TRUE);
  int err = s.first();
  return err == NOERR;
}

void TApertura_saldi_euro::main_loop()
{
  goto_lire();
  if (set_firm())
  {
    TEuro90_mask m;
  
    TFilename lit, eur;
    get_aree_dati(lit, eur);
    m.set(F11_DATI, lit);
    m.set(F11_DATIE, eur);
    m.on_firm_change();
    if (m.run() == K_ENTER)
    {
      const bool was_full = has_movs();
    
      TDate adozione = m.get(F11_ADOZIONE);
      TBill arrotino;
      arrotino.get(m, F11_DIFF_G, F11_DIFF_C, F11_DIFF_S);
      convert_saldi(adozione, arrotino);
      
      if (was_full && yesno_box("Esistono movimenti contabili:\nSi desidera ricalcolare i saldi?"))
      { 
        goto_euro();
        TExternal_app app("cg4 -0");
        app.run();
        goto_lire();
      }
    }
  }
}
  
int baeur09(int argc, char* argv[])
{  
  TApertura_saldi_euro ase;
  ase.run(argc, argv, "Ricalcolo saldi Lire/Euro");
  
  return 0;
}