#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <progind.h>
#include <recarray.h>
#include <relation.h>

#include "ce2100a.h"
#include "ce2101.h"
#include "celib.h"

#include "cespi.h"

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

public:
  void recalc_spese();
  TCalcamm_mask() : TAutomask("ce2100a") { }
};

void TCalcamm_mask::recalc_spese()
{ 
  TCurrency r0; get_currency(F_SPMS_MATGEN, r0);
  TCurrency r1; get_currency(F_SPMS_AUTOTRAS, r1);
  TCurrency r2; get_currency(F_MSPD_MATGEN, r2);
  TCurrency r3; get_currency(F_MSPD_AUTOTRAS, r3);
  TCurrency r4 = r0 > r2 ? r0-r2 : ZERO; 
  TCurrency r5 = r1 > r3 ? r1-r3 : ZERO;
  set(F_SPME_MATGEN, r4);
  set(F_SPME_AUTOTRAS, r5);
}

bool TCalcamm_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{ 
  switch (o.dlg())
  {              
  case F_ESERCIZIO:
  case F_GRUPPO:
  case F_SPECIE:
    if (e == fe_init || e == fe_modify)
    {
      const TString& esercizio = get(F_ESERCIZIO);
      const TString& gruppo = get(F_GRUPPO);
      const TString& specie = get(F_SPECIE);
      TString16 key; key << esercizio << gruppo << specie;
      TRelation ccb("CCB");
      ccb.curr().put("CODTAB", key);
      if (ccb.read() == NOERR)
        autoload(ccb);
      recalc_spese();
    }
    break;
  case F_SPMS_MATGEN:
  case F_SPMS_AUTOTRAS:
    if (e == fe_modify)
      recalc_spese();
    break;
  default: break;
  }
  return TRUE;
}

class TCalcamm : public TSkeleton_application
{ 
  TCalcamm_mask* _mask;

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

public:   
  bool calcola_ammortamenti();
};  

bool TCalcamm::calcola_ammortamenti()
{ 
  const TString& esercizio = _mask->get(F_ESERCIZIO);
  const TString& gruppo = _mask->get(F_GRUPPO);
  const TString& specie = _mask->get(F_SPECIE);
  const TDate data_limite(_mask->get(F_FINE_ES));

  TRectype filter(LF_CESPI);
  filter.put(CESPI_CODCGRA, gruppo);
  if (!specie.blank())
    filter.put(CESPI_CODSPA, specie);
  
  TRelation ccb("CCB");
  TRectype& ccq = ccb.curr();
  TString16 key;
  key << esercizio << gruppo << specie;
  ccq.put("CODTAB", key);
  if (ccb.read() == NOERR)
  {
    // Salva importi spesi per manutenzione
    ccq.put("R0", _mask->get(F_SPMS_MATGEN));
    ccq.put("R1", _mask->get(F_SPMS_AUTOTRAS));
  
    // Azzera monte spese di manutenzione
    ccq.zero("R2"); 
    ccq.zero("R3");
    ccq.put("D0", TDate(TODAY));
    ccb.rewrite();
  }

  TRelation cespiti(LF_CESPI);
  TCursor cur(&cespiti, "", 2, &filter, &filter);
  
  const long items = cur.items();
  cur.freeze();
  
  TString msg; 
  msg << TR("Calcolo ammortamenti di ") << items << TR(" cespiti...");
  TProgind pi(items, msg, TRUE, TRUE);
  
  for (cur = 0L; cur.pos() < items; ++cur)
  {
    pi.addstatus(1);
    if (pi.iscancelled())
      break;
      
    TCespite cespite(cur.curr());  
    for (int tipo_sit = 1; tipo_sit <= 3; tipo_sit++)
      cespite.calc_amm(tipo_sit, data_limite, TRUE);
  }
  
  // Aggiorna maschera
  ccq.put("CODTAB", key);
  if (ccb.read() == NOERR)
    _mask->autoload(ccb);

  return TRUE;
}

bool TCalcamm::create()
{
  open_files(LF_TABCOM, LF_TAB, LF_CESPI, LF_SALCE, LF_AMMCE, LF_MOVCE, LF_MOVAM, LF_AMMMV, 0);
  _mask = new TCalcamm_mask;
  return TSkeleton_application::create();
}

bool TCalcamm::destroy()
{
  delete _mask;
  return TRUE;
}

void TCalcamm::main_loop()
{
  const bool batch = argc() > 2 && *argv(2) == 'A';
  KEY k = K_ENTER;
  while (k == K_ENTER)
  {                   
    TDitta_cespiti& dc = ditta_cespiti();
    dc.init_mask(*_mask);
    _mask->recalc_spese();
    if (!batch)
      k = _mask->run();
    if (k == K_ENTER)
    {                                             
      const int ese = _mask->get_int(F_ESERCIZIO);
      const int gru = _mask->get_int(F_GRUPPO);
      const TString& spe = _mask->get(F_SPECIE);
      dc.set_attivita(ese, gru, spe);   
      
      bool ok = TRUE;
      if (dc.bollato_stampato())
        ok = error_box(TR("Non � possibile effettuare il calcolo degli ammortamenti:\n"
                       "il bollato dell'attivit� corrente � gi� stato stampato"));
      if (ok)
        calcola_ammortamenti();
    }
    if (batch)
      break;
  }
}

int ce2100(int argc, char* argv[])
{          
  TCalcamm a;
  a.run(argc, argv, TR("Calcolo ammortamenti"));
  return 0;
}