#include <form.h>
#include <mask.h>
#include <printapp.h>
#include <utility.h>

#include "contsan.h"
#include "soggetti.h"
#include "sezioni.h"

#include "at6.h"
#include "at6500a.h"

#define ALIAS_TCS	200

class TControlloControlli : public TPrintapp
{
  TRelation*					_rel;
  TMask*      				_msk;
  int									_counter;
  int 								_cur;
  TDate								_dataold, _dataini, _datafin;
  TString16						_tipocon, _sezold;
  TString16						_sezini, _sotini, _tipostampa, _ordinamento;
  
  TParagraph_string 	_cognome_nome;
  
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);

public:
  void crea_intestazione();
  void header_data(const TDate data, const TString16 luogo, const TString16 sezione);
  TMask& app_mask() { return *_msk; }
  TControlloControlli() : _cognome_nome("",35) {}
};

HIDDEN inline TControlloControlli& app() { return (TControlloControlli&) main_app(); }

void TControlloControlli::set_page(int file, int cnt)
{
	set_row(1,"@0g#D"		, &_counter);
	set_row(1,"@7g@pn"	, FLD(LF_SOGGETTI,SOG_CODICE,"########"));
	set_row(1,"@16g@S"	, FLD(LF_SOGGETTI,SOG_TESSAVIS));
	set_row(1,"@24g#a"	, &_cognome_nome);
	set_row(1,"@60g@ld"	, FLD(LF_SOGGETTI,SOG_DATANASC));
	set_row(1,"@71g@S"	, FLD(LF_SOGGETTI,SOG_CODSEZ));
	set_row(1,"@74g@S"	, FLD(LF_SOGGETTI,SOG_CODSOT));
	set_row(1,"@77g@ld"	, FLD(LF_CONTSAN,CON_DATACON));
	set_row(1,"@88g@S"	, FLD(LF_CONTSAN,CON_TIPOCON));
}

bool TControlloControlli::preprocess_page(int file, int counter)
{
	// contatore soggetti stampati 
	// per ora non c'�
	TString80 nome = current_cursor()->curr(LF_SOGGETTI).get(SOG_COGNOME);
	nome << " ";
	nome << current_cursor()->curr(LF_SOGGETTI).get(SOG_NOME);
	_cognome_nome = nome;
		
	// salto pagina se cambio punto di rottura
	switch (_tipostampa[0])
	{
		case 'D':
		{
			const TDate datanew = current_cursor()->curr().get(CON_DATACON);		
			if (datanew != _dataold )
			{
				if (_dataold.ok())
					printer().formfeed();
				_dataold = datanew;				
				header_data(datanew,"","");
				_counter = 0;
			} 
		}
		break;
		case 'S':
		{
			TString16 seznew = current_cursor()->curr(LF_SOGGETTI).get(SOG_CODSEZ);		
			seznew << "/";
			seznew << current_cursor()->curr(LF_SOGGETTI).get(SOG_CODSOT);		
			if (seznew != _sezold )
			{
				if (_sezold != "****")
					printer().formfeed();
				_sezold = seznew;				
				header_data(NULLDATE,"",seznew);
				_counter = 0;
			} 
		}
		break;			
	}		
	_counter++;
  return TRUE;
}

void TControlloControlli::header_data(const TDate data, const TString16 luogo, const TString16 sezione)
{
	TString intestazione(132);
	intestazione = "STAMPA DI CONTROLLO CONTROLLI SANITARI ";
	switch (_tipostampa[0])
	{
		case 'D':
		{
			intestazione << "PER DATA ";
			intestazione << data;
		}			
		break;
		case 'S':
		{
			intestazione << "PER SEZIONE ";
			intestazione << sezione;
		}			
		break;
	}		
	intestazione.center_just();
	set_header(1,"@0g%s", (const char*) intestazione);
 	intestazione = "Pag. @#";
 	set_header(1, "@110g%s", (const char*) intestazione);  
	return;
}

bool TControlloControlli::set_print(int m)
{ 
  KEY tasto;
 	tasto = _msk->run();
 	if (tasto == K_ENTER)
 	{ 
		_sezini = 	_msk->get(F_SEZINI);
 		_sotini = 	_msk->get(F_SOTINI);
		_dataini = 	_msk->get_date(F_DATAINI);	
		_datafin = 	_msk->get_date(F_DATAFIN);	
		_tipocon = 	_msk->get(F_TIPOCON);
 		
		_tipostampa = _msk->get(F_TIPOSTAMPA);
		_ordinamento = _msk->get(F_ORDINAMENTO);
		TString80 chiave = "";
		switch (_tipostampa[0])
		{
			case 'D':
				chiave = "93->DATACON|";
			break;
			case 'S':
				chiave = "90->CODSEZ|90->CODSOT|93->DATACON|";
			break;
		}
		switch (_ordinamento[0])
		{
			case 'C':
				chiave << "UPPER(90->COGNOME)|UPPER(90->NOME)";
			break;
		}
		TString80 filtro = "";			
		// filtro per tipo controlli
  	if (_tipocon.not_empty())
  		filtro = format("(TIPOCON == \"%s\")",(const char*)_tipocon);
		// filtro per sezione/sottogruppo
		if (_sezini.not_empty())
		{
  		if (filtro.empty())
  			filtro = format("(90->CODSEZ == \"%s\")",(const char*)_sezini);
			else
			{
				filtro << " && ";
				filtro << format("(90->CODSEZ == \"%s\")",(const char*)_sezini);
			}				
			if (_sotini.not_empty())
			{
	  		if (filtro.empty())
	  			filtro = format("(90->CODSOT == \"%s\")",(const char*)_sotini);
				else
				{
					filtro  << " && ";
					filtro << format("(90->CODSOT == \"%s\")",(const char*)_sotini);
				}				
			}
		}
		// filtro per data
	  TRectype da(LF_CONTSAN);
  	TRectype a (LF_CONTSAN);
  	if (_dataini.ok())
			da.put(CON_DATACON, _dataini);
  	if (_datafin.ok())
			a.put(CON_DATACON, _datafin);
	  _cur = add_cursor(new TSorted_cursor(_rel, (const char*) chiave, "", 2, &da, &a));
		current_cursor()->setfilter((const char*) filtro, TRUE);
 		_counter = 0;
		_dataold = NULLDATE;
		_sezold = "****";
	  reset_files(); 
  	add_file(LF_CONTSAN);
		reset_print();
		crea_intestazione();
		return TRUE;
  }	            
 	else
  	return FALSE;
}

void TControlloControlli::crea_intestazione()
{
  reset_header();
 	TString sep(132);
	sep = "Selezioni della stampa: ";
	if (_sezini.not_empty())
	{
		sep << "Sez. ";
		sep << _sezini;
		if (_sotini.not_empty())
		{
			sep << "/";
			sep << _sotini;
		}			
		sep << "; ";
	}
	if (_dataini.ok())
	{
		sep << "Dal ";
		sep << _dataini.string();
	}
	if (_datafin.ok())
	{
		sep << " Al ";
		sep << _datafin.string();
	}
	if (_dataini.ok() || _datafin.ok())
		sep << "; ";	
	if (_tipocon.not_empty())
	{
		sep << "Tipo ";
		sep << _tipocon;
		sep << "; ";
	}
	sep.center_just();
	set_header(2,"@0g%s", (const char*) sep);
 	set_header(3,"@0gProg.@7gCodice@16gTessera@24gCognome e nome@60gNato il@71gSe/So@77gData con.@88gTipo");
 	set_header(4,"@0g------@7g--------@16g-------@24g-----------------------------------@60g----------@71g-----@77g----------@88g----");
}

bool TControlloControlli::user_create()
{
  _rel = new TRelation(LF_CONTSAN);
  _rel->add(LF_SOGGETTI, "CODICE==CODICE");
  _rel->add("TCS", "CODTAB==TIPOCON",1,0,ALIAS_TCS);
  _msk = new TMask("at6500a");
  return TRUE;
}

bool TControlloControlli::user_destroy()
{
  delete _msk;
  delete _rel;
  return TRUE;
}

int at6500(int argc, char* argv[])
{
  TControlloControlli a;
  a.run(argc, argv, "Stampa di controllo controlli sanitari");
  return 0;
}