#ifndef __77STQ_H
#define __77STQ_H

#include <xvt.h>
#include <applicat.h>
#include <relation.h>
#include <config.h>
#include <mask.h>
#include <form.h>
#include <printer.h> 
#include <progind.h> 
#include "base.h"
#include <urldefid.h>
#include <nditte.h>
#include <anagr.h>   
#include <recarray.h>
#include "quadroc.h"
#include "quadrod.h"
#include "quadrod1.h"
#include "quadrogd.h"
#include "quadrif.h"
#include "77stqd.h"
#include "77lib.h"  

// Righe da saltare nelle prime pag. dei moduli successivi al primo (che' son
// senza le righe del posizionamento...)
HIDDEN int HEADER_PRIMA_NOPOS = 3;

#define QD_FORMLEN      72
#define HEADER_SECONDA  6
#define HEADER_TERZA    6
#define HEADER_QUARTA   6
 
HIDDEN TString16 __dep16;
HIDDEN TString80 __dep80;

// Vega-Key di Modulaser
HIDDEN const char*  VK_STARTDOC = "<VK>&MA797&0&1";
HIDDEN const char*  VK_ENDDOC   = "<VK>!0";
typedef enum { VEGASTARTDOC, VEGASTARTDITTA, VEGASTARTPAGE, VEGAENDDOC } ModulaserKey;

// Campi form
#define TOT_TOTALE  1
#define TOT_SNSRIT  2
#define TOT_IMPON   3
#define TOT_IMPOR   4
#define TOT_NETTO   5

#define D_TOTALE      16
#define D_SNSRIT      17
#define D_IMPONIBILE  18
#define D_IMPORTO     20
#define D_NETTO       21

#define D1_TOTALE     12
#define D1_QUOTAPRO   13
#define D1_SPESEANT   14
#define D1_IMPONIBILE 15
#define D1_IMPORTO    17
#define D1_NETTO      18

#define C_AMMLORDO    13
#define C_CONTROBB    14
#define C_SOMNONSOG   15
#define C_IMPONIBILE  16
#define C_IMPOSTA     17
#define C_DETCARFAM   18
#define C_GGLAV       19
#define C_DETLAVDIP   20
#define C_TOTDET      21
#define C_RITENUTE    22

#define H_COFI_DIC      13
#define H_NUM_FOGLIO    14  
#define QD_STATO_ESTERO 12

#define FIRMADIC 2

typedef enum { PRIMA=1, SECONDA, TERZA, QUARTA } PaginaQuadro;
typedef enum { fisiche, nofisiche } TipoPagina;

const char* get_ragsoc_anagr(char tipo, long codanagr);

#define FIRMADIC 2

class TDicForm : public TForm
{
  private:  
    real _f_tot_totale, _f_tot_snsrit, _f_tot_impon, _f_tot_impor, _f_tot_netto;
    real _nf_tot_totale, _nf_tot_snsrit, _nf_tot_impon, _nf_tot_impor, _nf_tot_netto;

    TCursor*    _cur;

  protected:                                                                           
    long      _Items; // numero di record che hanno passato il filtro
    PaginaQuadro    _PaginaCorrente;

    void      set_curr_page(PaginaQuadro pagina) { _PaginaCorrente = pagina; }    
    virtual int   dic_form_len() const;
    virtual void  inc_curr_page();
    virtual void  next_page(TPrinter& pr);
    bool    _modulaser;     // se stampa per modulaser
    bool    _posiziona;
    TipoDitta _tipo_ditta;  // tipo ditta: normale, estinto, dichiarante
    int     _num_foglio;    // numero foglio
    TString   _cofi_dic;    // cod.fis. dichiarante
    bool    _can_print_tot_fis, _can_print_tot_nofis;
    bool    _finite_fis, _finite_nofis, _LastDitta, _EndPrintDitta;
    bool    _GiaStampatiFis, _GiaStampatiNoFis, _PaginaPosizionamento;
    bool    _GiaPosizionato, _GiaMessoStartDoc, _GiaMessoStartPage[4];   // flag per modulaser
    int     _CtrNoFisStampati, _CtrFisStampati; // contatori p.f. e p.g. stampate
    long    _codditta, _codditta_dic;  // cod.ditta e cod.ditta dichiarante
    int     _anno; // Anno dichiarazione
    int     _RigaCorr;  // contatore riga corrente
    TString16 _quadro;    // codice quadro in stampa
    
    TString_array _tot_fis, _tot_giu;
    void attiva_totali(char tipo);
    
    void    stampa_testata(TPrinter& pr);
    virtual bool ultima_pagina() const { return _PaginaCorrente==QUARTA; }
    virtual void    stampa_totali(TPrinter& pr, bool tot, bool sig);
    virtual void    set_body(TPrinter& pr, const char tipo);
    void    StampaPagina(PaginaQuadro PaginaCorrente, const bool StampaTotali, const long Fis, const long NoFis);
    void    posiziona();                           
    void    fill_page(TPrinter& pr, const int righe);
    void    jump_to_line(TPrinter& pr, const int riga);
    const char* BuildModulaserStartPage();
    void    ClearFlagModulaser();      
    bool    PaginaPosizionamento() const;
    virtual bool InitPrint(const long codditta);

  public:                 
    void    put_modulaser(TPrintrow& row, ModulaserKey key, int page=0);     
    
    virtual TCursor* cursor() const     { return _cur; }
    virtual TRelation* relation() const { return _cur->relation(); }

    virtual long filtra(const long codditta);
    
    TProgind* _prog;    // progind usata in print()
    
    const long    codditta() const { return _codditta; }
    void      set_codditta(const long ditta) { _codditta = ditta; }
    const int anno() const { return _anno;}
    void    set_anno(int a)  { _anno = a; }
    void    set_posiziona(const bool posiz) { _GiaPosizionato = FALSE; }
    void    can_print_tot_fis(const bool canpr) { _can_print_tot_fis = canpr; }
    void    can_print_tot_nofis(const bool canpr) { _can_print_tot_nofis = canpr; }
    void    set_last_ditta(const bool last) { _LastDitta = last; }
    bool    last_ditta() const { return _LastDitta; }
    bool    EndJob() const { return _LastDitta && _EndPrintDitta; }
    bool    ultima_fis();
    bool    ultima_nofis();
    TString&  cofi_dic() { return _cofi_dic; }
    void    set_cofi_dic(const char* cofi);
    TipoDitta tipo_ditta() const { return _tipo_ditta; }
    void    set_tipo_ditta(TipoDitta tipo) { _tipo_ditta = tipo; }
    bool    modulaser() const { return _modulaser; }
    void    set_modulaser(const bool modul) { _modulaser = modul; }
    void    set_num_foglio(const int foglio) { _num_foglio = foglio; }
    int     num_foglio() const { return _num_foglio; }
    virtual void azzera_totali();
    PaginaQuadro    curr_page() const { return _PaginaCorrente; }

    int firma_dichiarante();
    
    void set_progind(TProgind* prog) { _prog = prog; }
    TProgind* progind() { return _prog; }
    bool usa_progind() const { return _prog != NULL; }
    
    virtual void set_cursor(TCursor* cur);
    virtual void close_print();    
    virtual bool print(const long codditta, const long NumFis, const long NumNoFis);
    virtual int   prima_riga(PaginaQuadro p) const;
    const TString& quadro() const { return _quadro; }
    bool MessoStartDoc() const { return _GiaMessoStartDoc; }
    
    TDicForm(const char* form, const char* quadro);
    virtual ~TDicForm() {}
};      

////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////  
////////////////////////////////////////////////////////////////////////////////////////////
//  
//                                        TStDicArray                                                                                    
//
// Array delle ditte da stampare. Contiene una riga per ogni ditta che si vuole stampare
// Il formato della riga e': 
//   codditta|estinti|numfis|numnofis|ultimafis|ultimanofis  
//
/////////////////////////////////////////////////////////////////////////////////////////////

class TStDicArray : public TObject
{
  private:
    TString_array _store;
  
  public:
    TToken_string& operator[](int i) const;
    int curr_index() const { return _store.last(); }
    void set(const int index, const TipoDitta tipo=normale, const int num_fis=0, const int num_nofis=0,
             bool ultima_con_fis=FALSE, bool ultima_con_nofis=FALSE, const char* cofidic=NULL);
    void set_tipo(const int index, const TipoDitta tipo);                               
    void set_ultima_con_fis(const int index, const bool ultima_fis);
    void set_ultima_con_nofis(const int index, const bool ultima_nofis);        
    void set_flag_tipi(const int index, const bool ultima_fis, const bool ultima_nofis);
    void set_ctr_tipi(const int index, const int num_fis, const int num_nofis);
    void add(const long codditta, const TipoDitta tipo=normale, const int num_fis=0, const int num_nofis=0,
             bool ultima_con_fis=FALSE, bool ultima_con_nofis=FALSE, const char* cofidic=NULL);
    int items() const { return _store.items(); }
    void remove(int index) { _store.destroy(index); }
    void destroy() { _store.destroy(); }
};

/////////////////////////////////////////////////////////////////////////////////////////////
//
//                                     STAMPA QUADRO
//
/////////////////////////////////////////////////////////////////////////////////////////////

class TStampaQuadro : public TApplication
{
  TMask*      _m;        // Maschera di stampa     

  TConfig*    _cnf;      // Configurazione
  TString16   _section;  // Paragrafo del config
  long        _codditta;
  int         _anno_dic;                     

  TString     _quadro;
  char        _livello;  // "S" studio, "D" singola ditta           
  TString     _title;

  TStDicArray _ditte;

protected:   // TApplication
  virtual bool menu(MENU_TAG);
  virtual void on_config_change();      
  
  virtual bool create(); 
  virtual bool destroy();
  
protected:    
  virtual bool user_create() pure;
  virtual bool user_destroy() pure;
  
  virtual TDicForm* get_form() const pure;
  virtual TCursor* get_cursor() const pure;

  virtual const char* mask_name() const;
  virtual const char* form_name() const;

  virtual bool conta_tipi_per() const { return FALSE; }  // Guy: Was TRUE in 1996
  void fill_estinti(const long CodDic);
  const TStDicArray& ditte() const { return _ditte; }

  virtual bool print_quadro(const int OffsetDitta, const bool modulaser);
  virtual void print(const bool modulaser);

  bool singola_ditta() const { return _livello == 'D'; }
  const TString& quadro() const { return _quadro; }
  
  void set_taitol(const char* t) { _title = t; }
  const int  anno_dic() const    { return _anno_dic;}
  TStampaQuadro(const char* quad, char liv);
  static bool setprint_handler(TMask_field& f, KEY k);
  
public:  
  const TString& taitol() const { return _title; }

  virtual ~TStampaQuadro() { }
};

class TQuadroD : public TDicForm
{
protected:                                                                        
  virtual void stampa_testata(TPrinter& pr);
  virtual bool print(const long codditta, const long NumFis, const long NumNoFis);

protected:            
  virtual int numero_pagine() const { return 4; }
  virtual int elementi_pagina(PaginaQuadro p) const;
  virtual int dic_form_len() const {  return QD_FORMLEN; }

public:
  virtual bool on_prima(TCursor& cur);
  virtual bool on_seconda(TCursor& cur);
  virtual bool on_terza(TCursor& cur);
  virtual bool on_quarta(TCursor& cur);
  virtual void on_firma();

  virtual bool preprocess_print(TCursor& cur)      { return TRUE; }
  virtual bool preprocess_body(const TCursor& cur) { return TRUE; }
  virtual void set_body(TPrinter& pr);

  TQuadroD(const char* form, const char* quadro)  : TDicForm(form, quadro) {}
  virtual ~TQuadroD() {} 
};      

class TStampaQuadroD : public TStampaQuadro
{
protected:  // Can be reused in Dbis and D1
  TQuadroD*  _form;
  TCursor*   _cur;        

protected:   
  virtual bool  user_create();
  virtual bool  user_destroy();

  virtual TDicForm* get_form() const   { return _form; }
  virtual TCursor*  get_cursor() const { return _cur; }
        
public:
  TStampaQuadroD(const char* quadro, char livel);
  virtual ~TStampaQuadroD() { }
};


#endif