#ifndef __APPLICATION_H
#define __APPLICATION_H

#ifndef INCL_XVTH
#include <xvt.h>
#endif

#ifndef __DICTION_H
#include <diction.h>
#endif

#define MSG_AI "AI"      // message auto_insert (relapp)
#define MSG_FS "FS"      // message filtered start (relapp)
#define MSG_LN "LN"      // message link (printapp -> relapp)
#define MSG_ED "ED"      // message edit (maskfld -> relapp)
#define CHK_ALL -1       // all authorization checks
#define CHK_DONGLE 0     // dongle authorization checks
//#define CHK_USER 1       // user authorization checks

#ifndef __ASSOC_H
class TAssoc_array;
#endif
// @doc EXTERNAL

// @class TApplication | Classe per la gestione di tutte le applicazioni PRASSI
class TApplication

// @author:(INTERNAL) Guido

// @access:(INTERNAL) Private Member
{
//  // @cmember:(INTERNAL) Identificatore del menu' legato all'applicazione
//  int _bar;
  // @cmember:(INTERNAL) Numero di argomenti passati all'applicazione
  int _argc_;
  // @cmember:(INTERNAL) Array di argomenti passati all'applicazione
  const char** _argv_;  
  // @cmember:(INTERNAL) Ora di inizio utilizzo del programma (per versioni DEMO)
  time_t _start_time;
  // @cmember:(INTERNAL) Array di autorizzazione concessa all'utente
  TBit_array _user_aut;
  // @cmember:(INTERNAL) Array di valori dei modi speciali
  TAssoc_array * _god_vars;
  
  // @cmember:(INTERNAL) Codice dell'applicazione
  TString _name;
  // @cmember:(INTERNAL) Nome della applicazione
  TString _title;
  // @cmember:(INTERNAL) Nome del modulo principale applicazione
  TString _module_name;
  // @cmember:(INTERNAL) Elenco dei files
  TArray _used_files;

  // @cmember:(INTERNAL) Codice della ditta
  long _savefirm;

  // @cmember:(INTERNAL) Indica se l'applicazione e' partita
  bool _running;
  // @cmember:(INTERNAL) Indica se l'applicazione e' stata creata con successo
  bool _create_ok;

  // @cmember:(INTERNAL) Termine dell'applicazione  
  void terminate(); 

// @access Protected Member
protected:
  // @cmember Ritorna il nome del modulo dell'applicazione
  const char* get_module_name() const;
  // @cmember Event handler della finestra principale del programma
  static long task_eh(WINDOW win, EVENT* ep);

  // @cmember Handler degli eventi della finestra principale, chiamato da <mf TApplication::task_eh>
  virtual long handler(WINDOW win, EVENT* ep);
  // @cmember Estende il dialog box della set_firm
  virtual bool extended_firm() const 
  { return false; }
  // @cmember Indica se si intendono usare i files DBF
  virtual bool use_files() const 
  { return true; }
  
  // @cmember Inizilizzazzioni di bassissimo livello
  virtual bool pre_create() 
  { return true; }
  // @cmember Crea la finestra principale
  virtual bool create();
  // @cmember Controlla il menu'
  virtual bool menu(MENU_TAG) 
  { return true; }  
  // @cmember Rimuove l'applicazione
  virtual bool destroy();
  
  // @cmember Chiamata ogni volta che l'utente usa il menu Cambia Parametri
  virtual void on_config_change();
  // @cmember Chiamata ogni volta che l'utente cambia ditta
  virtual void on_firm_change();
  
  virtual bool test_assistance_year() const;

  // @cmember Setta i permessi di utilizzo dei moduli
  void set_perms();
  
  // @cmember apre i files necessari
  void open_files(int logicnum, ...);  

  // @cmember Percorso documenti archiviati
  bool get_spotlite_path(TFilename& path) const; 

  // @access Public Member
public:
  // @cmember Fa partire l'applicazione
  void run(int argc, char* argv[], const char* name);

  // @cmember Ritorna l'identificatore della classe
  virtual word class_id() const 
  { return CLASS_APPLICATION; }

  // @cmember Controlla se il programa e' partito
  bool is_running() const { return _running; }
  // @cmember Controlla se si tratta di una applicazione valida
  virtual bool ok() const 
  { return _create_ok; }
  // @cmember Risposta alla selezione Stampa del menu File
  virtual void print();
  
  virtual bool get_next_pdf(int anno, long ditta, const char* codnum, long numdoc, long codcf, TFilename& pdf) const;
  virtual bool get_next_mail(TToken_string& to, TToken_string& cc, TToken_string& ccn, 
                             TString& subj, TString& text, TToken_string& attach, bool& ui) const;

  // @cmember Controlla se al programma corrente e' concesso cambiare ditta da menu.
  virtual bool firm_change_enabled() const;
  // @cmember Ritorna la <c TToken_string> con la lista dei moduli cui appartiene il programma
  virtual const char * extra_modules() const { return ""; }
  // @cmember Abilita la verifica del modulo cui appartiene il programma
  virtual bool check_autorization() const 
  {return true;}
                                    
  // @cmember Forza la chiusura dell'applicazione  
  void stop_run();

  // @cmember Mette il segno Check a fianco di una voce di menu
  void check_menu_item(MENU_TAG item, bool on = true);
  // @cmember Toglie il segno Check a fianco di una voce di menu
  void uncheck_menu_item(MENU_TAG item);
  // @cmember Permette di abilitare/disabilitare una voce di menu'
  void enable_menu_item(MENU_TAG item, bool on = true);
  // @cmember Permette di disabilitare una voce di menu' (chiama <mf TApplication::enable_menu_item>)
  void disable_menu_item(MENU_TAG item) 
  { enable_menu_item(item, false); }
  // @cmember Simula la selezione di una voce di menu
  void dispatch_e_menu(MENU_TAG item);

  // @cmember Ritorna il nome dell'applicazione
  const TString& name()  const 
  { return _name; }
  // @cmember Ritorna l'array di parametri da passare all'applicazione
  const char** argv() const  
  { return _argv_; }
  // @cmember Ritroan il parametro <p i>-esimo da passare all'applicazione
  const char* argv(int i) const  { return _argv_[i]; }
  // @cmember Ritorna il numero di paramentri da passare all'applicazione
  int argc() const  
  { return _argc_; }

  // @cmember Setta il titolo da assegnare all'applicazione
  void set_title(const char* t) 
  { _title = t; }
  // @cmember Ritorna il titolo da assegnare all'applicazione
  const TString& title() const 
  { return _title; }

  // @cmember static void | check_parameters | int & argc, char *argv[] |
  //          Legge il parametro /uUTENTE e lo toglie dalla lista
  static void check_parameters(int& argc, char *argv[]);

  // @cmember Ritorna i numeri della versione del programma  
  static bool get_version_info(int& year, int& release, int& tag, int& patch);

  // @cmember Controlla se il modulo <p module> ha l'autorizzazione all'esecuzione
  bool has_module(int module, int checktype = CHK_ALL) const;
  // @cmember Setta la ditta corrente (Ritorna se ce l'ha fatta)
  bool set_firm(long cod = -1);
  // @cmember Ritorna la ditta corrente
  long get_firm() const;
  // @cmember Ritorna la directory in cui si trovano i dati della ditta corrente
  const char* get_firm_dir() const;

  // @cmember Interfaccia runtime del menu' della finestra principale???
  bool add_menu(TString_array& menu, MENU_TAG id = 0);
  // @cmember Elimina il menu' <p id> (Ritorna se ce l'ha fatta???)
  bool remove_menu(MENU_TAG id);

  // @cmember Costruttore
  TApplication();
  // @cmember Distruttore
  virtual ~TApplication();
};

class TSkeleton_application : public TApplication
{          
protected:
  virtual bool create();
  virtual bool menu(MENU_TAG);
  
protected:
  virtual void main_loop() pure;
 
public: 
  TSkeleton_application() { }
  virtual ~TSkeleton_application() { }
};

TApplication& main_app();

#endif /* __APPLICATION_H */