#ifndef __M70102_H
#define __M70102_H

#ifndef __MSKSHEET_H
#include <msksheet.h>
#endif

#ifndef __CONFIG_H
#include <config.h>
#endif                   

#ifndef __RELAPP_H
#include <relapp.h>
#endif

#ifndef __77LIB_H
#include "77lib.h"   
#endif

#ifndef __770100a_H
#include "770100a.h"
#endif

// Id della maschera di edit dello sheet versamenti
#define F_VERS_1015         101
#define F_DATAVERS          102
#define F_LUOVERS           103
#define F_TIPOVERS          104
#define F_ABI               105   // abi e cab
#define F_CAB               72
#define SM_PROGRBANCA       107
#define F_RITVERS           108

// Posizioni nell'array-sheet dei pagamenti
const int AS_POS_RITPAG = 3;  
const int AS_POS_NRIGA  = 4;            
const int AS_POS_NVER   = 5; 
                                                      
#define COLONNE_SIGNIFICATIVE_SPREADSHEET_VERSAMENTI  8    

class TSchedaPercipienti : public TRelation_application
{
  private:
    bool  _from_modify;
    TLink770  _coll;
    TSchedaPE*  _rel;
    TMask*  _msk[2];
    long  _codanagr;
    TString16 _tipoa;
    TString80 _ragsoc;
    int _nproga;
    int _mode;
    TLocalisamfile* _per, *_scper, *_rver, *_rpag;
    long  _rigavers;
    long  _lastvers, _lastpag;
    long  _numreg;    // NUMREG inviato dalla 1. nota    
    int _anno_dic;  // anno dichiarazione
    bool _soggnres; // flag soggetto non residente (usato per controlli)
    
    // Collegamento versamento->pagamenti
    TBit_array _selected;
    TNikArray_sheet*  _pags;

    real _tot_compenso, _tot_spese;
    real _tot_vers, _tot_rit;
    
  private:               
    TString80 get_ragsoc(const char* tipoa, const long codanagr);
    static void work_tipoluogo(TMask_field& f);
    
    // controlla che il versamento abbia collegato almeno un pagamento
    static bool check_pagamenti     (TMask_field& f, KEY key);
    
    // Handler campi chiave
    static bool codditta_handler  (TMask_field& f, KEY key);    
    static bool codanagr_handler  (TMask_field& f, KEY key);
    static bool nprog_handler     (TMask_field& f, KEY key);

    // Handler del documento
    static bool check_handler(TMask_field& f, KEY key);
    static bool check_causale(TMask_field& f, KEY k);
    static bool check_compensi(TMask_field& f, KEY k);
    static bool check_spese(TMask_field& f, KEY k); 
    static bool check_competenza(TMask_field& f, KEY k);
    static bool forced_handler(TMask& m, KEY key);    
        
    // Handler del versamento
    static bool vers_notify(TSheet_field& s, int r, KEY key);
    static bool vers1015_handler(TMask_field& f, KEY key);
    static bool tipo_hndl(TMask_field& f, KEY key);      
    static bool luo_hndl(TMask_field& f, KEY key);      
    static bool abicab_hndl(TMask_field& f, KEY key);
    static bool ver_azzera(TMask_field& f, KEY key);
    
    // Handler del pagamento
    static bool pags_notify(TSheet_field& s, int r, KEY key);
    static bool pag_azzera(TMask_field& f, KEY key);    
    static bool pag_standard_handler(TMask_field& f, KEY key);
    
    // collegamento pagamenti a versamenti
    static bool pag_select(TMask_field& f, KEY key);
    static bool compilato_vers(TMask_field& f);          
    static long get_numvers  (TMask_field& f);
    static void setta_ritvers(TMask_field& f, const real& ritenuta);
    
    void enable_vers_cells  (int r, bool enable=TRUE);
    void disable_vers_cells (int r) { enable_vers_cells(r,FALSE); }
        
    bool vers_attached(const long numvers);

    void pag_pack();
    void ver_pack();
 
    // set automaticamente il numero progressivo di scheda
    static bool setta_nprog(TMask& m, const bool variazione=FALSE, 
                            const char* codanagr=NULL);
                                                              
    // restitiusce la maschera di modifica/inserimento
    TMask& TheMask() const;                                                                    
    // restitiusce lo sheet pagamenti attivato
    TSheet_field& pag_sheet_enabled(TMask& m, bool force_enable=FALSE) const;          
    // attiva lo sheet pagamenti in base al quadro
    bool activate_pag_sheet(TMask& m);      
    // ritorna il numero di colonne dello sheet attivo
    int num_sheet_column() const;                    
    // ritorna la posizione del Token t all'interno dello sheet attivo
    int token_pos(const char* t) const;                               
    // ritorna l'identificatore del Token t all'interno dello sheet attivo
    int token_dlg(const char* t) const;                               
    // ritorna la Token_string pilota dello sheet attivo
    const char* pilot_sheet() const;                    
    // riempe la struttura pagamento da una riga di sheet 
    Pag_struct& from_sheet_to_struct(TToken_string& t, Pag_struct& s); 
    // riempe una riga di sheet dalla struttura pagamento
    void from_struct_to_sheet(Pag_struct& s, TToken_string& t);
    // riempe la struttura pagamento dalla maschera di sheet
    Pag_struct& from_mask_to_struct(TMask& m, Pag_struct& s); 
    // riempe la maschera di sheet dalla struttura pagamento
    void from_struct_to_mask(Pag_struct& s, TMask& m);      
    // abilita lo sheet pagamenti in base al quadro
    TSheet_field& enable_pag_sheet(TMask& m, const TString& quadro) const;  
    // aggancia handler allo sheet passato 
    void set_pag_handler(TSheet_field& s) const;                        
    // genera gli items per la causale quadro
    void build_causqua_items(TMask& m, const TString& quadro) const;    
    // azzera struttura pagamento
    Pag_struct& clear_struct(Pag_struct& s); 
    // calcola una riga di pagamento dove <s> � la struttura con i dati,
    // <c> � la struttura con i calcolati per eventuali controlli,
    // <force> consente di forzare la sostituzione dei valori di riga
    // con i calcolati anche se sono diversi da zero
    Pag_struct& calcola_riga_pag(Pag_struct& s,
                                 Pag_struct& c,
                                 bool force,
                                 const real h_PercAssImp,
                                 const real h_PercCassaPrev,
                                 const real h_PercRitenuta,
                                 const real h_PercInps,
                                 const real h_PercAssImpInps,
                                 const real h_PercCommitInps);  
    
  protected:
    virtual bool        user_create();
    virtual bool        user_destroy();
    virtual TRelation*  get_relation() const { return _rel; }
    virtual TMask*      get_mask(int mode);
    virtual bool        changing_mask(int mode);  
    virtual void        init_query_mode (TMask&);
    virtual void        init_query_insert_mode (TMask&);    
    virtual void        init_insert_mode(TMask&);
    virtual void        init_modify_mode(TMask&);
    virtual int         rewrite(const TMask& m);
    virtual int         write(const TMask& m);
    virtual int         read(TMask& m);              
    virtual void        on_config_change();    
              
    void    init_mask(TMask&);  
    TMask*  load_mask(int n);
    void    fill_sheet(TMask&);
    bool    scrivi_dati_per(TRectype& rec);
    void    mask2rel(const TMask& m);
    void    rec2row(TToken_string& r, TRectype& rec, int row);
    void    update_lasts(TMask& m);
    
    void    attach_pag_vers (int pag, long numvers);
    void    detach_pag_vers (int pag);   
    void    new_row(TSheet_field& ver_pag, int r, bool vers);        
    bool    my_empty_items(TToken_string& r, bool versamenti);
    int     anno_dic() const { return _anno_dic; }

  public:
    bool        _flag_cg;
    void        load_pag_sheet(const long numvers);
    TTipo_coll  tipo_coll() const { return _coll._tipo_coll; }
    void        compila_testata(TMask& m);
    bool        coll_variazione() const; 
    bool        coll_datanum() const { return _coll._datadoc.not_empty() && _coll._numdoc.not_empty(); }
    bool        esiste_perc(TMask& m, const char* coda=NULL);

    TSheet_field& pags() const;
    TSheet_field& vers() const;
    
    TSchedaPercipienti ();
    ~TSchedaPercipienti() {};
};

inline TSchedaPercipienti& app() { return (TSchedaPercipienti&) main_app();}

#endif