#include <applicat.h>
#include <automask.h>
#include <execp.h>
#include <relation.h>
#include <tabutil.h>

#include "baeur.h"
#include "baeur40.h"
#include "../ve/velib.h"

#include <doc.h>
#include <rdoc.h>

class TEuro40_mask;

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

class TEuro04_app : public TEuro_app
{             
protected:
  virtual bool create();
  virtual void main_loop();
  void  copy_docs(TEuro40_mask & mask);

public:
};

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

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

class TEuro40_mask : public TAutomask
{ 
public:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
  TEuro40_mask() : TAutomask("baeur40") { }
  void load_mask();
};

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

void TEuro40_mask::load_mask()
{
  TTable num("%NUM");
  TSheet_field & s = (TSheet_field &) field(F40_DOCSHEET);
                            
  for (num.first(); num.good(); num.next())
  {
    TToken_string & row = s.row(-1);
    row.add("");
    row.add("");
    row.add(num.get("CODTAB"));
    row.add("");
    row.add("");   
    row.add("");
    row.add(num.get("S0")); 
    s.check_row(s.items() - 1);
  }

  TSheet_field & t = (TSheet_field &) field(F40_TIPISHEET);
  TTable tip("%TRI");
                            
  for (tip.first(); tip.good(); tip.next())
  {               
    const TString16 tipo(tip.get("CODTAB"));
    if (*tipo >= 'A')
    {
      TToken_string & row = t.row(-1);
    
      row.add("");
      row.add(tipo);
      row.add(tip.get("S0"));
    }
  }
}

///////////////////////////////////////////////////////////
// Main 
///////////////////////////////////////////////////////////
 
class TNum_data : public TObject
{     
  public:
  int _anno;
  int _da_stato;
  int _a_stato;
  bool _repeat;
  TAssoc_array _extra_tipi_riga;
} ;

bool TEuro04_app::create()
{
  goto_lire();

  if (!set_firm())
    return FALSE;
  const long ditta = get_firm();  
  if (!dbf_exists(LF_DOC, TRUE))
    return error_box("Non esistono gli archivi della ditta %ld nell'area in Euro", ditta);

  TEuro_app::create();
  open_files(LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART, 
             LF_TAB, LF_TABCOM, LF_CLIFO, LF_CFVEN, LF_INDSP, LF_OCCAS, LF_PCON,
             LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, 0);
             
  return TRUE;
}

static bool doc_handler(TRectype& rec, void* jolly)
{                                                              
  TAssoc_array * num = (TAssoc_array *) jolly;
  TNum_data * data = (TNum_data *) num->objptr(rec.get(DOC_CODNUM));
           
  if (data != NULL)
  {
    if (data->_anno <= rec.get_int(DOC_ANNO))
    {             
      const int stato = rec.get_int(DOC_STATO);
      if (data->_da_stato <= stato && (data->_a_stato == 0 || stato <= data->_a_stato)) 
      {                            
        const TString tipodoc(rec.get(DOC_TIPODOC));
        TTipo_documento t(cache().get("%TIP", tipodoc));
        
        if ((!t.is_ordine() || riporta_ordinato()) && !data->_repeat)
          rec.put(DOC_STATO, (char) t.stato_bloccato());

        const TString16 val = rec.get("CODVAL");
        
        if (is_firm_value(val))
        {
          rec.zero(DOC_CODVAL);
          rec.zero(DOC_CAMBIO);
          rec.put(DOC_CONTROEURO, "X");
          real imp = rec.get_real(DOC_IMPPAGATO) / EURO;
          
          imp.round(2);
          rec.put(DOC_IMPPAGATO, imp);
        }
        else
          if (is_euro_value(val))
          {
            rec.zero(DOC_CODVAL);
            rec.zero(DOC_CAMBIO);
            rec.zero(DOC_CONTROEURO);
          }
          else
            if (!rec.get_bool(DOC_CONTROEURO))
            {
              real contro_change = EURO / rec.get_real(DOC_CAMBIO);
                                                                        
              contro_change.round(6);
              rec.put(DOC_CAMBIO, contro_change);
              rec.put(DOC_CONTROEURO, "X");
            }
                            
        const TString16 key(rec.get(DOC_MOVMAG));
        if (key.not_empty())
        {
          const TRectype & mov =  cache().get(LF_MOVMAG, key);
          if (mov.empty())
            rec.zero(DOC_MOVMAG);  
        }
        return TRUE;                                                              
        
      }
    }
  }
  return FALSE;  
}

static bool rdoc_handler(TRectype& rec, void* jolly)
{           
  TString key;
  key << rec.get(RDOC_PROVV);
  key << "|" << rec.get(RDOC_ANNO);
  key << "|" << rec.get(RDOC_CODNUM);
  key << "|" << rec.get(RDOC_NDOC);
  TRectype doc((TRectype &) cache().get(LF_DOC, key));
  bool ok = doc_handler(doc, jolly);                     
  
  if (doc.get(DOC_MOVMAG).empty())
    rec.zero(RDOC_MOVMAG);
  if (doc.get(DOC_CODVAL).empty() && doc.get_bool(DOC_CONTROEURO))
  {  
    const TString16 tipo(rec.get(RDOC_TIPORIGA));
    
    
    if (tipo != "04" && tipo != "05" && tipo != "08")
    {
      real prezzo = rec.get_real(RDOC_PREZZO) / EURO;
      bool is_prezzo = tipo != "07";
      bool convert = TRUE;
      const int tipoint = atoi(tipo);
      if (*tipo >= 'A')
      {                               
        TAssoc_array * num = (TAssoc_array *) jolly;
        TNum_data * data = (TNum_data *) num->objptr(rec.get(RDOC_CODNUM));
        TString * tpc = (TString *)data->_extra_tipi_riga.objptr(tipo);
        if (tpc != NULL)
        {               
          if (*tpc == "N")
            convert = FALSE;
          else
            is_prezzo = *tpc == " ";
        }
      }
      else
        if (tipo == "02" || tipo == "03" || tipo == "06")
        {
          TString cod(rec.get(RDOC_CODART));
          TSpesa_prest s(cod, tipo == "06" ? 'P' : 'S');  
          is_prezzo = s.tipo() == 'Q';
          convert = s.tipo() != 'P';
        }   
      if (convert)
      {
        prezzo.round(TCurrency::get_euro_dec(is_prezzo));
        rec.put(RDOC_PREZZO, prezzo);
      }
    }

    real impfisso = rec.get_real(RDOC_IMPFISSO) / EURO;

    impfisso.round(TCurrency::get_euro_dec());
    rec.put(RDOC_IMPFISSO, impfisso);
  }
  
  return ok;            
}

void TEuro04_app::copy_docs(TEuro40_mask & mask)
{
  TSheet_field & t = (TSheet_field &) mask.field(F40_TIPISHEET);
  int items = t.items();
  TAssoc_array extra_tipi;
  
  for (int i = 0; i < items; i++)
  { 
    TToken_string & row = t.row(i);
    TString val(row.get(0));
    extra_tipi.add(row.get(), val);
  }
  
  TSheet_field & s = (TSheet_field &) mask.field(F40_DOCSHEET);
  items = s.items();
  TAssoc_array docs2convert;
                            
  for (i = 0; i < items; i++)
  {
    TToken_string & row = s.row(i);
    TString selected(row.get(0));
    
    if (selected == "X")
    {
      TNum_data * d = new TNum_data;
      
      d->_anno = row.get_int();      
      TString16 codnum(row.get());
      d->_da_stato = row.get_int();      
      d->_a_stato = row.get_int();      
      d->_repeat =  *row.get() == 'X';      
      d->_extra_tipi_riga = extra_tipi;
      docs2convert.add(codnum, d);
    } 
  }
  convert_file(LF_DOC, NULL, NULL, NULL, doc_handler, &docs2convert);  
  convert_file(LF_RIGHEDOC, NULL, NULL, NULL, rdoc_handler, &docs2convert);  
}

void TEuro04_app::main_loop()
{   
  TEuro40_mask msk;
  TDate apertura(1,1,2002);
  TDate chiusura(31,12,2001);
  const long firm = get_firm();
  TFilename dati, datie;
  get_aree_dati(dati, datie);
  msk.set(F40_DATI, dati);
  msk.set(F40_DATIE, datie);
  
  TString8 ditta; 
  ditta.format("%05ldA", firm);
  
  TFilename inie = datie;
  inie.add(ditta);
  inie.add("prassid.ini");
  
  bool adotta = FALSE, inizio = FALSE;
  if (inie.exist())
    adotta = data_adozione_euro(firm, apertura, inizio);
  
  msk.load_mask();
  if (msk.run() == K_ENTER)
  {
    copy_docs(msk);
    TExternal_app app("baeur -6 D");
    
    app.run();
  }

}

int baeur04(int argc, char* argv[])
{  
  TEuro04_app ma;
  ma.run(argc, argv, "Conversione documenti");
  
  return 0;
}