// 776100.cpp - Menu' manutenzione quadri
#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 = 26;
HIDDEN const int QUADRO_L	= 30;

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;
    
  protected:
    virtual bool create();
    virtual bool destroy();
    virtual bool menu(MENU_TAG m);
    virtual void on_config_change();

    static void show_menu(TMask& m, const int group, bool mostra);
    static bool filtra_ditte(const TRelation * r);
    static bool menu_stampe        (TMask_field& fld, KEY k);
    static bool cancel_menu_stampe (TMask_field& fld, KEY k);
    static bool menu_dich          (TMask_field& fld, KEY k);
    static bool cancel_menu_dich   (TMask_field& fld, KEY k);
    static bool menu_anagrafici    (TMask_field& fld, KEY k);
    static bool cancel_menu_anagrafici (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() {};
};

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());
}
                                    
// 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");

  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 A-1"  ;
      break;
    case 2:
      __tmp << "Quadro A-2";
      break;
    case 3:
      __tmp << "Quadro A-3"  ;
      break;
    case 4:
      __tmp << "Quadro B"  ;
      break;
    case 5:
      __tmp << "Quadro B-1";
      break;
    case 6:
      __tmp << "Quadro C"  ;
      break;
    case 7:
      __tmp << "Quadro D"  ;
      break;
    case 8:
      __tmp << "Quadro D-1";
      break;
    case 9:
      __tmp << "Quadro E"  ;
      break;
    case 10:
      __tmp << "Quadro E-1";
      break;
    case 11:
      __tmp << "Quadro E-2";
      break;
    case 12:
      __tmp << "Quadro F"  ;
      break;
    case 13:
      __tmp << "Quadro F-1";
      break;
    case 14:
      __tmp << "Quadro F-2";
      break;
    case 15:
      __tmp << "Quadro G"  ;
      break;
    case 16:
      __tmp << "Quadro G-1";
      break;
    case 17:
      __tmp << "Quadro H"  ;
      break;
    case 18:
      __tmp << "Quadro I"  ;
      break;
    case 19: 
      __tmp << "Quadro N"  ;
      break;
    case 20:
      __tmp << "Quadro P"  ;
      break;
    case 21:
      __tmp << "Quadro Q"  ;
      break;
    case 22:
      __tmp << "Quadro R"  ;
      break;
    case 23:
      __tmp << "Quadro S"  ;
      break;
    case 24:
      __tmp << "Quadro T"  ;
      break;
    case QUADRO_L:
      __tmp << "Quadro L"  ;
      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;
  
  for (int i = 0; i < NUM_QUADRI; i++)
    if (qric[i] == 'X')
    {
      dlg = start_dlg + (i * 2);
      m.field(dlg).disable();
    }
}

//
// Metto in grassetto  i quadri gia' compilati
// 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;
  const int     L = 19;
  int   dlg         = 0;
  
  for (int i = 0; i < L; i++)
  {
    dlg = start_dlg + (i * 2);                 
    prompt = make_prompt(i, qcomp[i] == 'X' ?  grassetto : piano);
    m.field(dlg).set_prompt(prompt);
  }

  prompt = esiste_record_L(get_firm_770(), _anno_dic) ? 
                           make_prompt(QUADRO_L, grassetto) : 
                           make_prompt(QUADRO_L, piano);  
                           
  dlg = start_dlg + (i * 2);                 
  m.field(dlg).set_prompt(prompt);
  
  for (i = L+1; i < NUM_QUADRI; i++)  
  {
    int   dlg = start_dlg + (i * 2);                 
// Controlla qcomp[i-1] perche' in QCOMP non c'e' il flag del quadro L
    prompt = make_prompt(i-1, qcomp[i-1] == 'X' ? grassetto : piano);
    m.field(dlg).set_prompt(prompt);
  }
}

void TManutenzione_quadri::show_menu(TMask& m, const int group, bool mostra)
{
  if (mostra)
  {
    m.hide(-1);   
    m.hide(DLG_NULL_SOCI);    
    m.hide(DLG_MANUTENZ_SOCI);    
    m.show(group);              
  } 
  else
  {
    m.hide(group);   
    m.show(-1);     
    m.show(DLG_NULL_SOCI);        
    m.show(DLG_MANUTENZ_SOCI);        
    m.enable(DLG_NULL_SOCI,     app()._soci);        
    m.enable(DLG_MANUTENZ_SOCI, app()._soci);        
  }
}

bool TManutenzione_quadri::menu_dich(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
    show_menu(f.mask(), -4, TRUE);
  return TRUE;
}

bool TManutenzione_quadri::cancel_menu_dich(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
    show_menu(f.mask(), -4, FALSE);
  return TRUE;
}

bool TManutenzione_quadri::menu_anagrafici(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
    show_menu(f.mask(), -2, TRUE);
  return TRUE;
}

bool TManutenzione_quadri::cancel_menu_anagrafici(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
    show_menu(f.mask(), -2, FALSE);
  return TRUE;
}

bool TManutenzione_quadri::menu_stampe(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
    show_menu(f.mask(), -3, TRUE);
  return TRUE;
}

bool TManutenzione_quadri::cancel_menu_stampe(TMask_field& f, KEY k)
{
  if (k == K_SPACE)               
    show_menu(f.mask(), -3, 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_NULL_SOCI,     _soci); 
  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);
  
// Fa uscire/entrare il menu' dati anagrafici
  m.set_handler(DLG_MANUTENZ,    menu_anagrafici);
  m.set_handler(DLG_CANCEL_MENU, cancel_menu_anagrafici);

// Fa entrare e uscire il menu' STAMPE
  m.set_handler(DLG_STOPREC_ST,     menu_stampe);
  m.set_handler(DLG_CANCEL_MENU_ST, cancel_menu_stampe);
  
// Fa entrare e uscire il menu' SOGG. DICHIARANTE
  m.set_handler(DLG_STOPREC_SD,     menu_dich);
  m.set_handler(DLG_CANCEL_MENU_SD, cancel_menu_dich);

// 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", (long)_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",(long)_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());
  return TRUE;
}

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

bool TManutenzione_quadri::main_loop()
{
  KEY tasto;

  do  {                     
    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);

    if (!lock(TRUE))
      continue;
      
    load_mask(1);
    _msk[1]->autoload(_rel);       

    init_menu(*_msk[1]);

    tasto = _msk[1]->run();
    
    switch (tasto)
    {
      case K_ESC :
      case K_QUIT :
      case K_SAVE :
        break;
      default:
        break;
    }
  
    lock(FALSE);  // release lock
  
  } while (tasto != K_QUIT);                              

  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();        
  _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;
}
