// 776100.cpp - Menu manutenzione quadri 
  
// menu manutenzione quadri               (GROUP 1 alias MENU_MAIN)    
// sottomenu manutenzione dati anagrafici (GROUP 2 alias MENU_DATIANAG)       
// sottomenu stampe                       (GROUP 3 alias MENU_STAMPE) 
// sottomenu soggetto dichiarante         (GROUP 4 alias MENU_SOGGDICH)
// sottomenu stampe dichiarzioni          (GROUP 5 alias MENU_STAMPEDICH) 

#include <applicat.h>
#include <config.h>
#include <msksheet.h>
#include <mailbox.h>
#include <execp.h>
#include <relapp.h>
#include <relation.h>
#include <urldefid.h>
#include <prefix.h>                 
#include <utility.h>

#include "776.h"
#include "776100a.h"
#include "776100b.h"
#include "77lib.h"
#include "../ba/ba4600.h"

HIDDEN TString80 __tmp;
HIDDEN const int NUM_QUADRI = 29;

typedef enum { grassetto=0, sottolineato, piano } stile;

class TManutenzione_quadri : public TApplication
{
  private:
    TRelation*      _rel;
    TMask*          _msk[2];
    int             _mode;
    TLocalisamfile*  _base, *_basebis;
    int             _anno_dic;
    bool            _soci;
    long						_codditta, _coddic;  
    TString					_qcomp_prev;
    
  protected:
    virtual bool create();
    virtual bool destroy();
    virtual bool menu(MENU_TAG m);
    virtual void on_config_change();
    static bool filtra_ditte(const TRelation * r); 
    static bool show_menu(TMask_field& fld, KEY k);
    static bool hide_menu(TMask_field& fld, KEY k);
    static bool codditta_handler(TMask_field& fld, KEY k);
    static bool leggi_quadri(TMask_field& f, KEY k);
    static bool exec_soci(TMask_field& fld, KEY k);
            
    void        init_mask(TMask&);
    TMask*      load_mask(int n);

    void        enphasize(TString& qcomp, TMask& m);     
    void        inibith(TString& qric, TMask& m);

    const char* make_prompt(int i, stile st = grassetto);    

    bool        main_loop(); 
    bool        query_mask();    

    void        init_query_mask (TMask&);
    void        init_menu (TMask&);
    bool		lock(const bool lok=TRUE);
    
  public:
    TManutenzione_quadri (); 
    ~TManutenzione_quadri() {};     
    virtual bool firm_change_enabled() const;
};

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

TManutenzione_quadri::TManutenzione_quadri(): _soci(FALSE),_rel(NULL) {memset(_msk, 0, sizeof(_msk));}

bool TManutenzione_quadri::filtra_ditte(const TRelation * r)
{           
  const TRectype& ditte_rec = r->lfile().curr();
  const long codditta = ditte_rec.get_long("CODDITTA");
  long  coddic = 0L;
  bool ok = FALSE;
  TLocalisamfile& base = *(app()._base);
  TString16	tipoq;
  
  base.zero();
  base.put("CODDITTA", (long)codditta);
  ok = base.read() == NOERR;
  
  if (ok)
  {
    coddic = base.get_long("CODDITTA");  
    tipoq  = base.get("TIPOQUA");
    ok = tipoq != "D" ? coddic == codditta : FALSE;
  }
  return ok;
}

void TManutenzione_quadri::on_config_change()
{
  TConfig conf(CONFIG_STUDIO);
  _anno_dic = (int)conf.get_long(ANNO_SEL, NULL, -1, TDate(TODAY).year());
}
   
bool TManutenzione_quadri::firm_change_enabled() const
{
  return FALSE;
}   
                                    
// Lancia la gestione soci passando la ditta                                    
bool TManutenzione_quadri::exec_soci(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
  {           
    TString appname("ba4 -5");
    TString body(16);
    const long ditta = app()._codditta;         
    body << FLD_SC1_CODDITTA << "|";
    body << FLD_SC1_CODDITTA << "=";
    body << ditta;        
    TMessage  msg(cmd2name(appname), MSG_FS, (const char*) body);          
                                                                               
    TMailbox mb;                                                           
    mb.send(msg);                                                          

    TExternal_app a(appname);                                                
    a.run();                                                                 
  }                        
  return TRUE;
}

bool TManutenzione_quadri::codditta_handler(TMask_field& f, KEY k)
{
  if (k == K_TAB && !(f.mask().is_running()) )
  {
    TString16 codditta;        
    app()._codditta = get_firm_770();    
    codditta << app()._codditta;
    if (codditta != "0")
    {
      f.set(codditta);
      f.check();
    }
  }   
  
  if (f.to_check(k))
  {
    const long codditta = atol(f.get());
// controlla se e' gia' stata inserita una dich. per la ditta
    if (!exist_dichiar_770(codditta))
      return f.warning_box("Dichiarazione non presente");
    else
      set_firm_770(codditta);
  }
  return TRUE;
}

TMask* TManutenzione_quadri::load_mask(int n)
{
  if (_msk[n] != NULL)
    return _msk[n];

  TFilename name("776100"); name << char(n == 0 ? 'a' : 'b');
  TMask* m = new TMask(name);

  switch (n)
  {
    case 0:
    {
      m->set_handler(F_CODDITTA, codditta_handler);  
      TEdit_field& rag = m->efield(F_RAGDITTA);
      rag.browse()->cursor()->set_filterfunction(filtra_ditte);
    }
    break;
    case 1:
      m->set_handler(RILEGGI_QUADRI, leggi_quadri);
      break;
    default:
      CHECKD(0, "Che strano genere di maschera e' la ", n);
      break;
  }
  return _msk[n] = m;
}

bool TManutenzione_quadri::create()
{
  TApplication::create();

  _base      = new TLocalisamfile(LF_BASE);
  _basebis   = new TLocalisamfile(LF_BASEBIS);
  _rel       = new TRelation(LF_BASE);
  _rel->add(LF_BASEBIS, "CODDITTA=CODDITTA");                  
  
  // inizializza stato precedente quadri per ottimizzazione enphasize
  _qcomp_prev.spaces(NUM_QUADRI); 

  load_mask(0);
  dispatch_e_menu (BAR_ITEM(1));

  return TRUE;
}

bool TManutenzione_quadri::destroy()
{
  if (_msk[1] != NULL) delete _msk[1];
  if (_msk[0] != NULL) delete _msk[0];

  lock(FALSE);  // release lock  

  delete _rel;
  delete _base; delete _basebis;

  return TApplication::destroy();
}


const char* TManutenzione_quadri::make_prompt(int i, stile vivid)
{
  if (vivid == sottolineato)
    __tmp = "@u";

  if (vivid == grassetto)
    __tmp = "@b";

  if (vivid == piano)
    __tmp = "";

  switch (i) {
    case 0:
      __tmp << "Quadro A"  ;
      break;
    case 1:
      __tmp << "Quadro A1"  ;
      break;
    case 2:
      __tmp << "Quadro A2";
      break;
    case 3:
      __tmp << "Quadro A3"  ;
      break;
    case 4:
      __tmp << "Quadro B"  ;
      break;
    case 5:
      __tmp << "Quadro B1";
      break;
    case 6:
      __tmp << "Quadro C"  ;
      break;
    case 7:
      __tmp << "Quadro D"  ;
      break;
    case 8:
      __tmp << "Quadro D1";
      break;
    case 9:
      __tmp << "Quadro E"  ;
      break;
    case 10:
      __tmp << "Quadro E1";
      break;
    case 11:
      __tmp << "Quadro E2";
      break;
    case 12:
      __tmp << "Quadro F"  ;
      break;
    case 13:
      __tmp << "Quadro F1";
      break;
    case 14:
      __tmp << "Quadro F2";
      break;
    case 15:
      __tmp << "Quadro G"  ;
      break;
    case 16:
      __tmp << "Quadro G1";
      break;
    case 17:
      __tmp << "Quadro H"  ;
      break;
    case 18:
      __tmp << "Quadro I"  ;
    	break;  
    case 19:
      __tmp << "Quadro L"  ;      
      break;
    case 20: 
      __tmp << "Quadro N"  ;
      break;
    case 21:
      __tmp << "Quadro P"  ;
      break;
    case 22:
      __tmp << "Quadro Q"  ;
      break;
    case 23:
      __tmp << "Quadro R"  ;
      break;
    case 24:
      __tmp << "Quadro S"  ;
      break;
    case 25:
      __tmp << "Quadro T"  ;
      break;
    case 26:
      __tmp << "Quadro Abis";
      break;
    case 27:
      __tmp << "Quadro Dbis";
      break;  
    default:
      break;
  }
  return __tmp;
}

//
// Disabilito i quadri gia' ricevuti via supp. magnetico
//
void TManutenzione_quadri::inibith(TString& qric, TMask& m)
{
  int   start_dlg   = DLG_STOPREC_A;
  int   dlg;
  
  // quadri fino al quadro U non compreso
  for (int i = 0; i < (NUM_QUADRI-1); i++)
    if (qric[i] == 'X')
    {
      dlg = start_dlg + (i * 2);
      m.field(dlg).disable();
    }
}

// Metto in grassetto  i quadri gia' compilati        
// ma solo quelli variati dal ciclo precedente
// Il quadro L non ha il flag di compilato sul base.
void TManutenzione_quadri::enphasize(TString& qcomp,TMask& m)
{
  int 				start_dlg = DLG_NULL_A;
  const char* prompt;
  int   			dlg = 0;       
  
  // quadri fino al quadro U non compreso
  for (int i = 0; i < (NUM_QUADRI-1); i++)
  {
    if (qcomp[i] != _qcomp_prev[i])
    {
    	dlg = start_dlg + (i * 2);                 
    	prompt = make_prompt(i, qcomp[i] == 'X' ?  grassetto : piano);
    	m.field(dlg).set_prompt(prompt);
    	_qcomp_prev[i] = qcomp[i];
  	}
  }
}

bool TManutenzione_quadri::show_menu(TMask_field& f, KEY k)
{
if (k == K_SPACE)  
  {
    if (f.dlg() == DLG_MANUTENZ)                      // enter su menu
    {                                                 // dati anagrafici  
    	f.mask().hide(-MENU_MAIN);
    	f.mask().show(-MENU_DATIANAG); 
    	f.mask().set_focus_field(DLG_STOPREC_DICH);
    	f.mask().set_caption("Manutenzione dati anagrafici");  
    	return TRUE; 
    }	 
    if (f.dlg() == DLG_STOPREC_ST)                    // enter su menu  
    {                                                 // stampe    	   
    	f.mask().hide(-MENU_MAIN);        
    	f.mask().show(-MENU_STAMPE);           
    	f.mask().set_focus_field(DLG_STOPREC_ST0);             
    	f.mask().set_caption("Stampe");  
    	return TRUE;
    }   
    if (f.dlg() == DLG_STOPREC_SD)                    // enter su menu
    {                                                 // soggetto dichiarante
    	f.mask().hide(-MENU_MAIN);           
    	f.mask().show(-MENU_SOGGDICH);         
    	f.mask().set_focus_field(DLG_STOPREC_SD0);
    	f.mask().set_caption("Soggetto dichiarante");
    	return TRUE;
    }	 
    if (f.dlg() == DLG_STOPREC_STQD)                  // enter su menu 
    {                                                 // stampe dichiarazioni
    	f.mask().hide(-MENU_STAMPE);    
    	f.mask().show(-MENU_STAMPEDICH);       
    	f.mask().set_focus_field(B_BASE);
    	f.mask().set_caption("Stampe dichiarazioni");
    	return TRUE;
    }	  	    	
    return FALSE;      	    	
  }
  return TRUE;    
}

bool TManutenzione_quadri::hide_menu(TMask_field& f, KEY k)
{
  if (k == K_SPACE)  
  {
    if (f.mask().field(DLG_STOPREC_DICH).shown())     // cancel da menu
    {                                                 // dati anagrafici  
    	f.mask().hide(-MENU_DATIANAG);
    	f.mask().show(-MENU_MAIN);      
    	f.mask().first_focus(DLG_MANUTENZ);
    	f.mask().set_caption("Manutenzione dichiarazione");  
    	return TRUE; 
    }	 
    if (f.mask().field(DLG_STOPREC_ST0).shown())      // cancel da menu  
    {                                                 // stampe    	   
    	f.mask().hide(-MENU_STAMPE);
    	f.mask().show(-MENU_MAIN);       
    	f.mask().first_focus(DLG_STOPREC_ST);                
    	f.mask().set_caption("Manutenzione dichiarazione");  
      return TRUE;
    }   
    if (f.mask().field(DLG_STOPREC_SD0).shown())      // cancel da menu
    {                                                 // soggetto dichiarante
    	f.mask().hide(-MENU_SOGGDICH);
    	f.mask().show(-MENU_MAIN);         
    	f.mask().first_focus(DLG_STOPREC_SD);                
    	f.mask().set_caption("Manutenzione dichiarazione");  
    	return TRUE;
    }	 
    if (f.mask().field(B_BASE).shown())               // cancel da menu 
    {                                                 // stampe dichiarazioni
    	f.mask().hide(-MENU_STAMPEDICH);   
      f.mask().show(-MENU_STAMPE);       
      f.mask().first_focus(DLG_STOPREC_STQD);
      f.mask().set_caption("Stampe");  
    	return TRUE;
    }	  	    	
    return FALSE;      	    	
  }
  return TRUE;  
}

void TManutenzione_quadri::init_menu(TMask& m)
{
  m.set(F_ANNODIC, _anno_dic); 
  
  _codditta = _msk[0]->get_long(F_CODDITTA);
  TString80 ragsoc(_msk[0]->get(F_RAGDITTA));
  m.set(F_CODDITTA, _codditta);
  m.set(F_RAGDITTA, ragsoc);

// Se persona giuridica c'e' la voce "Amministratori" 
  _soci = tipo_persona(_codditta) == 'G';
  m.enable(DLG_MANUTENZ_SOCI, _soci);
  m.set_handler(DLG_MANUTENZ_SOCI, exec_soci);  

// Se non e' giuridica non si puo' usare il quadro G  
  m.enable(DLG_STOPREC_G, _soci);
  
// aggancio handler d'ingresso sui menu
  m.set_handler(DLG_MANUTENZ,    show_menu);
  m.set_handler(DLG_STOPREC_ST,  show_menu);
  m.set_handler(DLG_STOPREC_SD,  show_menu); 
  m.set_handler(DLG_STOPREC_STQD,show_menu);  

// Se non e' un dichiarante disabilita la corrispondente voce
  m.enable(DLG_STOPREC_SD, sogg_dic(_codditta));
      
// Evidenzia i quadri compilati o inibiti  
  TString qcomp(NUM_QUADRI), qric(NUM_QUADRI);

// 1.5       
  _basebis->setkey(1);
  _basebis->zero();                                 
  _basebis->put("CODDITTA", _codditta);        
  int rt = _basebis->read();  
  qcomp = _basebis->get("QCOMP");
  qric  = _basebis->get("QSUPPRIC");
     
  if (qcomp == "") qcomp.spaces();  
  if (qric == "")  qric.spaces();
    
  enphasize (qcomp, m);
  inibith   (qric, m);
}

bool TManutenzione_quadri::lock(const bool lok)
{
  TLocalisamfile& base = *_base;
  
  base.setkey(1);
  base.zero();
  base.put("CODDITTA", _codditta);        
  const int rt = base.read(_isequal, _testandlock);  
  if (rt != NOERR)
    return error_box("Impossibile leggere i dati: errore %d", rt);
  
  if (lok)
  {  
    if (rt != NOERR)              
    {
      if (rt == _islocked)                                            
        return message_box("I dati sono gia' in uso ad un altro programma.");  
    }
    
    const bool in_uso = base.get_bool("IN_USO");
  
    if (in_uso)
      return message_box("I dati sono gia' in uso ad un altro programma");    
    else
    {
      base.put("IN_USO", "X");
      const int rewr = base.rewrite();
#ifdef DBG  
      if (rewr != NOERR)
        return message_box("Rewrite fallita errore %d.", rewr);
#endif    
    }                      
  }
// Release lock  
  else
  {
    base.put("IN_USO", " ");
    const int rewr = base.rewrite();
#ifdef DBG  
    if (rewr != NOERR)
      return message_box("Rewrite fallita errore %d", rewr);
#endif    
  }  
  base.reread(_unlock);
  return TRUE;
}


// Forza la rilettura dei quadri compilati
bool TManutenzione_quadri::leggi_quadri(TMask_field& f, KEY k)
{
  if (k == K_TAB)
	{
		app().init_menu(f.mask());
    xvt_statbar_set(""); // serve per ripristinare la statusbar 
  }  
  return TRUE;
}

void TManutenzione_quadri::init_query_mask(TMask& m)
{
  m.set(F_ANNODIC, _anno_dic);
}

bool TManutenzione_quadri::main_loop()
{
  KEY tasto = K_TAB;

  while (tasto != K_QUIT) 
  { 
               
// eseguo la prima maschera (richiesta codice ditta) solo la prima volta,
// oppure quando esco dal menu manutenzione quadri con "Annulla"    
  	if (tasto != K_ESC) 
  	{                 
    	if (!query_mask()) 
     	 return FALSE;
// Disabilita cambio ditta
   	  enable_menu_item(M_FILE_NEW, FALSE);
// Disabilita cambio parametri
    	enable_menu_item(M_FILE_REVERT, FALSE); 
// Impegna ditta    	
   	  if (!lock(TRUE))
     	 continue;        
// carico la maschera di manutenzione quadri      
   	  load_mask(1);
   	  _msk[1]->autoload(*_rel);       
      init_menu(*_msk[1]);  
      _msk[1]->open_modal();     	 
    }                                             
    
// eseguo la maschera di manutenzione quadri      
    tasto = _msk[1]->run();
    
    switch (tasto)
    {
      case K_ESC : 
// forzo l'esecuzione dell'handler del bottone "Annulla" 
// se ritorna false significa che era attivo il menu principale
// e quindi permetto la riesecuzione della maschera di richiesta ditta          
      	if (!(hide_menu(_msk[1]->field(DLG_CANCEL), K_SPACE)))
      	{
      		tasto = K_TAB;   
      		lock(FALSE);      // release lock
      		_msk[1]->close_modal(); // chiude maschera
      	}	
      	break;
      case K_QUIT : 
   		  lock(FALSE);      // release lock
   		  _msk[1]->close_modal(); // chiude maschera 
   		  break;     		
      case K_SAVE :
        break;
      default:
        break;
    }
  
  } 

  return FALSE;
}

bool TManutenzione_quadri::menu(MENU_TAG m)
{
  if (m == BAR_ITEM(1))
    return main_loop(); 
  return FALSE;
}

bool TManutenzione_quadri::query_mask()
{
  load_mask(0);
  init_query_mask(*_msk[0]);    
  _msk[0]->first_focus(DLG_OK);
  KEY ch = _msk[0]->run();        
  if (ch == K_ENTER)
  	_codditta = _msk[0]->get_long(F_CODDITTA);
  return ch == K_ENTER;
}

int MenuQuadri (int argc, char* argv[])
{
  TManutenzione_quadri a;
  a.run(argc, argv, "Manutenzione dichiarazione");
  return 0;
}