#include <applicat.h>
#include <mask.h>
#include <isam.h>
#include <relation.h>
#include <sheet.h>
#include <utility.h>
#include <urldefid.h>

#include "ba4600.h"

///////////////////////////////////////////////////////////
// TSoci_sheet
///////////////////////////////////////////////////////////

const char* const PHYSICAL_HEAD = "Codice|Cognome@30|Nome@20";
const char* const JURASSIC_HEAD = "Codice|Ragione sociale@50";

class TSoci_sheet : public TArray_sheet
{
  bool _physical;

protected:
  const char* lastcode();

public:
  TSoci_sheet(bool);
  void add_socio(const TString& codice, const TString& ragione, int elem = -1);
};

TSoci_sheet::TSoci_sheet(bool fis)
: TArray_sheet(-1,-1, 0, 0, "Soci", fis ? PHYSICAL_HEAD : JURASSIC_HEAD),
  _physical(fis)
{}

const char* TSoci_sheet::lastcode()
{
  if (items() < 1) return "";
  return data(items()-1).get(0);
}

void TSoci_sheet::add_socio(const TString& codice,
                            const TString& ragione,
                            int elem)
{
  if (elem == -1 && codice == lastcode()) return;

  TToken_string t(60);

  t.add(codice);
  if (_physical)
  {
    t.add(ragione.left(30));
    t.add(ragione.mid(30));
  } else t.add(ragione);

  if (elem < 0) add(t);
  else row(elem) = t;
}

///////////////////////////////////////////////////////////
// TQuery_socio
///////////////////////////////////////////////////////////

class TQuery_socio
{
  TString16 _tipo;        // tipo = F | G
  TString16 _attprec;     // {A}ttuale / {P}recedente
  TString16 _carica;      // codice carica
  TString16 _qualifica;   // richiesta qualifica
  TString16 _q740;        // quadro 740
  TString16 _q750;        // quadro 750

public:
  TQuery_socio(const TMask* mask);

  const TString& tipo() const { return _tipo; }
  int test(const TRectype& rec) const;
};

TQuery_socio::TQuery_socio(const TMask* mask)
{
  _tipo      = mask->get(LST_SC1_TIPOASOC);
  _attprec   = mask->get(FLD_SC1_ANNO);
  _carica    = mask->get(FLD_SC1_CODCAR);
  _qualifica = mask->get(LST_SC1_RICQUAL);
  _q740      = mask->get(LST_SC2_Q740);
  _q750      = mask->get(LST_SC2_QUATTPREV);
}

int TQuery_socio::test(const TRectype& r) const
{
  if (_tipo != r.get("TIPOASOC")) return 1;
  if (_attprec.not_empty()&& _attprec != r.get("ATTPREC")) return 2;
  if (_carica.not_empty() && _carica != r.get("CODCAR")) return 3;
  if (_qualifica.not_empty() && _qualifica != r.get("RICQUAL")) return 4;
  if (_q740.not_empty() && _q740 != r.get("Q740")) return 5;
  if (_q750.not_empty() && _q750 != r.get("QUATTPREV")) return 6;
  return 0;
}

///////////////////////////////////////////////////////////
// TQuery_application
///////////////////////////////////////////////////////////

class TQuery_application : public TApplication
{

  TRelation* _soci;
  TLocalisamfile* _anag;
  TLocalisamfile* _ditte;
  TMask* _mask;

  void create_files();
  void create_masks();
  void destroy_masks();
  void destroy_files();

protected:
  virtual bool create();
  virtual bool destroy();
  virtual bool menu(MENU_TAG m);

  bool do_query();

public:
  TQuery_application();
};


TQuery_application::TQuery_application() : _mask(NULL)
{}

void TQuery_application::create_files()
{
  _soci = new TRelation(LF_SOCI); _soci->lfile().setkey(3);
  _anag = new TLocalisamfile(LF_ANAG); 
  _ditte = new TLocalisamfile(LF_NDITTE);
}

void TQuery_application::destroy_files()
{
  delete _ditte;
  delete _anag;
  delete _soci;
}

void TQuery_application::create_masks()
{
  _mask = new TMask("ba5000");
}

void TQuery_application::destroy_masks()
{
  delete _mask;
}

bool TQuery_application::create()
{
  TApplication::create();

  create_files();
  create_masks();
  dispatch_e_menu(MENU_ITEM(1));

  return TRUE;
}

bool TQuery_application::destroy()
{
  destroy_masks();
  destroy_files();

  return TApplication::destroy();
}


bool TQuery_application::menu(MENU_TAG m)
{
  while (do_query());
  return FALSE;
}

const char* head(const TRectype& r, const char* name,
                 const char* title)
{
  if (title == NULL) title = name;

  if (r.exist(name))
  {
    TString h(r.length(name));
    h.spaces();
    h.overwrite(title, 0);
    strcpy(__tmp_string, h);
  }
  else strcpy(__tmp_string, title);

  return __tmp_string;
}

bool TQuery_application::do_query()
{
  if (_mask->run() != K_F9) return FALSE;

  TQuery_socio query(_mask);
  TSoci_sheet s(query.tipo() == "F");                       // Create sheet

  TRectype& soci = _soci->curr();
  TRectype& anag = _anag->curr();
  TRectype& ditte = _ditte->curr();

  soci.zero();
  _mask->autosave(_soci);
  for (_soci->read(_isgteq); !_soci->eof(); _soci->next())  // Fill sheet
  {
    if (query.test(soci) == 0)
      s.add_socio(soci.get("CODANAGRSO"), "");
  }

  TString ragsoc(80),
  cur_codice(10);
  for (int i = 0; i < s.items(); i++)
  {

    TToken_string& t = (TToken_string&) s.row(i);

    t.restart();
    cur_codice = t.get();
    anag.zero();
    anag.put("TIPOA", query.tipo());
    anag.put("CODANAGR", cur_codice);
    if (_anag->read() != NOERR) ragsoc = "Anagrafica assente";
    else ragsoc = _anag->curr().get("RAGSOC");
    s.add_socio(cur_codice, ragsoc, i);
  }

  if (s.items() == 0)
  {
    warning_box("Nessuna corrispondenza");
    return TRUE;
  }

  while(s.run() == K_ENTER)
  {
    TToken_string& r = s.row();
    r.restart();
    TString codice(r.get());
    TString nome(r.get());

    TToken_string h(128);
    h.add("A/P ");
    h.add(head(ditte, "CODDITTA", "Codice"));
    h.add(head(ditte, "RAGSOC", "Ragione sociale"));
    h.add("Carica|Qualifica|740|750");
    h.add(head(soci, "PERCQUAZ", "% Quote"));
    TArray_sheet d(-1,-1, 0, 0, nome, h);

    soci.zero();
    soci.put("TIPOASOC", query.tipo());
    soci.put("CODANAGRSO", codice);

    TToken_string row(128);
    for (_soci->read(_isgteq); !_soci->eof(); _soci->next())
    {
      if (codice != soci.get("CODANAGRSO")) break;
      if (query.test(soci) != 0) continue;

      row = soci.get("ATTPREC");
      ditte.zero();
      row.add(soci.get("CODDITTA"));
      ditte.put("CODDITTA", row.get(1));
      if (_ditte->read() != NOERR)
        row.add("Ditta assente");
      else
        row.add(ditte.get("RAGSOC"));
      row.add(soci.get("CODCAR"));
      row.add(soci.get("RICQUAL"));
      row.add(soci.get("Q740"));
      row.add(soci.get("QUATTPREV"));
      row.add(soci.get("PERCQUAZ"));

      d.add(row);
    }
    d.run();
  }
  
  return TRUE;
}


int main(int argc,char** argv)
{
  TQuery_application qa;
  qa.run(argc, argv, "Ricerca Soci");
  return TRUE;
}
