#include <applicat.h>
#include <automask.h>
#include <printer.h>
#include <recarray.h>

#include "celib.h"
#include "ce3400.h" 
#include "ce3500a.h" 

#include "../cg/cglib01.h" 

#include "ammce.h" 
#include "cespi.h" 
#include "salce.h" 

///////////////////////////////////////////////////////////
// Main Form
///////////////////////////////////////////////////////////

class TLC_form : public TCespi_list_form
{ 
  TCursor* _cur;
  int _tiposit, _order, _suborder;
  TString _str;  // Jolly string

protected:
  virtual TRelation* relation() const { return _cur->relation(); }
  virtual TCursor* cursor() const { return _cur; }
  virtual bool validate(TForm_item& fld, TToken_string& val);

public:
  void set_cursor(TCursor& cur) { _cur = &cur; }
  void set_testata(const TMask& m, const TString& codtab);   
  
  TPrint_section& cespite() { return section('B', odd_page); }
  TPrint_section& totcat()  { return section('B', even_page); }
  TPrint_section& totgen()  { return section('B', last_page); }
  
  const TString& decode_group(const char* cod, int sit=0);

  TLC_form(bool extended) : TCespi_list_form(extended ? "ce3500b" : "ce3500a") { }
};

const TString& TLC_form::decode_group(const char* codtab, int mode)
{
  const int order = mode > 0 ? mode : _order;
  _str = "@b";
  if (mode > 0) // Riga
    _str << "@r" << (order==1 ? TR("Cat.") : TR("Imp.")) << codtab << ' ';
  else          // Testata
    _str << (order==1 ? TR("Categoria") : TR("Impianto")) << "@r " << codtab << ' ';
    
  if (order == 1)
  {
    const TRectype& cat = ditta_cespiti().categoria(0, NULL, atoi(codtab));
    _str << cat.get("S0");
  }
  else   
    _str << cache().get("CIM", codtab, "S0");
  return _str;
}

void TLC_form::set_testata(const TMask& m, const TString& codtab)
{ 
  TCespi_list_form::set_testata(m);

  _tiposit = m.get_int(F_SITUAZIONE);
  _order = m.get_int(F_ORDINAMENTO);
  
  TPrint_section& header = section('H', odd_page);
  header.find_field(F_CODTAB).set(decode_group(codtab));
}

bool TLC_form::validate(TForm_item& fld, TToken_string& val)
{
  const TRectype& cespi = relation()->curr();
  const char* cmd = val.get(0);
  if (xvt_str_compare_ignoring_case(cmd, "_INVCODTAB") == 0)
  {                 
    // Se la stampa � ordinata per categoria allora stampo l'impianto e viceversa
    const TString16 codtab = cespi.get(_order == 1 ? CESPI_CODIMP : CESPI_CODCAT);
    if (codtab.not_empty())
      fld.set(decode_group(codtab, 3-_order));
    else
      fld.set("");
    return TRUE;
  }
  if (xvt_str_compare_ignoring_case(cmd, "_USOPROM") == 0)
  {           
    bool yes = cespi.get_bool(CESPI_VEIDIP);
    if (!yes)
      yes = cespi.get_int(CESPI_USOPROM) > 1;
    fld.set(yes ? TR("Si") : TR("No"));
    return TRUE;
  }
  if (xvt_str_compare_ignoring_case(cmd, "_TPSPEMAN") == 0)
  {
    switch(cespi.get_int(CESPI_TPSPEMAN))
    {                           
    case  2: fld.set(TR("Incluso 5%")); break;
    case  3: fld.set(TR("Incluso 24%")); break;
    case  4: fld.set(TR("Art.14 L.449/97")); break;
    default: fld.set(TR("Escluso")); break;
    }
    return TRUE;
  }
  if (xvt_str_compare_ignoring_case(cmd, "_RIVGEN") == 0)
  {
    const TRectype& salce = relation()->curr(LF_SALCE);
    fld.set(salce.get(_tiposit == 2 ? SALCE_RIVGC : SALCE_RIVGF)); 
    return true;
  }
	if (xvt_str_compare_ignoring_case(cmd, "_VNONAMM") == 0)
  {
		const TRectype& salce = relation()->curr(LF_SALCE);
		real vnonamm = salce.get_real(_tiposit == 2 ? SALCE_VNONAMMC : SALCE_VNONAMM);
		vnonamm += salce.get_real(SALCE_VNONAMM06);
    fld.set(vnonamm.string());
		return true;
	}
  return TCespi_list_form::validate(fld, val);
}

///////////////////////////////////////////////////////////
// Main Mask
///////////////////////////////////////////////////////////

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

public:
  TLC_mask() : TAutomask("ce3500a") { }
};

bool TLC_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
{ 
  bool ok = TRUE;
  switch (f.dlg())
  {
  case F_FROM_CAT:
  case F_D_FROM_CAT:
  case F_TO_CAT:
  case F_D_TO_CAT:
    {
      TDitta_cespiti& dc = ditta_cespiti();
      ok = dc.on_category_event(f, e, jolly);
    }
    break;
  default: break;
  }
  return ok;
}

///////////////////////////////////////////////////////////
// Main Application
///////////////////////////////////////////////////////////

class TLC_app : public TSkeleton_application
{
  int _tipo_sit, _order, _suborder; 
  TLC_form* _form;
  
protected:
  virtual void main_loop();
  
public:
  void print_cespite();
  void print_total(int level, const char* prompt);
};

void TLC_app::print_cespite()
{
  TPrint_section& ces = _form->cespite();
  _form->print_section(ces);
}

void TLC_app::print_total(int level, const char* prompt)
{   
  TPrint_section& body = level == 0 ? _form->totcat() : _form->totgen();
  if (level == 0)
    body.find_field(F_CODTAB).set(_form->decode_group(prompt));
  else
    body.find_field(F_CODTAB).set(prompt);
  _form->print_separator();
  _form->print_section(body);
  for (unsigned int i = 0; i < body.fields(); i++)
    body.field(i).set("");
}

void TLC_app::main_loop()
{
  TLC_mask m;
  ditta_cespiti().init_mask(m);
  while (m.run() != K_QUIT)
  {
    const int ese = m.get_int(F_ESERCIZIO);
    const int gruppo = m.get_int(F_GRUPPO);
    const TString4 specie = m.get(F_SPECIE);
    ditta_cespiti().set_attivita(ese, gruppo, specie);
    const bool extra = m.get_bool(F_SALDINI);
    TLC_form form(extra);
    _form = &form;
    _tipo_sit = m.get_int(F_SITUAZIONE);
    _order = m.get_int(F_ORDINAMENTO);
    _suborder = m.get_int(F_SUBORDINAMENTO);
  
    TRelation rel(LF_CESPI);    
    TString expr;
    expr << "IDCESPITE==IDCESPITE|CODES==" << m.get(F_ESERCIZIO) << "|TPSALDO==1";
    rel.add(LF_SALCE, expr);  
    
    expr << "|TPAMM=" << _tipo_sit;
    rel.add(LF_AMMCE, expr);  
    
    const TRectype& cespi = rel.curr();
    
    TString filter;
    if (_order == 1)
    {
      const int fc = m.get_int(F_FROM_CAT);
      const int tc = m.get_int(F_TO_CAT);
      if (fc != 0)
      {
        if (filter.not_empty()) filter << "&&";
        filter << '(' << CESPI_CODCAT << ">=" << fc << ')';
      }
      if (tc != 0)
      {
        if (filter.not_empty()) filter << "&&";
        filter << '(' << CESPI_CODCAT << "<=" << tc << ')' ;
      }
    }
    else
    {
      const TString& fi = m.get(F_FROM_IMP);
      const TString& ti = m.get(F_TO_IMP);
      if (!fi.blank())
      {
        if (filter.not_empty()) filter << "&&";
        filter << '(' << CESPI_CODIMP << ">=\"" << fi << "\")";
      }
      if (!ti.blank())
      {
        if (filter.not_empty()) filter << "&&";
        filter << '(' << CESPI_CODIMP << "<=\"" << ti << "\")";
      }
    }
    
    TString orderby;
    if (_order == 1)
      orderby = "CODCAT";
    else  
      orderby = "CODIMP";
    if (_suborder == 1)  
      orderby << "|DTCOMP|IDCESPITE";
    else  
      orderby << "|IDCESPITE";
      
    TSorted_cursor cur(&rel, orderby, filter);
    form.set_cursor(cur);

    const long items = cur.items();
    cur.freeze();
    
    printer().open();
    
    TString16 last_group = "@";  // Simbolo speciale per indicare nessuna stampa!
    
    for (cur = 0L; cur.pos() < items; ++cur)
    {             
      // Controllo qui la validit� per non incasinare il valutatore con stringhe e numeri
      if (cespi.get_int(CESPI_CODCGRA) != gruppo || cespi.get(CESPI_CODSPA) != specie)
        continue;
    
      const TString16 curr_group = cespi.get(_order == 1 ? CESPI_CODCAT : CESPI_CODIMP);
      if (curr_group != last_group)
      {
        if (last_group != "@")
        {
          if (extra)
            print_total(0, last_group); 
          printer().formfeed();
        }
        last_group = curr_group;
        form.set_testata(m, last_group);
      } 
      print_cespite();
    }
    if (last_group != "@")
    {
      if (extra)
      {
        print_total(0, last_group);
        print_total(1, "GENERALE");
      }
    }

    printer().close();
    xvtil_statbar_set("");
  }
}

int ce3500(int argc, char* argv[])
{
  TLC_app app;
  app.run(argc, argv, TR("Lista Cespiti"));
  return 0;
}