#include 
#include 
#include 
#include 
#include 
#include "soggetti.h"
#include "sezioni.h"
#include 
#include "at7.h"
#include "at7200a.h"
#include "at7100.h"
#define ALIAS_COMDOM 501
#define ALIAS_COMNAS 500 
#define ALIAS_LCP    100
enum ts { undefined = 0, elenco = 1, tessere = 2 };
 
// definizione form per tessere associative
class TTessereS_form : public TForm
{
public:
	
	virtual TCursor* cursor() const;
	virtual TRelation* relation() const;
	TPrint_section& get_body() { return section('B'); } ;
  TTessereS_form(): TForm() {};
  TTessereS_form(const char* form, const char * code = "", int editlevel = 0, const char* desc = "")
    						: TForm(form,code,editlevel,desc) {};
  virtual ~TTessereS_form() {};
};
class TStampaTessereS : public TPrintapp
{
  TRelation*			_rel;
  TIsamtempfile*	_sogtmp;
  TMask*      		_msk;
  TTessereS_form*	_form_pag;
  TAssoc_array		_asoggetti;
  int							_numdon;
  bool						_aggiorna;
  int 						_cur;
  TDate 					_data_stampa;
	ts 	      			_tipostampa;
	TString					_riepilogodon;
  int							_totfinestampa;
  bool						_sttess2;
  int							_numdon2;
	TString16				_catini2, _catfin2;
protected:
  virtual bool user_create();
  virtual bool user_destroy();
  virtual bool set_print(int m);
  virtual void set_page(int file, int cnt);
  virtual bool preprocess_page(int file, int counter);
  virtual print_action postprocess_print(int file, int counter);
	
	static void add_rows_soggetti(TSheet_field& s, int count = 10, int start = 1);
	static bool soggetti_notify(TSheet_field& s, int r, KEY k);
	static bool nome_handler(TMask_field& f, KEY k);
	static bool codice_handler(TMask_field& f, KEY k);
	
public:
  void crea_intestazione();
	void filtra_codici();  
	void fine_stampa();
  TMask& app_mask() { return *_msk; }
  TStampaTessereS() : _data_stampa(TODAY), _riepilogodon(35) {}
};
HIDDEN inline TStampaTessereS& app() { return (TStampaTessereS&) main_app(); }
TCursor* TTessereS_form::cursor() const { return app().current_cursor(); }
TRelation* TTessereS_form::relation() const { return cursor()->relation(); }
void TStampaTessereS::add_rows_soggetti(TSheet_field& s, int count, int start)
{
	if (start == 1)
		s.destroy();
	for (int r=start; rfirst(); !_sogtmp->eof(); _sogtmp->next())
		_sogtmp->remove();
	TSheet_field& s = (TSheet_field&)_msk->field(F_SOGGETTI);
	for (int r=0; r < s.items(); r++)
 	{
 		TToken_string& row = s.row(r);
 		const long codice = row.get_long(0);
 		if (codice != 0)
 		{
 			TLocalisamfile soggetti(LF_SOGGETTI);
 			soggetti.setkey(1);
 			soggetti.zero();
 			soggetti.put(SOG_CODICE,codice);
 			if (soggetti.read() == NOERR)
 				_sogtmp->write(soggetti.curr());
 		}
	} 		
}	
void TStampaTessereS::set_page(int file, int cnt)
{
	switch (_tipostampa)
	{
		case tessere:
    {
			TPrint_section& corpo = _form_pag->get_body();
			corpo.reset();
		  TForm_item& rigadon = corpo.find_field(TES_RIGADON1);
			rigadon.set(_riepilogodon);
			corpo.update();
			for (word i = 0; i < corpo.height(); i++)
			{
				TPrintrow& riga = corpo.row(i);
				set_row(i+1,riga);
			}  			
			force_setpage(TRUE);	// serve perchè alla prossima etichetta rifaccia la setpage
														// altrimenti stampa sempre la stessa etichetta
		}
		break;
		case elenco:
		{
			set_row(1,"@0g@S", FLD(LF_SOGGETTI,SOG_CODSEZ));
			set_row(1,"@2g@S", FLD(LF_SOGGETTI,SOG_CODSOT));
			set_row(1,"@5g@S", FLD(LF_SOGGETTI,SOG_COGNOME));
			set_row(1,"@31g@S", FLD(LF_SOGGETTI,SOG_NOME));
			set_row(1,"@57g@ld", FLD(LF_SOGGETTI,SOG_DATANASC));
			set_row(1,"@68g@S", FLD(LF_SOGGETTI,SOG_TESSAVIS));
			set_row(1,"@75g@ld", FLD(LF_SOGGETTI,SOG_DATAULTDON));
			set_row(1,"@86g@pn", FLD(LF_SOGGETTI,SOG_TOTDON, "###"));
			set_row(1,"@90g@S", FLD(LF_SOGGETTI,SOG_PUNTORACC));
		}
		break;
	}																
  /*
	TPrint_section& corpo = _form_pag->get_body();
	corpo.update();
  //TForm_item& rigadon = corpo.find_field(TES_RIGADON1);
	//rigadon.set(_riepilogodon);
	for (word i = 0; i < corpo.height(); i++)
	{
		TPrintrow& riga = corpo.row(i);
		set_row(i+1,riga);
	}  			
	force_setpage(TRUE);	// serve perchè alla prossima etichetta rifaccia la setpage
												// altrimenti stampa sempre la stessa etichetta
	*/												
}
bool TStampaTessereS::preprocess_page(int file, int counter)
{                
	if (_tipostampa == tessere)              
	{
		TLocalisamfile& sogg = current_cursor()->file(LF_SOGGETTI);
		const int totdon = sogg.get_int(SOG_TOTDON);
		const TDate dataultima = sogg.get(SOG_DATAULTDON);
		_riepilogodon = "";
		if (totdon != 0)	
		{	
			_riepilogodon = "Donazioni fino al ";
			_riepilogodon << dataultima.string();
			_riepilogodon << " n.";
			_riepilogodon << totdon;
		}	
		if (_aggiorna)
		{                 
			// se non faccio cosi' non mi registra le variazioni!!!!
			// provato come in at7100.cpp ma non va
			// forse perche' la relazione e' su un'altro file principale????
			TLocalisamfile filesogg(LF_SOGGETTI);
			filesogg.setkey(1);
			filesogg.zero();
			filesogg.put(SOG_CODICE, sogg.get_long(SOG_CODICE));
			if (filesogg.read() == NOERR)
			{
				filesogg.put(SOG_T_STAMPATA,TRUE);
				TString16 catdon = filesogg.get(SOG_CATDON);
				const int totdon = filesogg.get_int(SOG_TOTDON);
				if ((totdon >= _numdon2) && (catdon == _catini2) && _sttess2)
					filesogg.put(SOG_CATDON, _catfin2);
				filesogg.rewrite();					
			}		
		}	
	}		
	else
		_totfinestampa++;
  return TRUE;
}
bool TStampaTessereS::set_print(int m)
{                              
  TPrinter& p = printer();
	p.read_configuration();
	TSheet_field& s = (TSheet_field&)_msk->field(F_SOGGETTI);
	_tipostampa = undefined;
  KEY tasto;
  tasto = _msk->run();
  switch (tasto)
  {
  case F_ELENCO:
  	_tipostampa = elenco;
  break;
  case F_TESSERE:
  {
  	_tipostampa = tessere;
    p.read_configuration("AT_TESSERE");
    p.set_printtype(winprinter);
    if (p.set())
			message_box("Stampante configurata per stampa tessere");    	
		else           
		{
			_tipostampa = undefined;			
			message_box("Operazione di stampa tessere annullata");    	
		}
	}  	
  break;	
	case F_AZZERA:
	{
		TSheet_field& s = (TSheet_field&)_msk->field(F_SOGGETTI);
		s.destroy();
		s.force_update();
		if (s.items()==0)
			add_rows_soggetti(s,50);
	}  	
  break;
  }	
  if (tasto==F_AZZERA)
  	return TRUE;
	if (_tipostampa != undefined)
  {   
    reset_files(); 
    add_file(LF_SOGGETTI);
	  _asoggetti.destroy();
	 	for (int r=0; r < s.items(); r++)
	 	{
	 		TToken_string& row = s.row(r);
	 		const long codice = row.get_long(0);
	 		const char* scodice = row.get(0);
	 		if (codice != 0)
	 			_asoggetti.add(scodice);
	 	}
	 	if (_asoggetti.items() != 0)
	 	{
			_aggiorna = _msk->get_bool(F_AGGIORNA);
			filtra_codici();
		}				
 		_totfinestampa = 0;
		reset_print(); 
		printer().footerlen(0);		
		crea_intestazione();
    return TRUE;
  }
  else
    return FALSE;
}
void TStampaTessereS::crea_intestazione()
{
  reset_header();
  if (_tipostampa == elenco)
  {
  	TString sep(94);
  	sep = "ELENCO TESSERE RICHIESTE";
		sep.center_just(94);
  	set_header(1, "@0g%s", (const char*) sep);
  	TString16 data_stampa = _data_stampa.string();
  	set_header(1,"@0g%10s", (const char*) data_stampa);
  	sep = "";
  	sep << "Pag. @#";
 		set_header(1, "@86g%s", (const char*) sep);  
  	sep = "";
  	sep.fill('-');
  	set_header(2, (const char *) sep);
	  set_header(3,"@0gSeSo@5gCognome@31gNome@57gData nasc.@68gTess.@75gUlt.don.@86gTot Punto");
	  set_header(4,"@0g----@5g-------------------------@31g-------------------------@57g----------@68g------@75g----------@86g--- -----");
  	printer().footerlen(3);
		set_row(1,"@0g@S", FLD(LF_SOGGETTI,SOG_CODSEZ));
		set_row(1,"@2g@S", FLD(LF_SOGGETTI,SOG_CODSOT));
		set_row(1,"@5g@S", FLD(LF_SOGGETTI,SOG_COGNOME));
		set_row(1,"@31g@S", FLD(LF_SOGGETTI,SOG_NOME));
		set_row(1,"@57g@ld", FLD(LF_SOGGETTI,SOG_DATANASC));
		set_row(1,"@68g@S", FLD(LF_SOGGETTI,SOG_TESSAVIS));
		set_row(1,"@75g@ld", FLD(LF_SOGGETTI,SOG_DATAULTDON));
		set_row(1,"@86g@pn", FLD(LF_SOGGETTI,SOG_TOTDON, "###"));
		set_row(1,"@90g@S", FLD(LF_SOGGETTI,SOG_PUNTORACC));
	}  	
}
void TStampaTessereS::fine_stampa()
{
	// stampa totale soggetti a fine stampa
	TPrintrow row;
	TString rigastampa = "";
	rigastampa.fill('-',94);
	row.put((const char*) rigastampa);
	printer().print(row);			
	row.reset();
	printer().print(row);			
	rigastampa.format("TOTALE TESSERE RICHIESTE %d", _totfinestampa);
	row.put((const char*) rigastampa);
	printer().print(row);			
	printer().formfeed();
}
         
print_action TStampaTessereS::postprocess_print(int file, int counter)
{ 
	if (_tipostampa == elenco)
	{
		if (_totfinestampa>0)
			fine_stampa();				
	}			
	return NEXT_PAGE;
}
         
bool TStampaTessereS::user_create()
{
  _sogtmp = new TIsamtempfile(LF_SOGGETTI,NULL,TRUE,TRUE);
  _rel = new TRelation(_sogtmp);
	_rel->add(LF_SOGGETTI, "CODICE==CODICE");
  _rel->add(LF_COMUNI, "COM==DOM_CODCOM",1,0,ALIAS_COMDOM);
  _rel->add(LF_COMUNI, "COM==COMNASC",1,0,ALIAS_COMNAS);
  _rel->add("LCP", "CODTAB==DOM_CODLOC",1,0,ALIAS_LCP);
  _rel->add(LF_SEZIONI, "CODSEZ==CODSEZ|CODSOT==CODSOT");
  _rel->add(LF_SEZIONI, "CODSEZ==CODSEZ|CODSOT==CODSOT");
	//cursore ordinamento per sezione+sottogruppo+cognome+nome  
  _cur = add_cursor(new TCursor(_rel, "", 3));
  _msk = new TMask("at7200a");
  TConfig config(CONFIG_STUDIO);
  _numdon2 = config.get_int("NumDon2");
  _catini2 = config.get("CatIni2");
  _catfin2 = config.get("CatFin2");
  _sttess2 = config.get_bool("StTess2");
  _form_pag = new TTessereS_form("ATTESSER");
	TSheet_field& ss = (TSheet_field&)_msk->field(F_SOGGETTI);
	add_rows_soggetti(ss,50);
	ss.set_notify(soggetti_notify);
	ss.sheet_mask().set_handler(F_S_NOME,nome_handler);
	ss.sheet_mask().set_handler(F_S_CODICE,codice_handler);
  return TRUE;
}
bool TStampaTessereS::soggetti_notify(TSheet_field& s, int r, KEY k)
{              
	bool ok = TRUE;
	switch (k)
	{ 
		case K_INS:
			// richiesta inserimento riga
		break;	
		case K_DEL:
		case K_CTRL+K_DEL:
		// avvenuta cancellazione riga
		break;
		case K_SPACE:
		// inizio modifica riga
		break;
		case K_TAB:
		// entrata riga			
		{         
		  static bool entering = TRUE;
		  if (entering)
		  {
		    entering = FALSE;
			  if ((r == s.items()-1) && (r == s.first_empty()))
				  app().add_rows_soggetti(s,10,r+1);
			  TToken_string& row = s.row(r);
			  if (row.empty_items())
			  	s.select(r,1,FALSE);			
			  entering = TRUE;	
			}  	
		}
	  break;
		case K_ENTER:
		// uscita da riga modificata
		case K_CTRL+K_TAB:
		// uscita riga
		{ 
			TToken_string& row = s.row(r);
			const long codsog = row.get_long(0);
			if (codsog != 0)
				for (int i=s.items()-1; i>=0; i--)
				{
					if (i != r)
					{
						TToken_string& row = s.row(i); 
						if (codsog == row.get_long(0))
							return s.sheet_mask().field(F_S_CODICE).error_box("Soggetto gia' inserito");
					}					
				}				
			else
			{
				const char* cognome = row.get(1);
				if ((cognome != NULL) && (cognome != "\0"))
					s.sheet_mask().field(F_S_NOME).set_focusdirty();
			}
		}
	  break;  	
	}  
  return ok;  
}
bool TStampaTessereS::nome_handler(TMask_field& f, KEY k)
{
	bool ok = TRUE;
  if (f.to_check(k))
  {
  	TMask& m = f.mask();
  	long codsog = m.get_long(F_S_CODICE);
  	if (codsog == 0)
      f.on_key(K_F9);
  }	
  return ok;
}
bool TStampaTessereS::codice_handler(TMask_field& f, KEY k)
{
	bool ok = TRUE;
  if (f.to_check(k))
  {
  	TMask& m = f.mask();
  	long codsog = m.get_long(F_S_CODICE);
  	if (codsog != 0)
  	{
			TLocalisamfile sog(LF_SOGGETTI);
  		sog.setkey(1);	
			sog.zero();
			sog.put(SOG_CODICE, codsog);
			int err = sog.read();
			if (err == NOERR)
			{
  			m.set(F_S_COGNOME, sog.get(SOG_COGNOME));
  			m.set(F_S_NOME, sog.get(SOG_NOME));
  			m.set(F_S_DATANASC, sog.get(SOG_DATANASC));
  			m.set(F_S_TESSAVIS, sog.get(SOG_TESSAVIS));
  			m.set(F_S_CODSEZ, sog.get(SOG_CODSEZ));
  			m.set(F_S_CODSOT, sog.get(SOG_CODSOT));
  			m.set(F_S_CATDON, sog.get(SOG_CATDON));
			}  			
			else
				ok = FALSE; // codice non esistente  			
  	}
  }	
  return ok;
}
bool TStampaTessereS::user_destroy()
{
  delete _form_pag;
  delete _msk;
  delete _rel;
  delete _sogtmp;
  //printer().read_configuration();
  return TRUE;
}
int at7200(int argc, char* argv[])
{
  TStampaTessereS a;
  a.run(argc, argv, "Stampa tessere singole");
  return 0;
}