#include <applicat.h>
#include <assoc.h>
#include <automask.h>
#include <currency.h>
#include <filetext.h>
#include <msksheet.h>
#include <recarray.h>
#include <relation.h>
#include <sort.h>
   
#include "..\ve\velib.h"

#include "pg0388.h"
#include "pg0388100a.h"

#define ALIAS_COMCF 200
#define ALIAS_IND 300
 
class TPG0388100_file: public TFile_text
{
protected:
  virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str);

public:
  TPG0388100_file(const TString& file_name);
  virtual ~TPG0388100_file() { }
};

TPG0388100_file::TPG0388100_file(const TString& file_name)
          : TFile_text(file_name, "pg0388100a.ini")
{
}

class TPG0388100_mask : public TAutomask
{
protected:
  bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:

  TPG0388100_mask();
  
  virtual ~TPG0388100_mask(){};
};
  
TPG0388100_mask::TPG0388100_mask() :TAutomask ("pg0388100a")
{
}  
  
bool TPG0388100_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{ 
  return true;
}

class TPG0388100 : public TSkeleton_application
{                     
	TCursor*				   _cur;
  TPG0388100_mask*	 _msk;
  TPG0388100_file* 	 _trasfile;
  TConfig*					 _configfile;
	TRiga_documento*	 _riga_doc_curr;

virtual const char * extra_modules() const {return "ve";}
  
protected:
  virtual bool create(void);
  virtual bool destroy(void);
  virtual void main_loop() ;
	void mask2ini();
	void ini2mask();
	bool trasferisci_ordini();
	real _omaggio;

public:   
	const real& get_omaggio() {return _omaggio;};
  TPG0388100() {} ;
  virtual ~TPG0388100() {} ;
};  

// restituisce un riferimento all' applicazione
inline TPG0388100& app() { return (TPG0388100&) main_app();}

// gestione dei messaggi estesi nei campi
void TPG0388100_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str)
{
  const TString code(s.get(0));
  TString valore;
  if (code == "_FISSO")
  {
    // gestione dei campi fissi 
    // sintassi: _FISSO,!<valore>
    // dove: <valore> � la stringa fissa da emettere
    TString in(s.get());
    CHECK(in[0]=='!',"Macro _FISSO senza carattere '!'");
    in.ltrim(1);
    in.trim();
    valore = in;
  }
	else if (code == "_OMAGGIO")
	{
		valore = app().get_omaggio().string();
	}
	else if (code == "_CONCAT")
	{
    TString in(s.get());
    CHECK(in[0]=='!',"Macro _CONCAT senza carattere '!'");
    in.ltrim(1);
    in.trim();
		valore << str;
		TString fi(s.get());
		str = cur.curr(in).get(fi);
		if (str.not_empty())
		{
			valore << ',';
			valore << str;	
		}
	}
	else if (code == "_NOTE")
	{
		valore = cur.curr(LF_DOC).get(DOC_NOTE);
		valore.replace(char(182), '\n');
		TParagraph_string nota(valore, 50);
		valore = nota.get();		
	}
  else NFCHECK("Macro non definita: %s", (const char *)code); 
  str = valore;
}

bool TPG0388100::create()
{      
	open_files(LF_DOC, LF_CLIFO, LF_COMUNI, LF_CFVEN, 0);
  _msk = new TPG0388100_mask();
	_configfile = new TConfig("pg0388conf.ini", "INVIO");
  return TSkeleton_application::create();
}

bool TPG0388100::destroy()
{             
 	delete _configfile;
  delete _msk;
  return TSkeleton_application::destroy();
}

void TPG0388100::mask2ini()
{
	//carica i parametri del file di configurazione
	_configfile->set_paragraph("INVIO");
  for (int i = 0; i < _msk->fields() ; i++)
	{
		TMask_field& f = _msk->fld(i);
		const TFieldref* fr = f.field();
		if (fr != NULL)
			_configfile->set(fr->name(), f.get());
	}
}

void TPG0388100::ini2mask()
{
	//carica i parametri del file di configurazione
	_configfile->set_paragraph("INVIO");
  for (int i = 0; i < _msk->fields() ; i++)
	{
		TMask_field& f = _msk->fld(i);
		const TFieldref* fr = f.field();
		if (fr != NULL)
		{
			const TString& val = _configfile->get(fr->name());
			f.set(val);
		}
	}
}

void TPG0388100::main_loop()
{
  KEY	tasto;
	ini2mask();
  tasto = _msk->run();
  if (tasto == K_ENTER)
  {
		mask2ini();
		if (trasferisci_ordini())
			message_box(TR("Trasmissione ordini completata"));
  }
}

bool TPG0388100::trasferisci_ordini()
{                
	const TFilename file = _msk->get(F_FILENAME);
  _trasfile = new TPG0388100_file(file);
  _trasfile->open(file,'w');

	//parametri dei documenti da estrarre
	const TString4 numord = _msk->get(F_NUMORD);
	const char statoini = _msk->get(F_STATOINI)[0];
	const char statofin = _msk->get(F_STATOFIN)[0];
	const int anno = _msk->get_int(F_ANNO);
	const long numini = _msk->get_long(F_NUMINI);
	const long numfin = _msk->get_long(F_NUMFIN);
  TRelation doc_rel(LF_DOC);
  doc_rel.add(LF_RIGHEDOC, "CODNUM==CODNUM|ANNO==ANNO|PROVV==PROVV|NDOC==NDOC");
  doc_rel.add(LF_CLIFO, "TIPOCF==TIPOCF|CODCF==CODCF");
  doc_rel.add(LF_COMUNI, "COM==COMCF", 1, LF_CLIFO, ALIAS_COMCF);
  doc_rel.add(LF_INDSP, "TIPOCF==TIPOCF|CODCF==CODCF|CODIND==CODINDSP");
  doc_rel.add(LF_COMUNI, "COM==COM", 1, LF_INDSP, ALIAS_IND);
  TRectype da(LF_DOC);
  TRectype a(LF_DOC);
	da.put(DOC_PROVV, "D");
	a.put(DOC_PROVV, "D");
	da.put(DOC_ANNO, anno);
	a.put(DOC_ANNO, anno);
	da.put(DOC_CODNUM, numord);
	a.put(DOC_CODNUM, numord);
	da.put(DOC_NDOC, numini);
	a.put(DOC_NDOC, numfin);
	TString filt_expr;
 	filt_expr = "(STATO==\"";
 	filt_expr << statoini << "\")";
	doc_rel.lfile().set_curr(new TDocumento);
	_omaggio = ZERO;
	_cur = new TCursor(&doc_rel,filt_expr,1,&da,&a);
	const long cur_items = _cur ->items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato
	if (cur_items != 0) 
	{
	  for (*_cur = 0; _cur->pos() < cur_items; ++(*_cur))
	  {
			_omaggio = ZERO;
			TRecord_text rec;
  		rec.set_type("TE");
  		_trasfile->autoload(rec, *_cur); 
  		_trasfile->write(rec);
			TDocumento documento = doc_rel.curr();
			_configfile->set("NUMINI", documento.numero());
			// modifico lo stato del documento estratto
			documento.stato(statofin);
			documento.rewrite();
			for (int i=1;i<=documento.rows();i++)
			{       
				TRecord_text recr;
				const TRiga_documento& rec_rdoc = documento[i];
				if (!(rec_rdoc.is_omaggio()))
				{
					if (i< documento.rows())
					{
						const TRiga_documento& rec_rigasucc = documento[i+1];
						if (rec_rigasucc.is_omaggio())
							_omaggio = rec_rigasucc.quantita();
						else 
							_omaggio = ZERO;
					}
					//_riga_doc_curr = new TRiga_documento(rec_rdoc);
					doc_rel.curr(LF_RIGHEDOC) = rec_rdoc;
					recr.set_type("RI");
  				_trasfile->autoload(recr, *_cur); 
  				_trasfile->write(recr);
					//delete _riga_doc_curr;
				}
			}  
	  }
	  delete _cur;
	}  
  _trasfile->close();
	delete _trasfile;
	return true;
}


int pg0388100(int argc, char **argv) 
{
  TPG0388100 a;
  a.run(argc, argv, "Trasmissione ordini");
  return 0;
}