#include "ab3100.h"

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

bool gestione_sheet(TSheet_field& s, int r, KEY k)
{
  if (k == K_CTRL + K_INS)
  {
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TToken_string &codice = s.row(r-1);
    ab_tree.insert_new_node(codice);
    ab_tree.user_tree()->write_cache(); //solo debug
    ab_tree.user_tree_voc()->write_cache(); //solo debug
    // Sincronizzo l'albero con lo sheet
    ab_tree.user_tree()->goto_father();
    naviga_tree(s.mask().field(F_TREE),K_SPACE);
    
    TMask &s_msk = s.sheet_mask();
    s_msk.field(F_COMPONENTE).on_key(K_F9);
    const TString &componente = s_msk.get(F_COMPONENTE);
    s.row(r).add(componente,F_COMPONENTE-F_ID);
    k = K_ENTER;
  }
  
  if (k == K_DEL)
  {    
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TToken_string &codice = s.row(r);
    //Posiziono il nodo sul record selezionato
    TNumeric_id temp_id = codice.get(0);
    ab_tree.remove_node(temp_id);
    ab_tree.user_tree()->goto_father();
  }

/*  if ( k = K_CTRL + K_DEL) 
  {
    // Sincronizzo l'albero con lo sheet come risposta alla rimozione
    naviga_tree(s.mask().field(F_TREE),K_SPACE);
  } */

  if (k == K_ENTER)
  {
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TMask &msk = s.sheet_mask();
    
    // A questo punto devo modificare il contenuto di CARADD:
    // ricavo il suo contenuto da maschera, e lo scrivo nella cache
    // se il nodo � stato rimosso, la caradd non viene rimossa dal database: per 
    // rimuoverla fare i passi successivi in K_DEL
    
    TRectype caradd(ricava_caradd(msk));
    ab_tree.user_caradd()->current_cache_record().put(caradd);
    ab_tree.user_caradd()->set_status_node(caradd.get(ABCA_ID),NODO_MODIFICATO);
    ab_tree.user_caradd()->write_cache();   //solo debug
    
//    TRectype coll(ricava_colldich(msk));
//    ab_tree.user_colldich()->current_cache_record().put(coll);
//    ab_tree.user_colldich()->set_status_node(coll.get(ABCD_ID),NODO_MODIFICATO);
//    ab_tree.user_colldich()->write_cache();   //solo debug
    
    TToken_string &codice = s.row(r);
    ab_tree.modify_node(codice);
    // Sincronizzo l'albero con lo sheet
    ab_tree.user_tree()->goto_father();
    naviga_tree(s.mask().field(F_TREE),K_SPACE);
  }
  return TRUE;
}    

bool naviga_tree(TMask_field& f, KEY k)
{
  if (k == K_SPACE)
  { //Premuto su un nodo
    TTree_field &tf = (TTree_field&)f;  //Trasformo il contenuto del campo in un tree
    TMask &_msk=f.mask();      //Prelevo la maschera
    TSheet_field &sheet_box = _msk.sfield(F_VISTA);  //Creo un array che conterr� i dati dello sheet
    sheet_box.destroy(-1,FALSE);    // ... e lo vuoto
    TLocalisamfile voci(LF_VOCI);
    TAlbero_locale *ab = (TAlbero_locale*)tf.tree();
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TToken_string key_rel;
    TString father_id;
    ab->curr_id(father_id);   //Salvo l'id del padre
    TNumeric_id temp_id;  // Serve per la navigazione dei figli
    temp_id = ab->current().get_real(ABRA_IDFIGLIO);
    if (temp_id > ID_NULLO)
    { // Significa che ho dei figli
      for (int i = 0; temp_id > ID_NULLO; i++ )
      {
        TToken_string &codice = sheet_box.row(i); //Setto la riga dell sheet
        ab->goto_node(temp_id);   //vado sul nodo
        ab->curr_id(codice);
        codice.add(ab->current().get(ABRA_TIPOCOD));
        codice.add(ab->current().get(ABRA_CODVC));
        codice.add(ab->current().get(ABRA_NCOMP));
        codice.add(ab->current().get(ABRA_VOCEINCID));
        codice.add(ab->current().get(ABRA_DESCRIZ));
        codice.add(ab->current().get(ABRA_USACARADD));
  
        // Rintraccio i dati di RELVOCI
        key_rel.cut(0);
        key_rel.add(ab->current().get(ABRA_TIPOCOD));
        key_rel.add(ab->current().get(ABRA_CODVC));
        key_rel.add(ab->current().get(ABRA_NCOMP));
        ab_tree.user_tree_voc()->goto_node(key_rel);
        
        // Rintraccio i dati di VOCI
        voci.put(ABVC_CODVC,ab_tree.user_tree_voc()->current().get(ABRL_CODCOMP));
        
        if (voci.read() == NOERR)
        {              
          codice.add(voci.get(ABVC_CODVC));
          if ( ab->current().get_bool(ABRA_USACARADD) )
          { // Se il nodo esisteva gi�, ci sar� anche la caradd;
            // se il nodo � nuovo, la caradd la devo aggiungere
            TNumeric_id id_caradd(ab->current().get(ABRA_IDCARADD));   // Caratteristica addizionale ridefinita
            if (id_caradd != ID_NULLO)
            { // Esiste gi� una caradd specifica definita
              codice.add(id_caradd.string());
            }
            else
            { // Devo trovare un nuovo id per la nuova caradd
              id_caradd = ab_tree.new_id_caradd();
              codice.add(id_caradd.string());
            }
          }
          else
          { // Uso la caradd di default
            codice.add(voci.get(ABVC_IDCARADD));            // Caratteristiche addizionali di default
          }
//          sheet_box.disable_cell(i,7); 
//          sheet_box.disable_cell(i,8);
        }
        else
        { 
          ;
        }  
        sheet_box.check_row(i);
        temp_id = ab->current().get_real(ABRA_IDSUCC);
      } // Ho finito di scorrere (e visualizzare) tutti i figli
      //Riposiziono il nodo e aggiorno lo sheet
      ab->goto_node(father_id);
      sheet_box.force_update();
    }
    else                          
    {
      sheet_box.destroy(-1,FALSE);
    }
    return TRUE;
  }             
  return TRUE;
}

TRectype ricava_colldich(TMask & msk)
{
  TRectype coll (LF_COLLDICH);
  TString id = msk.get(F_ID_COLL);
  // FARE LA SERIE DI PUT COME NELLA RICAVA CARADD
  return coll;
}


TRectype ricava_caradd(TMask & msk)
{
  TRectype car (LF_CARADD);
  TString id = msk.get(F_IDCARADD);
  car.put(ABCA_ID,id.right_just(12,' '));
  car.put(ABCA_STD,msk.get(F_STAMPA_DETT));
  car.put(ABCA_CLI,msk.get(F_COL_STM_IMP));
  car.put(ABCA_SPI,msk.get(F_CAR_SOPRA));
  car.put(ABCA_STI,msk.get(F_CAR_SOTTO));
  car.put(ABCA_DST,msk.get(F_DESCR_TOT));
  car.put(ABCA_CLT,msk.get(F_COL_STM_TOT));
  car.put(ABCA_SPT,msk.get(F_CAR_SOPRA_TOT));
  car.put(ABCA_STT,msk.get(F_CAR_SOTTO_TOT));
  car.put(ABCA_SVT,msk.get(F_STAMPA_IMP_TOT));
  car.put(ABCA_LST,msk.get(F_LIV_STR));
  car.put(ABCA_ODA,msk.get(F_FLAG_DA));
  car.put(ABCA_SKI,msk.get(F_LINEA_SALTA_SMP));
  car.put(ABCA_SKT,msk.get(F_LINEA_SALTA_TOT));
  car.put(ABCA_NDV,msk.get(F_NON_DSR_VOC_COM));
  car.put(ABCA_RII,msk.get(F_RIGA_GRASS));
  car.put(ABCA_RIT,msk.get(F_RIGA_TOT_VC_CMP));
  car.put(ABCA_TVL,msk.get(F_TVL));
  
  return car;
}

void aggiorna_colldich(TMask &msk)
{
  TLocalisamfile coll(LF_COLLDICH);
  coll.put(ABCD_ID,msk.get(F_ID_COLL));
  
  if (coll.read() != NOERR)
  {
    coll.curr().zero();
  }
  // FARE LA SERIE DI SET DAI CAMPI DELLA MASCHERA COME NELLA AGGIORNA_CARADD
}

void aggiorna_caradd(TMask &msk)
{
  TLocalisamfile car(LF_CARADD);
  car.put(ABCA_ID,msk.get(F_IDCARADD));
  
  if (car.read() != NOERR)
  {
    car.curr().zero();
  }
  
  msk.set(F_STAMPA_DETT,car.get(ABCA_STD));
  msk.set(F_COL_STM_IMP,car.get(ABCA_CLI));
  msk.set(F_CAR_SOPRA,car.get(ABCA_SPI));
  msk.set(F_CAR_SOTTO,car.get(ABCA_STI));
  msk.set(F_DESCR_TOT,car.get(ABCA_DST));
  msk.set(F_COL_STM_TOT,car.get(ABCA_CLT));
  msk.set(F_CAR_SOPRA_TOT,car.get(ABCA_SPT));
  msk.set(F_CAR_SOTTO_TOT,car.get(ABCA_STT));
  msk.set(F_STAMPA_IMP_TOT,car.get(ABCA_SVT));
  msk.set(F_LIV_STR,car.get(ABCA_LST));
  msk.set(F_FLAG_DA,car.get(ABCA_ODA));
  msk.set(F_LINEA_SALTA_SMP,car.get(ABCA_SKI));
  msk.set(F_LINEA_SALTA_TOT,car.get(ABCA_SKT));
  msk.set(F_NON_DSR_VOC_COM,car.get(ABCA_NDV));
  msk.set(F_RIGA_GRASS,car.get(ABCA_RII));
  msk.set(F_RIGA_TOT_VC_CMP,car.get(ABCA_RIT));
  msk.set(F_TVL,car.get(ABCA_TVL));
}

bool aggiorna_id_colldich(TMask_field& f, KEY k)
{   
  if ((k==K_SPACE) && (f.dlg() == F_USA_COLL) && (f.focusdirty()))
  {
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TMask &sheet_msk = f.mask();
    if (sheet_msk.get_bool(F_USA_COLL))
    {
      ab_tree.user_tree()->goto_node(sheet_msk.get(F_ID));
      TNumeric_id id_coll(ab_tree.user_tree()->current().get(ABRA_IDCOLDICH));  // id del collegamento a dich.
      if (id_coll != ID_NULLO)
      {
        //Rintraccio il collegamento
        sheet_msk.set(F_ID_COLL,id_coll);
      }
      else
      {
        //Devo reperire un id disponibile
        id_coll = ab_tree.new_id_colldich();
        sheet_msk.set(F_ID_COLL,id_coll);
      }
      // Aggiorno la maschera dei collegamenti a dich.
      aggiorna_colldich(sheet_msk);
      return TRUE;
    }
  }
  return TRUE;
}



bool aggiorna_id_caradd(TMask_field& f, KEY k)
{
  if (((k==K_TAB) && (f.focusdirty()) && (f.dlg()==F_COMPONENTE))
    || ((k==K_SPACE) && (f.dlg() == F_USA_CARADD) && (f.focusdirty())))
  {
    TRelation *rel = app().get_relation();
    TAnalisi_bil &ab_tree = (TAnalisi_bil&)rel->curr();
    TMask &sheet_msk = f.mask();
    
    if (sheet_msk.get_bool(F_USA_CARADD))
    { //CARADD NON DI DEFAULT
      ab_tree.user_tree()->goto_node(sheet_msk.get(F_ID));
      
      TNumeric_id id_caradd(ab_tree.user_tree()->current().get(ABRA_IDCARADD));   // Caratteristica addizionale ridefinita
      if (id_caradd != ID_NULLO)
      { // Esiste gi� una caradd specifica definita
        sheet_msk.set(F_IDCARADD,id_caradd);
      }
      else
      { // Devo trovare un nuovo id per la nuova caradd
        id_caradd = ab_tree.new_id_caradd();
        sheet_msk.set(F_IDCARADD,id_caradd);
      }
    }
    else
    { //CARADD DI DEFAULT  
      TLocalisamfile voci(LF_VOCI);
      // Rintraccio i dati di VOCI
      voci.put(ABVC_CODVC,sheet_msk.get(F_COMPONENTE));
      if (voci.read() == NOERR)
      {
        sheet_msk.set(F_IDCARADD,voci.get(ABVC_IDCARADD));
      }
      else
      {
        error_box (TR("Voce non presente nell'archivio voci"));
      }
    }
    aggiorna_caradd(sheet_msk);
    return TRUE;
  }
  return TRUE;
}




bool TGestione_tree::user_create()
{
  _msk = new TMask("ab3100a");
  _anas = new TRelation(LF_ANALISI);
  TAnalisi_bil *tree = new TAnalisi_bil();  
  
  _anas->lfile().set_curr(tree);
  
  TTree_field & tf = (TTree_field&)_msk->field(F_TREE);
  tf.set_tree(tree->user_tree());
  tf.hide_leaves();       //Nasconde le foglie dell'albero
  TSheet_field &sheet = _msk->sfield(F_VISTA);  //Creo un array che conterr� i dati dello sheet
  _msk->set_handler(F_TREE, naviga_tree);
  sheet.set_append(FALSE);
  sheet.sheet_mask().set_handler(F_COMPONENTE,aggiorna_id_caradd);
  sheet.sheet_mask().set_handler(F_USA_CARADD,aggiorna_id_caradd);
  sheet.sheet_mask().set_handler(F_USA_COLL,aggiorna_id_colldich);

  sheet.set_notify(gestione_sheet);
  return TRUE;
}

bool TGestione_tree::user_destroy()
{             
  delete _anas;
  delete _msk;

  return FALSE;
}


void ab3100(int argc, char **argv)
{
  TGestione_tree a;
  a.run(argc,argv, TR("Gestione dati"));
}