#include <confapp.h>
#include <mask.h>
#include <relation.h>
#include <urldefid.h>

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

  _last_choice = BAR_ITEM(1);

  // process args
  TString arg(16);
  for (int i = 0; i < argc(); i++)
  {
    arg = argv(i);
    if (arg == "-c")
      set_config(atoi(argv(++i)));
    else
      if (arg[0] == '-')
        continue;
      else
        _paragraphs.add(arg);
  }

  user_create();
  dispatch_e_menu(_last_choice);
  return TRUE;
}

bool TConfig_application::destroy()
{
  bool b = user_destroy();
  if (_m) delete _m;
  if (_cnf) delete _cnf;
  TApplication::destroy();
  return b;
}

bool TConfig_application::menu(MENU_TAG m)
{
  // funziona da se' fino a 20 voci della menubar
  if (m >= BAR_ITEM(1) && m <= BAR_ITEM(20))
  {
    _last_choice = m;
    do_config((m - BAR_ITEM(0))/100);
  }
  return xvt_test_menu_tag(BAR_ITEM(2));
}

bool TConfig_application::user_create()  
{ 
  return TRUE; 
}

bool TConfig_application::user_destroy() 
{ 
  return TRUE; 
}


void TConfig_application::save_mask(bool tosave) 
{
  if (_m==NULL) return;
  const int max = _m->dirty() ? _m->fields() : 0;
  for (int i = 0; i < max; i++)
  {
    TMask_field& f = _m->fld(i);
    if (f.dirty() && f.field())
    {
      const char* fname = f.field()->name();
      const char* value = f.get();
      const int index = f.field()->to();
      const char* oldvl = _cnf->get(fname);
                
      if (!tosave)
        tosave = yesno_box("Modifiche non registrate. Salvare?");
                
      if (!tosave) break;
                
      if (postprocess_config_changed(_parag, fname, oldvl, value))
        _cnf->set(fname, value, NULL, TRUE, index > -1 ? index : -1); 
    }
  }
}


void TConfig_application::load_mask()
{                    
  if (_m==NULL) return;
  const int max = _m->fields();
  for (int i = 0; i < max; i++)
  {                    
    TMask_field& f = _m->fld(i);
    if (f.field() != NULL)
    {
      const TFieldref* fr = f.field();
      const char* fname = fr->name();
      const int index = fr->to();
      TString& oldvl = _cnf->get(fname,NULL, index > -1 ? index : -1);
      f.set(oldvl);
    }  
  }
}

void TConfig_application::load_config()
{
  if (_cnf) delete _cnf;
  _cnf = new TConfig(_which_config, _parag);
}

void TConfig_application::do_config(int m)
{
  TString _parag(name()); 
  if (m < _paragraphs.items())
    _parag = (TString&)_paragraphs[m];
  else _parag.cut(2); 

  load_config();
  for (;;)
  {
    
    const TFilename maskname(_cnf->get("EdMask"));
    if (!maskname.empty())
    {
      if (_m) delete _m;
      _m= new TMask(maskname);
      
      // carica campi
      load_mask();
      // run mask
      if (!preprocess_config(*_m,*_cnf)) 
        break;

      int k = _m->run();
      if (postprocess_config(*_m,*_cnf))
      {
        bool tosave = k == K_ENTER || k == K_SAVE;
        
        if (k == K_ENTER || k == K_QUIT)
        {
          // aggiusta campi
          save_mask(tosave);
        }
        else break;  
      }  
      if (k == K_QUIT) 
        break;
    }
    else 
    {
      warning_box("Nessun parametro da configurare");
      break;
    }
  }
}

void TConfig_application::on_firm_change()
{
  ((TConfig_application *)this)->save_mask(FALSE);
  load_config();
  load_mask();
}



void TConfig_application::set_config(int which) 
{
  _which_config= which;

}

bool TConfig_application::preprocess_config (TMask& mask, TConfig& config)
{ 
  return TRUE;
}

bool TConfig_application::postprocess_config (TMask& mask, TConfig& config)
{ 
  return TRUE;
}

// @doc EXTERNAL

// @mfunc Simile alla <mf TApplication::change_config>, ma viene usata 
//        dalla maschera principale.
//
// @rdesc Ritorna i seguenti valori:
//
// @flag TRUE | Se la modifica viene acettatta (dafault)
// @flag FALSE | Se la modifica non viene accettata
bool TConfig_application::postprocess_config_changed(
     const char* par,  // @parm Paragrafo in corso di editing
     const char* var,  // @parm vedi <c TApplication>
     const char* oldv, // @parm vedi <c TApplication>
     const char* newv) // @parm vedi <c TApplication>

// @comm Rispetto alla <mf TApplication::change_config> le viene passato in piu' il paragrafo
//       in corso di editing. E' chiamata per ogni parametro modificato.

{
  return TRUE; 
}

TConfig_application::TConfig_application(int which_config) 
  : _cnf(NULL), _m(NULL)
{
  set_config(which_config);
}

TConfig_application::~TConfig_application() 
{
}