#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <recset.h>
#include <tabutil.h>

#include "pd6411100a.h"
#include "../ve/velib.h"

///////////////////////////////////////////////////////////
// TListini_haba_msk
///////////////////////////////////////////////////////////

class TListini_haba_msk: public TAutomask
{
protected:
  void riempi_sheet();
  void cambio(const short primo, const short secondo);
  void aggiungi_riga();
  void registra();
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
	TListini_haba_msk();
};

void TListini_haba_msk::riempi_sheet()
{
  const TString8 gruppo = get(F_GRUPPO);
  const TString4 mese = get(F_MESE);

  TSheet_field& sheet = sfield(F_SHEET);
  sheet.destroy();

  if(gruppo.empty() || mese.empty())
  {
    sheet.force_update();
    return;
  }

  TString16 codtab;
  codtab << gruppo << mese;
  codtab.trim();

  TString query;
  query << "USE LGM\n"
        << "FROM CODTAB=\"" << codtab << "\"\n"
        << "TO CODTAB=\""   << codtab << "\"";

  TISAM_recordset listini(query);

  for(bool ok = listini.move_first(); ok; ok = listini.move_next())
  {
    const TRectype& lis = listini.cursor()->curr();
    const TString80 codtab = lis.get("CODTAB");
    const real      impeu  = lis.get("R0");
    const real      impfr  = lis.get("R1");

    TToken_string& row = sheet.row(-1);
    row.add(codtab.left(3),  sheet.cid2index(S_GRUPPO));
    row.add(codtab.mid(3,2), sheet.cid2index(S_MESE));
    row.add(codtab.mid(5),   sheet.cid2index(S_SPESSORE));
    row.add(impeu.string(),  sheet.cid2index(S_IMPEURO));
    row.add(impfr.string(),  sheet.cid2index(S_IMPFRANCO));
  }
  sheet.force_update();

  if(get(F_CAMBIO).empty())
  {
    TToken_string& row = sheet.row(0);
    real euro(row.get(sheet.cid2index(S_IMPEURO)));
    real franco(row.get(sheet.cid2index(S_IMPFRANCO)));

    real cambio = franco / euro;
    set(F_CAMBIO, cambio);
  }
}

void TListini_haba_msk::cambio(const short primo, const short secondo)
{
  TSheet_field& sheet = sfield(F_SHEET);
  TMask& msk = sheet.mask();
  const real cambio = msk.get_real(F_CAMBIO);

  TMask& rmsk = sheet.sheet_mask();

  if(rmsk.field(secondo).empty() || cambio.is_zero())
    return;

  TToken_string& row = sheet.row(sheet.selected());
  real impval = rmsk.get_real(secondo);

  if(secondo == S_IMPEURO)
    impval *= cambio;
  else
    impval /= cambio;

  rmsk.set(primo, impval);
}

void TListini_haba_msk::aggiungi_riga()
{
  const TString4 gruppo = get(F_GRUPPO);
  const TString4 mese   = get(F_MESE);

  if(gruppo.empty() || mese.empty())
    return;

  TSheet_field& sheet = sfield(F_SHEET);
  TToken_string& row = sheet.row(-1);
  row.add(gruppo, sheet.cid2index(S_GRUPPO));
  row.add(mese,   sheet.cid2index(S_MESE));
  sheet.force_update();
}

void TListini_haba_msk::registra()
{
  TTable listini("LGM");
  TSheet_field& sheet = sfield(F_SHEET);

  FOR_EACH_SHEET_ROW(sheet, r, riga)
  {
    TToken_string& row = *(TToken_string*)riga;
    TString4 spessore; spessore.format("%02d", row.get_int(sheet.cid2index(S_SPESSORE)));
    TString80 codtab;
    codtab << row.get(sheet.cid2index(S_GRUPPO)) << row.get(sheet.cid2index(S_MESE)) << spessore;
    const real impeuro(row.get(sheet.cid2index(S_IMPEURO)));
    const real impfranco(row.get(sheet.cid2index(S_IMPFRANCO)));

    if(impeuro == ZERO && impfranco == ZERO)
    {
      listini.put("CODTAB", codtab);
      listini.remove();
    }
    else
    {
      listini.put("CODTAB", codtab);
      listini.put("R0", impeuro);
      listini.put("R1", impfranco);      
      listini.rewrite_write();
    }    
  }
  riempi_sheet();
}

bool TListini_haba_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{ 
  switch(o.dlg())
  {
  case DLG_CANCEL:
    if(e == fe_button && jolly == 0)
    {
      reset(F_GRUPPO);
      reset(F_MESE);
      reset(F_CAMBIO);
      sfield(F_SHEET).destroy();
      return false;
    }
    break;
  case DLG_SAVEREC:
    if(e == fe_button)
      registra();
    break;
  case DLG_DELREC:
    if(e == fe_button && jolly == 1)
    {
      TMask& msk = sfield(F_SHEET).sheet_mask();
      msk.reset(S_IMPEURO);
      msk.reset(S_IMPFRANCO);
      return false;
    }
    break;
  case F_GRUPPO:
  case F_MESE:
    if(e == fe_modify)
      riempi_sheet();
    break;
  case F_SHEET:
    if(e == se_query_add)
    {
      aggiungi_riga();
      return false;
    }
    if(e == se_query_del)
    {
      TSheet_field& sheet = (TSheet_field&)o;
      TToken_string& row = sheet.row(jolly);
      row.add("", sheet.cid2index(S_IMPEURO));
      row.add("", sheet.cid2index(S_IMPFRANCO));
      sheet.force_update(jolly);

      TButton_field& button = (TButton_field&)sheet.sheet_mask().field(DLG_DELREC);

      return on_field_event(button, fe_button, 1);
    }
    break;
  case S_SPESSORE:
    if(e == fe_modify)
    {
      TSheet_field& sheet = sfield(F_SHEET);
      const int rsel = sheet.selected();
      const int spessore = o.get_long();

      FOR_EACH_SHEET_ROW(sheet, r, riga)
      {
        if(r == rsel)
          continue;
        
        TToken_string& row = *(TToken_string*)riga;
        if(row.get_int(sheet.cid2index(S_SPESSORE)) == spessore)
        {
          TString msg;
          msg << "Attenzione: esiste gi� una riga con spessore " << spessore;
          warning_box(msg);

          sheet.select(rsel);
          TMask& rmsk = sheet.sheet_mask();
          rmsk.set(S_SPESSORE, 0L);
          break;
        }
      }
    }
    break;
  case S_IMPEURO:
  case S_IMPFRANCO:
    if(e == fe_modify || e == fe_close)
    {      
      const short primo   = o.dlg();
      const short secondo = S_IMPEURO + S_IMPFRANCO - o.dlg();

      TMask& rmsk = o.mask();

      if(rmsk.field(primo).empty() && !rmsk.field(secondo).empty())
        cambio(primo, secondo);

      if(!rmsk.field(primo).empty() && rmsk.field(secondo).empty())
        cambio(secondo, primo);
    }
    break;  
  default:  break;
  }
  return true;
}

TListini_haba_msk::TListini_haba_msk() : TAutomask("pd6411100a")
{
}

///////////////////////////////////////////////////////////
// TListini_haba_app
///////////////////////////////////////////////////////////

class TListini_haba_app: public TSkeleton_application
{
protected:
  virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "cg";}

  virtual void main_loop();
  
  void elabora();
};

void TListini_haba_app::elabora()
{
}

void TListini_haba_app::main_loop()
{
  TListini_haba_msk m;
	bool running = true;

  while(m.run() == K_ENTER)
	{
		elabora();
	}
}

int pd6411100(int argc, char* argv[])
{  
  TListini_haba_app app;
  app.run(argc, argv, TR("Listini Haba piastre"));
  return 0;
}