#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 "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;
 
// Chincaglieria che serve per posiziona()
typedef   long       HWND;
HIDDEN const int MAX_LEN = 300;
extern "C" {
  BOOLEAN PrintLineNow( char *pData, word cbBytes, HWND hInst );
};


HIDDEN TString16 __dep16;
HIDDEN TString80 __dep80;

// Vega-Key di Modulaser
HIDDEN const char*  VK_STARTDOC = "<VK>&MA796&0&1";
HIDDEN const char*  VK_ENDDOC   = "<VK>!0";
typedef enum { STARTDOC, STARTDITTA, STARTPAGE, ENDDOC } 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_TOTALE      14
#define C_CONTSSN     15
#define C_SOMME       16
#define C_IMPONIBILE  17
#define C_RITENUTE    18
#define C_NETTO       19

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

#define HEADER_SECONDA  8
#define HEADER_TERZA    8
#define HEADER_QUARTA  13

#define HEADER_D1_SECONDA 8
#define HEADER_D1_TERZA   8
#define HEADER_D1_QUARTA 14

#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     _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    put_modulaser(TPrintrow& row, ModulaserKey key, int page=0);     
    void    ClearFlagModulaser();      
    bool    PaginaPosizionamento() const;
    virtual bool InitPrint(const long codditta);

  public:                 
    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()
    
    long    codditta() const { return _codditta; }
    void    set_codditta(const long ditta) { _codditta = ditta; }
    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; }
    
    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 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 TRUE; }  
  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; }
  
  TStampaQuadro(const char* quad, char liv);

public:  
  const TString& taitol() const { return _title; }

  virtual ~TStampaQuadro() { }
};

#endif