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

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

  _last_choice = BAR_ITEM_ID(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()
{
  _cnf->set_paragraph(""); // Flush
  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_ID(1) && m <= BAR_ITEM_ID(20))
  {
    _last_choice = m;
    do_config((m - BAR_ITEM_ID(0))/100);
  }
  return xvtil_test_menu_tag(BAR_ITEM_ID(2));
}

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

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


void TConfig_application::save_mask(bool tosave) 
{
  TMask* mask = get_mask();
  if (mask==NULL) return;
  const int max = mask->dirty() ? mask->fields() : 0;
  for (int i = 0; i < max; i++)
  {
    TMask_field& f = mask->fld(i);
    if (f.field())
    {
      const char* fname = f.field()->name();
      const TString& 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))
      {
        if (value[0] == ' ' || value.right(1) == " ")
        {
          TString val;
          val << '"' << value << '"';
          _cnf->set(fname, val, NULL, TRUE, index > -1 ? index : -1); 
        }
        else          
          _cnf->set(fname, value, NULL, TRUE, index > -1 ? index : -1); 
      }  
    }
  }
}


void TConfig_application::load_mask()
{                    
  TMask* mask = get_mask();
  if (mask==NULL) return;
  const int max = mask->fields();
  TString oldvl;
  for (int i = 0; i < max; i++)
  {                    
    TMask_field& f = mask->fld(i);
    if (f.field() != NULL)
    {
      const TFieldref* fr = f.field();
      const char* fname = fr->name();
      const int index = fr->to();
      oldvl = _cnf->get(fname,NULL, index > -1 ? index : -1);
      if (oldvl[0] == '"' && oldvl.right(1) == "\"")
      {
        oldvl.rtrim(1);
        oldvl.ltrim(1);  
      }
      f.set(oldvl);
    }  
  }
}

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

TMask* TConfig_application::create_mask(const TFilename& f) 
{ 
  if (_m != NULL)
    destroy_mask();
  _m = new TMask(f); 
  return _m;
}

const char* TConfig_application::get_mask_name() const
{
  TString& maskname = get_tmp_string();
  maskname = _cnf->get("EdMask"); 
  return maskname;
}


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

  load_config();
  for (;;)
  {
    TFilename maskname = get_mask_name();
    maskname.ext("msk");
      
    if (maskname.not_empty() && maskname.exist())
    {
      TMask* mask = get_mask();
      if (mask == NULL || mask != _m) 
        mask = create_mask(maskname);
      
      // carica campi
      load_mask();
      // run mask
      if (!preprocess_config(*mask,*_cnf)) 
        break;

      int k = mask->run();
      if (postprocess_config(*mask,*_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() 
{
}