#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <recarray.h>
#include <recset.h>
#include <relation.h>
#include <reputils.h>

#include <clifo.h>
#include "cfban.h"

///////////////////////////////////////////////////////////
// TIBAN_mask
///////////////////////////////////////////////////////////

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

public:
  TIBAN_mask() : TAutomask("cg1310") { }
};

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

///////////////////////////////////////////////////////////
// TIBAN_app
///////////////////////////////////////////////////////////

class TIBAN_app : public TSkeleton_application
{
protected:
  void update(TRecord_array& a, TLog_report& log) const;
  void elabora() const;

public:
  virtual void main_loop();
};

void TIBAN_app::update(TRecord_array& a, TLog_report& log) const
{
  const TRectype& row = a.row(a.last_row());

  TString msg;
  msg << TR("Aggiornamento banca del ")
      << row.get(CFBAN_TIPOCF) << '/' << row.get_long(CFBAN_CODCF)
      << " : " << row.get(CFBAN_ABI) << '/' << row.get(CFBAN_CAB)
      << "  " << row.get(CFBAN_IBAN);

  log.log(0, msg);

  const int err = a.rewrite();
  if (err != NOERR)
  {
    msg.format(FR("Errore %d durante l'aggiornamento del file delle banche"), err);
    log.log(2, msg);
  }
}

void TIBAN_app::elabora() const
{
  TLog_report log;

  TISAM_recordset clifo("USE CLIFO");
  TProgind pi(clifo.items(), clifo.cursor()->file(0).description());
  TRectype& curr = clifo.cursor()->curr();
  for (bool ok = clifo.move_first(); ok; ok = clifo.move_next())
  {
    if (!pi.addstatus(1))
      break;
    const TString80 iban = curr.get(CLI_IBAN);
    const TString8 abi = curr.get(CLI_CODABI);
    const TString8 cab = curr.get(CLI_CODCAB);
    if (iban.len() > 15 || atoi(cab) >= 1000)
    {
      TString16 key; key.format("%c|%ld|V", curr.get_char(CLI_TIPOCF), curr.get_long(CLI_CODCF));
      TRecord_array cfban(key, LF_CFBAN);
      if (iban.len() > 15)
      {
        int r = -1;
        for (r = cfban.last_row(); r > 0; r = cfban.pred_row(r))
        {
          const TRectype& row = cfban.row(r);
          if (row.get(CFBAN_IBAN) == iban)
            break;
        }
        if (r <= 0)
        {
          TRectype& row = cfban.row(-1, true);
          row.put(CFBAN_IBAN, iban);
          if (iban.starts_with("IT"))
          {
            row.put(CFBAN_ABI, iban.mid(5, 5));
            row.put(CFBAN_CAB, iban.mid(10, 5));
            row.put(CFBAN_NUMCC, iban.mid(15));
          }
          update(cfban, log);
        }
      }
      else
      {
        int r = -1;
        for (r = cfban.last_row(); r > 0; r = cfban.pred_row(r))
        {
          const TRectype& row = cfban.row(r);
          if (row.get(CFBAN_ABI) == abi && row.get(CFBAN_CAB) == cab)
            break;
        }
        if (r <= 0)
        {
          TRectype& row = cfban.row(-1, true);
          row.put(CFBAN_ABI, abi);
          row.put(CFBAN_CAB, cab);
          row.put(CFBAN_NUMCC, curr.get(CLI_NUMCC));
          update(cfban, log);
        }
      }
    }
  }

  log.preview();
}

void TIBAN_app::main_loop()
{
  TIBAN_mask m;
  if (m.run() == K_ENTER)
    elabora();
}

void agg_iban(int argc, char* argv[])
{
  TIBAN_app a;
  a.run(argc, argv, TR("Allineamento IBAN"));
}