#include <defmask.h>
#include <diction.h>
#include <dongle.h>
#include <prefix.h>
#include <progind.h>
#include <relation.h>
#include <sheet.h>

#include "ba1100.h"

bool TEdit_file::_browse(TCursor& cursor, const TFilename& name)
{
  TRectype& curr = cursor.curr();
  TRectype svrec(cursor.curr());
  
  TToken_string head(256);
  TToken_string trac(256);
  
  const char* n;
  trac.add("");
  head.add("@1");

  for(int i = 0; (n = curr.fieldname(i)) != NULL; i++)
  {
    trac.add(n);
    
    TString16 name(n); name.lower(); name[0] = toupper(name[0]);
    head.add(name);
    
    const TFieldtypes t = curr.type(n);
    int len = 0;
    switch (t)
    {
    case _datefld: len = 10; break;
    case _memofld: len = 50; break;
    default      : len = curr.length(n); break;
    }  
    head << '@' << max(len, (int)strlen(n));
    if (t == _realfld || t == _intfld || t == _longfld || t == _wordfld || t == _realfld) 
      head << 'R';
  }

  const bool superprassi = user() == ::dongle().administrator();
  
  KEY ch;
  TCursor_sheet sheet(&cursor, trac, name, head, superprassi ? 6 : 0);

  while ((ch = sheet.run()) != K_ESC)
  {     
    if (!superprassi)
    {            
      error_box(FR("Funzione non ammessa per l'utente %s"), (const char*)user());
      ch = K_ESC;
    }
    
    if (ch == K_DEL && sheet.one_checked())
    {
      TProgind* pind = NULL;
      cursor.freeze(TRUE);
      bool go = FALSE;
      bool first = FALSE;
      long j;
      const long items   = sheet.items();
      const long checked = sheet.checked();
      if (checked && yesno_box(FR("Si desidera cancellare i %ld record indicati?"), checked))
      {
        TWait_cursor hourglass;
        for (j = 0, cursor = 0; j < items; j++)
        {
          if (sheet.checked(j))
          {
            if (!pind)
            {
              pind = new TProgind(sheet.checked(),TR("Attendere..."), TRUE, TRUE);
              pind->addstatus(1);
            }
            else 
            {
              if (pind->iscancelled()) break;
              pind->addstatus(1);
            }  
  
            cursor = j;
            cursor.file().remove();
            sheet.uncheck(j);
          }
        }
      }
      if (pind) delete pind;
      cursor.freeze(FALSE);
      
      // Forza update del cursore
      cursor.set_filterfunction(NULL, TRUE);
      if (cursor.items() > 0)
        sheet.select(1);
      continue;
    }
    if (ch == K_ENTER || ch == K_DEL) 
    { 
      if (cursor.items() > 0)
        cursor = sheet.selected();
    }  
    
    switch(ch)
    {
    case K_ENTER:  // edit fields
      svrec = curr;
      if (edit_record(curr, FALSE) == K_ENTER)
      {
        const TString s(svrec.key(1));
        if (s != curr.key(1))
        {
          const int err = curr.write(cursor.file());
          if (err == NOERR)
            svrec.remove(cursor.file());
        }
        else
          curr.rewrite(cursor.file());
      }
      break;
    case K_DEL:    // delete record
      if (yesno_box(TR("Confermare la cancellazione del record")))
        cursor.file().remove();
      break;
    case K_INS:    // insert new record
      curr.zero();
      if (edit_record(curr,FALSE) == K_ENTER)
        cursor.file().write();
      break;
    default:
      break;  
    }
    sheet.force_update();
  }
  return ch != K_ESC;
}

bool TEdit_file::browse(int logicnum, const TFilename& name, const TString& tab)
{
  if (logicnum > 2)
  {
    TSystemisamfile test(logicnum);
    int err = test.open_ex();
    if (err != NOERR)
      return error_box(FR("Impossibile aprire il file %d: errore %d"), logicnum, err);
    test.close();
  }


  TRelation relation(logicnum);
  TCursor cursor(&relation);
  if (logicnum == LF_TAB || logicnum == LF_TABCOM || logicnum == LF_TABGEN) 
  {
    if (tab.len() == 3)  // Filtra la tabella interessata
    {
      TRectype filter(logicnum);
      filter.put("COD", tab);
      cursor.setregion(filter, filter);
    }  
  }  
  return _browse(cursor,name);
}

bool TEdit_file::browse(TExternisamfile* file, const TFilename& name)
{
  TRelation relation(file);
  TCursor cursor(&relation);
  
  return _browse(cursor,name);
}

KEY  TEdit_file::edit_record(TRectype& rec, bool readonly)
{
  for(int recs = 0; rec.fieldname(recs) != NULL; recs++);
  
  const int fpp = 16;                               // Fields per page
  const int rows  = recs > fpp ? 20 : recs+4;
  const int pages = recs/fpp + (recs % fpp ? 1 : 0);
  TMask m(TR("Modifica record"), pages, 78, rows);
  if (pages > 1) m.add_default_tag_buttons();
  
  int curpage = 0, currow = 1, nid = 100;
  const char* cp;
  int mcnt =0;
  
  const char* flags = readonly ? "D" : "";
  
  for(int i = 0; (cp = rec.fieldname(i)) != NULL; i++)
  {
    // add fields ONE by ONE
    TString16 s(cp); s.left_just(16);
    const int len = rec.length(cp);
    switch (rec.type(cp))
    {
    case _alfafld:
      {
        TString16 f; f << flags << '_';
        m.add_string(nid++,curpage, s, 3, currow, len, f, len > 50 ? 50 : len);
      }
      break;
    case _intfld:
    case _longfld:
    case _wordfld:
    case _realfld:
      m.add_number(nid++, curpage, s, 3, currow, len, flags, rec.ndec(cp));
      break;
    case _datefld:
      m.add_date(nid++, curpage, s, 3, currow, flags);
      break;
    case _charfld:
      m.add_string(nid++, curpage, s, 3, currow, 1, flags);
      break;
    case _boolfld:
      m.add_boolean(nid++, curpage, s, 3, currow, flags);
      break;
    case _intzerofld:
    case _longzerofld:                                 
      {
        TString16 f; f << flags << 'Z';
        m.add_number(nid++, curpage, s, 3, currow, len, f, 0);
      }  
      break;
    case _memofld:
      m.add_zoom( nid++, curpage, s, 3, currow, 50, flags, 50 );
      break;
    default:
      break;
    }
    
    m.field(nid-1).set(rec.get(cp));
    
    if (((i+1) % fpp) == 0 || i == recs-1) 
    { 
      m.add_button(DLG_OK, curpage, "", -12, -1, 9, 2);
      m.add_button(DLG_CANCEL, curpage, "", -22, -1, 9, 2);
      curpage++; currow = 1;
    }
    else currow++;
  }

  const KEY k = m.run();
  if (k == K_ENTER && !readonly)
  {
    nid = 100;
    for(i = 0; (cp = rec.fieldname(i)) != NULL; i++)
      rec.put(cp, m.get(nid++));
  }

  return k;
}