#include <automask.h>
#include <modaut.h>
#include <printer.h>
#include <tabapp.h>

#include "velib.h"
#include "../ca/calib01.h"

#include "vetbatr.h"
#include "vetbgmc.h"
#include "vetbnum.h"
#include "vetbprs.h"
#include "vetbrss.h"
#include "vetbspp.h"

#define TAB_GRMERC      "GMC"

///////////////////////////////////////////////////////////
// TVendite_mask
///////////////////////////////////////////////////////////

class TVendite_mask : public TAutomask
{
  TString4 _tab;  // Voglio la tabella sempre sotto mano

protected:
  virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);

  bool is_table(const char* tab) const { return _tab == tab; }
  
  void get_printer_config(TString& name) const;
  bool get_printer_name(TString& name) const;
  void reset_printer_config() const;

  bool on_num_event(TOperable_field& o, TField_event e, long jolly);

public:
  const TString& table_code() const { return _tab; }

  TVendite_mask(const char* name);
  virtual ~TVendite_mask() { }
};

void TVendite_mask::get_printer_config(TString& config) const
{
  config = _tab;  
  for (TEditable_field* f = get_key_field(1, TRUE); f; f = get_key_field(1, FALSE)) 
  {
    if (f->shown())
      config << f->get();
  }
}

bool TVendite_mask::get_printer_name(TString& name) const
{
  TString config; get_printer_config(config);  
  TConfig ini(CONFIG_STAMPE, config);              
  name = ini.get("Name");
  return name.not_empty();
}

void TVendite_mask::reset_printer_config() const
{
  TString config; get_printer_config(config);  
  TConfig ini(CONFIG_STAMPE, config);              
  ini.remove_all();
}

static TString4 __tab_codnum;

static bool tab_tip_filter(const TRelation* r)
{
	if (__tab_codnum.blank())
		return true;
	const TCodice_numerazione & cod_num = cached_numerazione(__tab_codnum);
	const TString4 tipo = r->curr().get("CODTAB");
	const int last = cod_num.ntipi_doc();
	for (int i = 0; i < last; i++ )
	{
		const TString& curtipo = cod_num.tipo_doc(i);
		if (curtipo == tipo) 
      return true;
	}
	return false;
}

bool TVendite_mask::on_num_event(TOperable_field& o, TField_event e, long jolly)
{
	switch (o.dlg())
	{
		case F_CODNUM:
			if (e == fe_init || e == fe_modify)
      {
				__tab_codnum = o.get();
        efield(F_TIPODOC).browse()->cursor()->set_filterfunction(tab_tip_filter);
      }
			break;
		default:
			break;
	}
	return true;	//metodo che gestiva la stampante per le numerazioni documenti
}

bool TVendite_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
  if (is_table("NUM"))
    return on_num_event(o, e, jolly);
  return true;
}

TVendite_mask::TVendite_mask(const char* name) : TAutomask(name) 
{ 
  const TFixed_string n(name);
  _tab = n.mid(4,3);
  _tab.upper();
}

///////////////////////////////////////////////////////////
// TVendite_tabapp
///////////////////////////////////////////////////////////

class TVendite_tabapp : public TTable_application
{

	virtual const char * extra_modules() const {return "dt";}

protected:
  virtual TMask* set_mask(TMask* m);
  virtual void add_anal_fields(TVendite_mask& vm);
  virtual void init_query_mode(TMask& m);
  virtual int read(TMask& m);
  virtual int write(const TMask& m);
  virtual int rewrite(const TMask& m);
  virtual bool user_create();
  void write_gmc(const TMask& m, TRectype& curr);
  static bool codgmc_handler(TMask_field& f, KEY k);

  bool is_table(const char* tab) const { return get_tabname() == tab; }

public:
};

void TVendite_tabapp::add_anal_fields(TVendite_mask& vm)
{
	int y = 4;
	short dlg = F_ANAL1;
	int nfields = 0;
	const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
	const TMultilevel_code_info& cominfo = ca_multilevel_code_info(LF_COMMESSE);
	const TMultilevel_code_info& cdcinfo = ca_multilevel_code_info(LF_CDC);
	int fasi_fields = fasinfo.levels();
	const int cdc_fields = cdcinfo.levels();
	const int com_fields = cominfo.levels();
	const bool use_fsc = fasi_fields > 0;

	if (use_fsc && fasinfo.parent() == LF_CDC)
	{
		nfields = ca_create_fields(vm, 1, LF_FASI, 2, y, dlg, dlg+50, 0x0, "S1", 20);

		const int dlgf = dlg + com_fields;
		fasi_fields -= com_fields;
		const int offset = 61 - vm.field(dlgf).field()->from();

		for (short i = 0 ; i< fasi_fields; i++)
		{
			TFieldref * fr = (TFieldref *) vm.field(dlgf + i).field();

			if (fr != NULL)
			{
				TEdit_field & fld = vm.efield(dlgf + i);
        TString16 str;
				
				str.format("S1[%d,%d]", fr->from() + offset + 1, fr->to() + offset);
        fld.set_field(str);
			}
		}
	}
	else
		nfields = ca_create_fields(vm, 1, LF_CDC, 2, y, dlg, dlg+50, 0x0, "S1", 20);
	dlg += nfields;
	y += nfields;
	if (use_fsc && fasinfo.parent() == LF_COMMESSE)
	{
		nfields = ca_create_fields(vm, 1, LF_FASI, 2, y, dlg, dlg+50, 0x0, "S1", 40);
		const int dlgf = dlg + com_fields;
		fasi_fields -= com_fields;
		const int offset = 60 - vm.field(dlgf).field()->from();

		for (short i = 0 ; i < fasi_fields; i++)
		{
			TFieldref * fr = (TFieldref *) vm.field(dlgf + i).field();

			if (fr != NULL)
			{
				TEdit_field & fld = vm.efield(dlgf + i);
        TString16 str;
				
				str.format("S1[%d,%d]", fr->from() + offset + 1, fr->to() + offset);
        fld.set_field(str);
			}
		}
	}
	else
		nfields = ca_create_fields(vm, 1, LF_COMMESSE, 2, y, dlg, dlg+50, 0x0, "S1", 40);
	dlg += nfields;
	y += nfields;
	if (use_fsc && fasinfo.parent() <= 0)
		nfields = ca_create_fields(vm, 1, LF_FASI, 2, y, dlg, dlg+50, 0x0, "S1", 60);

}

TMask* TVendite_tabapp::set_mask(TMask* m)
{
  if (m == NULL)
  {
    TFilename mn; get_mask_name(mn);
    TVendite_mask* vm = new TVendite_mask(mn);

    if (has_module(CAAUT, CHK_DONGLE) || has_module(CMAUT, CHK_DONGLE))
    {
       // Crea i campi per i conti analitici (vendite e acquisti)
      if (vm->table_code() == "SPP")
      {
        ca_create_fields(*vm, 0, LF_PCONANA, 2, 11, SPP_CDC_V1, SPP_CDC_V1+50, 0x0, "S1");
        ca_create_fields(*vm, 0, LF_PCONANA, 2, 16, SPP_CDC_A1, SPP_CDC_A1+50, 0x0, "S2");
				add_anal_fields(*vm);
      } else
      if (vm->table_code() == "PRS")
      {
        ca_create_fields(*vm, 0, LF_PCONANA, 2, 12, PRS_CDC_V1, PRS_CDC_V1+10, 0x0, "S1");
				ca_create_fields(*vm, 0, LF_PCONANA, 2, 18, PRS_CDC_A1, PRS_CDC_A1+10, 0x0, "S2");
				add_anal_fields(*vm);
      } else
      if (vm->table_code() == "RSS")
      {
        ca_create_fields(*vm, 0, LF_PCONANA, 2, 16, RSS_CDC_V1, RSS_CDC_V1+10, 0x0, "S1");
				add_anal_fields(*vm);
      } else
      if (vm->table_code() == "ATR")
      {
        ca_create_fields(*vm, 0, LF_PCONANA, 2, 12, ATR_CDC_V1, ATR_CDC_V1+10, 0x0, "S1");
				add_anal_fields(*vm);
      }
    }
    m = vm;
  }
  return TTable_application::set_mask(m);
}

void TVendite_tabapp::init_query_mode(TMask& m)
{
  if (is_table("RSS"))
  {
    m.enable(RSS_RAGSOC);
  }
}

int TVendite_tabapp::read(TMask& m)
{
	int err = Tab_application::read(m);
  if (err == NOERR)
  {
    const TRectype& curr = get_relation()->curr();

    if (curr.get_real("R10").is_zero())
    {
      const TString& r0 = curr.get("R0");
		  if (is_table("SPP"))
			  m.set(SPP_PREZZO, r0); else
			if (is_table("PRS"))
			  m.set(PRS_PREZZO, r0); else
			if (is_table("RSS"))
				m.set(RSS_PREZZO, r0); else
			if (is_table("ATR"))
			  m.set(ATR_PREZZO, r0);
    }

    //in caso dei grmerc sono cazzi, perch� lo sheet va riempito usando il contenuto di S1 ed S2, che sono tokenstring..
    //..di tokenstrings!
    if (is_table("GMC"))
    {
      //intanto deve controllare da configurazione se enablare o meno la colonna CATVEN

      TSheet_field& listini = m.sfield(F_RIGHE_LIS);
      listini.enable_column(S_CATVEN, ini_get_bool(CONFIG_DITTA, "ve", "GESLISCV"));

      TToken_string stringona(140, ';');
      TString s = curr.get("S1");
      if (s.full())
      {
        stringona.add(s);
        s = curr.get("S2");
        if (s.full())
          stringona.add(s);
      }
                 
      listini.destroy();
      //questo serve per settare il separatore in modo che non mandi in confusione l'editor degli archivi..
      //..separator � definito nella maschera
      TToken_string stringhina(16, listini.separator());
      FOR_EACH_TOKEN(stringona, str)
      {
        stringhina = str;
        if (stringhina.find('|') >= 0)    //converte eventuali pipe standard in broken pipe
          stringhina.replace('|', stringhina.separator());
        listini.row(-1) = stringhina;
        listini.check_row(listini.items() - 1);
      }
      listini.force_update();
    }
  }
  return err;
}

bool TVendite_tabapp::codgmc_handler(TMask_field& f, KEY k)
{
  TMask& m = f.mask();
  if (m.query_mode() && k == K_ENTER)
  {
    const TString& codice = m.get(f.dlg()); //stringa immessa nella maschera
    const TString& codtab = cache().get("GMC", codice, "CODTAB"); //stringa cercata nella tabella
    if (codtab.empty()) //se non trovi la stringa in tabella (in codice magazzino non esiste->se in insert mode)
    {
      const int lungh = codice.len();
      if (lungh > 0 && lungh < 3)
        return f.error_box("Il codice del gruppo merceologico deve avere obbligatoriamente lunghezza 3");
    }
  }

  return true;
}

void TVendite_tabapp::write_gmc(const TMask& m, TRectype& curr)
{
  //la tabella gmc � + incasinata causa la presenza di uno sheet che va salvato come tokenstring(;separated)..
  //di tokenstrings(|separated) in uno o due campi alfanumerici
  TSheet_field& listini = m.sfield(F_RIGHE_LIS);
  TToken_string s1(70, ';'), s2(70, ';');
  FOR_EACH_SHEET_ROW (listini, r, riga)
  {
    TToken_string mini_string(12, SAFE_PIPE_CHR);   //separatore broken_pipe !!!
    mini_string.add(riga->get(0));      //catven
    mini_string.add(riga->get());       //codlis
    mini_string.add(riga->get());       //ricarico
    mini_string.trim();
    if (!mini_string.empty_items())
    {
      if (s1.len() + mini_string.len() < 70)
        s1.add(mini_string);
      else
      {
        if (s2.len() + mini_string.len() < 70)
          s2.add(mini_string);
      }
    }
  }
  curr.put("S1", s1);
  curr.put("S2", s2);
}

int TVendite_tabapp::write(const TMask& m)
{
  TRectype& curr = get_relation()->curr();
	if (is_table("SPP"))
		curr.put("R0",	m.get(SPP_PREZZO)); else
	if (is_table("PRS"))
		curr.put("R0",	m.get(PRS_PREZZO));	else
	if (is_table("RSS"))
		curr.put("R0",	m.get(RSS_PREZZO));	else
	if (is_table("ATR"))
		curr.put("R0",	m.get(ATR_PREZZO));
  if (is_table("GMC"))
    write_gmc(m ,curr);

  return Tab_application::write(m);
}

int TVendite_tabapp::rewrite(const TMask& m)
{
  TRectype& curr = get_relation()->curr();

	if (is_table("SPP"))
		curr.put("R0",	m.get(SPP_PREZZO)); else
	if (is_table("PRS"))
		curr.put("R0",	m.get(PRS_PREZZO));	else
	if (is_table("RSS"))
		curr.put("R0",	m.get(RSS_PREZZO));	else
	if (is_table("ATR"))
		curr.put("R0",	m.get(ATR_PREZZO));
  if (is_table("GMC"))
    write_gmc(m ,curr);

	return Tab_application::rewrite(m);
}


bool TVendite_tabapp::user_create()
{
  bool ok = TTable_application::user_create();
  if (ok) 
  {
    const TString& name = get_tabname();
    TMask& mask = *get_mask();

    if (name == TAB_GRMERC)
      mask.set_handler(201, codgmc_handler);
  }
  return ok;
}


int ve0400(int argc, char* argv[])
{
  TVendite_tabapp vta;
  vta.run(argc, argv, TR("Tabella Vendite"));
  return 0;
}