#include <applicat.h>
#include <automask.h>
#include <config.h>
#include <execp.h>
#include <filetext.h>
#include <progind.h>
#include <printer.h>
#include <recarray.h>
#include <strings.h>
#include <utility.h>

#include "pd1579.h"
#include "pd1579100a.h"

#include "clifo.h"
#include "comuni.h"

// TAutomask

class TImpClienti_mask : public TAutomask
{
protected:
  bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
  TImpClienti_mask();
  virtual ~TImpClienti_mask(){};
};
  
TImpClienti_mask::TImpClienti_mask() :TAutomask ("pd1579100a")
{
}  

bool TImpClienti_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
{ 
  return TRUE;
}

// TFile_text

class TImpClienti_file: public TFile_text
{ 
protected:
  virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str);

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

TImpClienti_file::TImpClienti_file(const TString& file_name)
          : TFile_text(file_name, "pd1579100a.ini")
{
}

void TImpClienti_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str)
{
  const TString code(s.get(0));
  TString valore = str;
  if (code == "_UPPERCASE")
  {
    valore.upper(); 
  }
  else NFCHECK("Macro non definita: %s", (const char *)code);
  str = valore;
} 

// TSkeleton_application

class TImpClienti : public TSkeleton_application
{
	TImpClienti_mask*	_msk;
	TImpClienti_file* _trasfile;
	TLocalisamfile* _clienti;
	TConfig*		    _configfile;
  TRelation*      _rel;
  TCursor*        _cur;
  TProgind*       _prog;  

  long    _numreg;

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

public:           
  bool print_header();
  void print_line(const TString& rigastampa = "");
  void print_footer();
	virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
	bool transfer();
	const long get_nextcodcf();
  TImpClienti() {}
};

TImpClienti& app() { return (TImpClienti&) main_app(); }

bool TImpClienti::print_header()
{
	if (printer().open())
	{
		TDate oggi(TODAY);
		TPrintrow row;
		TString256 rigastampa;
		rigastampa = "IMPORTAZIONE CLIENTI";
		rigastampa.center_just(80);
		row.put(rigastampa);
  	row.put("@>", 1);
  	row.put("Pag. @#", 65);
  	printer().setheaderline(2, row);
		rigastampa = "";
		rigastampa.fill('-',80);
		row.reset();
		row.put(rigastampa);
		printer().setheaderline(3, row);
		return TRUE;
	}
	else
		return error_box("Errore in apertura stampante.");	
}		

void TImpClienti::print_line(const TString& rigastampa)
{                        
	TPrintrow row;
	row.reset();
	if (rigastampa.not_empty())
	{                    
		row.put((const char*) rigastampa);
		printer().print(row);			
	}
}

void TImpClienti::print_footer()
{                     
	printer().formfeed();
	printer().close();
}

                                   
bool TImpClienti::create()
{
  open_files(LF_CLIFO, 0);
	TFilename configname = "pd1579100.ini";
	configname.custom_path();
  _configfile = new TConfig(configname);
  _msk = new TImpClienti_mask();
	_clienti = new TLocalisamfile(LF_CLIFO);       
  return TSkeleton_application::create();
}

bool TImpClienti::destroy()
{
	delete _clienti;
	delete _msk;
	delete _configfile;
  return TApplication::destroy();
}

void TImpClienti::main_loop()
{  
	KEY	tasto;
  _msk->set(F_PERCORSO,	_configfile->get("PERCORSO", "OPZIONI"));
  tasto = _msk->run();
  if (tasto == K_ENTER)
  {
		if (print_header())
		{
			if (transfer())
			{
				_configfile->set("PERCORSO", _msk->get(F_PERCORSO), "OPZIONI");

				message_box(TR("Importazione clienti completata"));
			}
			print_footer();
		}
		else
			error_box("Errore in apertura stampante.");	
  }   
}

const long TImpClienti::get_nextcodcf()
{
	TLocalisamfile& clifo = *_clienti;
  long  codcf = 1L ;
  if (!clifo.empty())
  {
		clifo.zero() ;
    clifo.setkey(1) ;
    clifo.put(CLI_TIPOCF, 'F');
    clifo.read(_isgteq) ;
    if (clifo.good())
      clifo.prev() ;
    clifo.setstatus(NOERR);
	}
  else clifo.last();
  if (clifo.good())
	{
		const TFixed_string tipocf(clifo.get(CLI_TIPOCF)); 
    if ( tipocf == "C")
		{
			codcf = clifo.get_long(CLI_CODCF);
			if (codcf == 999999)
				clifo.prev();
			codcf = clifo.get_long(CLI_CODCF)+1;
		}
  }               
	return codcf;
}

bool TImpClienti::transfer()
{
// cache per i comuni
	TRecord_cache cache_comuni(LF_COMUNI, 2);

  _trasfile = new TImpClienti_file(_msk->get(F_PERCORSO));
  _trasfile->open(_msk->get(F_PERCORSO),'r');

	const long dimension = fsize(_msk->get(F_PERCORSO));
  TProgind pi(dimension,"Importazione in corso...");

  TRelation rel(LF_CLIFO);
  TRectype& reccli = rel.curr();

	TLocalisamfile& clifo = rel.lfile();
  rel.lfile().setkey(2);

	TString80 stampa;
	int err = NOERR;
  TRecord_text curr;
  while (_trasfile->read(curr) == NOERR && !pi.iscancelled() && err == NOERR) 
  {
    pi.setstatus(_trasfile->read_file()->tellg());
		TString80 ragsoc = curr.get(0);
		ragsoc.trim();
		ragsoc.upper();
		reccli.zero();
		reccli.put(CLI_TIPOCF, 'C');
		reccli.put(CLI_RAGSOC, ragsoc);
		if (reccli.read(rel.lfile())!=NOERR)
	  {
			reccli.zero();
			const long codcf = get_nextcodcf();
			reccli.put(CLI_TIPOCF, 'C');
	    reccli.put(CLI_CODCF, codcf);
			reccli.put(CLI_RAGSOC, ragsoc);
	    err = reccli.write(rel.lfile());
			if (err != NOERR)
				message_box("Errore in scrittura clienti %d", err);
	  }  
    _trasfile->autosave(rel, curr);
		// indirizzo
		TString80 str = curr.get(4);
		str << " " << curr.get(5);
		reccli.put(CLI_INDCF, str);
		// comune

		str = curr.get(11);
		str.trim();
		str.upper();
		if (str == "ITALIA")
		{
			TString80 dencom = curr.get(9);
			dencom.trim();
			dencom.upper();
			TRectype reccom = cache_comuni.get(dencom);
			str = reccom.get(COM_DENCOM);
			str.trim();
			if (str == dencom)
				reccli.put(CLI_COMCF, reccom.get(COM_COM));
			else
			{
				reccli.put(CLI_COMCF, " ");
				reccli.put(CLI_LOCCF, dencom);
				stampa = "Cliente ";
				stampa << reccli.get(CLI_CODCF);
				stampa << " - comune " << dencom << " non trovato";
				print_line(stampa);
			}
		}
		rel.rewrite();
	}
  _trasfile->close();
	delete _trasfile;
	return TRUE;
}

int pd1579100 (int argc, char* argv[])
{
  TImpClienti main_app;
  main_app.run(argc, argv, TR("Importazione clienti"));
  return TRUE;
}