#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <utility.h>
#include <relation.h>
#include <reprint.h>
#include <reputils.h>
#include <textset.h>
#include <tabutil.h>

#include "../cg/cglib01.h"
#include "../cg/cg2103.h"
#include "../cg/cgsaldac.h"
#include "../cg/cgpagame.h"

#include "pi0001.h"
#include "pi0001100.h"
#include "pi0001200.h"
#include "pi0001200a.h"

#include <pconti.h>
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>

/* // Tracciato File: FGA5DAT/CGSCA00F - CGSCA : Scadenze INDEX                                                 9/12/09 17:43:05 Pag.    1
#define TR01CD     0		// A=Att./Sosp./Ann/Estr.ant.ft                          DIZSMAS    - ATTI
#define DT01CD     1		// Data ult.manut.                                       DIZSMAS    - DATS
#define NR01CD     2		// Numero azione di aggiornamento                        DIZSMAS    - NRAZ
#define CDDTCD     3		// Codice Ditta                                          DIZSMAS    - CDDT
#define AAPRCD     4		// Anno Operazione                                       DIZSMAS    - AAPR         Key   1
#define ANNPCD     5		// Anno Reg.DA GESTIRE                                   DIZSMAS    - ANNP
#define TPGICD     6		// Giornale IVA  TB=GI                                   DIZSMAS    - TPGI         Key   2
#define DTOPCD     7		// Data operazione                                       DIZSMAS    - DATS         Key   3
#define NONPCD     8		// Nr. Operaz./Nr. Prot.                                 DIZSMAS    - NONP         Key   4
#define NRRGCD     9		// Numero Riga 2                                         DIZSMAS    - NRR2         Key   5
#define PROGCD     10		// Progressivo                                           DIZSMAS    - PROG         Key   6
#define IMPOCD     11		// Importo  "-"=Avere                                    DIZSMAS    - IMPO
#define CDVACD     12		// Codice Valuta  TB=VA                                  DIZSMAS    - CDVA
#define CAMBCD     13		// Cambio                                                DIZSMAS    - CAMB
#define IMVACD     14		// Importo Valuta                                        DIZSMAS    - IMVA
#define SCADCD     15		// Data scadenza                                         DIZSMAS    - DATS
#define TIPOCD     16		// Tipo Effetto                                          DIZSMAS    - TIPO
#define GEINCD     17		//  * = Generato RCD su Insoluti                          DIZSMAS    - FLAG
#define CAMBCD2    18		// Cambio EURO                                           DIZSMAS    - CAME
#define IMVACD2    19		// Importo val2                                          DIZSMAS    - IMPO */

// Tracciato File: FGA5DAT/CGSPA00F - CGSPA : Scadenze partite aperte                                        9/12/09 17:43:12 Pag.    1
#define AT01PA     0		// Tipo provvisorio                                      DIZSMAS    - ATTI
#define CONTPA     1		// Gr. Conto Sottoconto                                  DIZSMAS    - CONT1
#define DIVIPA     2		// Divisione  TB=DI                                      DIZSMAS    - DIVI
#define AAOPPA     3		// Anno partita                                          DIZSMAS    - ANNO
#define NPARPA     4		// Nr Partita                                            DIZSMAS    - NPAR
#define NONPPA     5		// Nr. Operaz./Nr. Prot.                                 DIZSMAS    - NONP
#define DTRGPA     6		// Data registrazione                                    DIZSMAS    - DATS
#define IMPOPA     7		// Importo  "-"=Avere                                    DIZSMAS    - IMPO
#define CDVAPA     8		// Codice Valuta  TB=VA                                  DIZSMAS    - CDVA
#define CAMBPA     9		// Cambio                                                DIZSMAS    - CAMB
#define IMVAPA     10		// Importo Valuta                                        DIZSMAS    - IMVA
#define DTSCPA     11		// Data scadenza                                         DIZSMAS    - DATS
#define DTDOPA     12		// Data documento                                        DIZSMAS    - DATS
#define NRDOPA     13		// N� Documento                                          DIZSMAS    - NUDO
#define CDRAPA     14		// Codice rata Tab.ET                                    DIZSMAS    - TIPO
#define TIPOPA     15		// Tipo Effetto                                          DIZSMAS    - TIPO
#define DSTIPA     16		// Descr.tipo rata                                                  -
#define NREFPA     17		// Nr.effetto attivo                                     DIZSMAS    - NREF
#define NREPPA     18		// Nr.effetto passivo                                    DIZSMAS    - NREF
#define FL01PA     19		// Flag Generico                                         DIZSMAS    - FLAG
#define FL02PA     20		// Flag Generico                                         DIZSMAS    - FLAG
#define FL03PA     21		// Flag Generico                                         DIZSMAS    - FLAG
#define FL04PA     22		// Flag Generico                                         DIZSMAS    - FLAG
#define FL05PA     23		// Flag Generico                                         DIZSMAS    - FLAG
#define FL06PA     24		// Flag Generico                                         DIZSMAS    - FLAG
#define FL07PA     25		// Flag Generico                                         DIZSMAS    - FLAG
#define FL08PA     26		// Flag Generico                                         DIZSMAS    - FLAG
#define FL09PA     27		// Flag Generico                                         DIZSMAS    - FLAG
#define FL10PA     28		// Flag Generico                                         DIZSMAS    - FLAG
#define CAMBPA2    29		// Cambio EURO                                           DIZSMAS    - CAME
#define IMPOPA2    30		// Importo val 2                                         DIZSMAS    - IMPO
#define TIPOCF     31		// Creato da Roberto


TObject* TCausali_cache::key2obj(const char* key)
{
  // Metodo bastardo per evitare TToken_string temporanee "a randa"
  // sfrutto chiave a lunghezza fissa
  const int anno = atoi(key);
  const char* codice = key+5;
  TCausale* pcaus = new TCausale(codice, anno);
  return pcaus;
}

const TCausale& TCausali_cache::causale(const char* codice, int annoiva)
{
  // Metodo bastardo per evitare TToken_string temporanee "a randa"
  // creo chiave a lunghezza fissa anno+codice = 9999|AAA
  TString8 key;
  key.format("%04d|%s", annoiva, codice);
  return *(const TCausale*)objptr(key);
}

///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////

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

public:
  TImporta_sc_mask();
};
  
TImporta_sc_mask::TImporta_sc_mask() :TAutomask ("pi0001200a")
{
}  

bool TImporta_sc_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
{ 
	switch (f.dlg())
	{
		//giochetto per avere la lista dei files validi nella directory di trasferimento!
		case F_NAME:
			if (e == fe_button)
			{
				TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), 
                           "File@32");
				TFilename path = get(F_PATH);
				path.add("*.txt");	//files delle testate
				list_files(path, as.rows_array());
				TFilename name;
				FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
				{
					name = *row;
					*row = name.name();
				}
				if (as.run() == K_ENTER)
				{
					f.set(as.row(as.selected()));
				}
			}
			break;
		default:
			break;
	}
  return true;
}


///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TImporta_sc : public TSkeleton_application
{
	virtual bool check_autorization() const {return false;}
  virtual const char * extra_modules() const {return "ba";}

	TImporta_sc_mask*				  _msk;

//protected:


public:           
  virtual bool create();
  virtual bool destroy();
  virtual void main_loop();
	void build_table();
	void transfer(const TFilename& file);
 
  TImporta_sc() {};
};

bool build_rec(const TRelation& rel, void* pJolly)
{
	CHECK(pJolly != NULL, "Null Table");

	TTable * gmm = (TTable * ) pJolly;
	long nmov = rel.lfile().get_long(MOV_NUMREG);
	TString part = rel.lfile().get(MOV_DESCR);
	int p = part.find("Part. ");

	if (p >= 0)
	{
		p += 6;

		const int p1 = part.find(" ", p);

		gmm->zero();
		if (p1 > p)
			part.cut(p1);
		TString key(rel.lfile().get(MOV_TIPO));
		key << ',' << rel.lfile().get(MOV_CODCF) << ',' << part.mid(p);
		gmm->put("CODTAB", key);	
		gmm->put("I0", nmov);
		gmm->write_rewrite();
	}
	return true;
}

void TImporta_sc::build_table()
{
	TTable gmm("GMM");
	TCursor mov(new TRelation(LF_MOV));
	
	if (gmm.items() == 0)
		mov.scan(build_rec, &gmm, "Costruzione tabella di correlazione movimenti");
}

void TImporta_sc::transfer(const TFilename& file)
{
  TImporta_galileo_recset s(file);
  TProgind pi(s.items(),"Importazione saldaconto in corso ...",true,true);
	TConfig * conf = NULL;
	int anno = 0;
	int part;
	TString4 gruppo;
	TString4 conto;
	TString8 sottoconto;
	TString descr(50);
	TPartita * game = NULL;
	long nreg;
	TCausali_cache cache_causali;
	TLog_report log("Importazione partite");

  build_table();
	for (bool ok=s.move_first();ok;ok=s.move_next())
  {
    if (!pi.addstatus(1)) 
      break;
		
		const int a = s.get(AAOPPA).as_int();
	  const long p = s.get(NPARPA).as_int();

		if (a == 0)
			continue;

		if (anno != a || p != part )
		{
			anno = a;
			part = p;

			TToken_string key(25, ',');
			const TString tipocf = s.get(TIPOCF).as_string();
			const long codcf = atol(s.get(CONTPA).as_string().mid(4));

			key.add(tipocf);
			key.add(codcf);
			key.add(part);
			key.add(anno);

			nreg = cache().get("GMM", key).get_long("I0");

			if (nreg == 0)
			{
				const TString msg = format("Partita %s non trovata nei movimenti", (const char *) key);

				log.log(0, msg);
				continue;
			}
			if (game != NULL)
			{
				game->write();
				delete game;
			}
			game = NULL;
		}
		
    real residuo = s.get(IMPOPA).as_real();
		if (residuo !=ZERO)
		{
			TToken_string keymov;

			keymov.add(nreg);
			const TRectype & mov = cache().get(LF_MOV, keymov);

			keymov.add(1);

			const TRectype & rmov = cache().get(LF_RMOV, keymov);
			TBill clifo(rmov);

			const TCausale & c = cache_causali.causale(mov.get(MOV_CODCAUS), mov.get_int(MOV_ANNOIVA));
	    
			if (game == NULL)
				game = new TPartita(clifo, anno, format("%7d", part));

			TRiga_partite& partita = game->new_row();

			partita.put(PART_TIPOMOV, c.tipomov());
			partita.put(PART_DATAREG, mov.get(MOV_DATAREG)); 
			partita.put(PART_DATADOC, mov.get(MOV_DATADOC));
			partita.put(PART_NUMDOC, mov.get(MOV_NUMDOC));
			descr = s.get(DSTIPA).as_string();
			if (descr.blank())
				descr = mov.get(MOV_DESCR);
			partita.put(PART_DESCR, descr);
			partita.put(PART_CODCAUS, c.codice());
			partita.put(PART_REG, c.reg().name());
			partita.put(PART_SEZ, c.sezione(1));

			partita.put(PART_SOTTOCONTO, clifo.sottoconto());
			const TString8 codpag(mov.get(MOV_CODPAG));
			TPagamento pag(codpag);
			partita.put(PART_TIPOPAG, pag.n_rate() > 0 ? pag.tipo_rata(0) : _rim_dir);

			partita.put(PART_GRUPPOCL, clifo.gruppo());
			partita.put(PART_CONTOCL, clifo.conto());
			partita.put(PART_PROTIVA, mov.get(MOV_PROTIVA));
			int sign = residuo.sign();
	    
			TImporto importo(sign < 0 ? 'A' : 'D', abs(residuo));
			importo.normalize(c.sezione(1));
			partita.add(PART_IMPTOTDOC, importo.valore());
			partita.put(PART_IMPORTO, importo.valore());
	    
			TRiga_scadenze& scadenza = partita.new_row(); 

			scadenza.put(SCAD_CODPAG, codpag);
			scadenza.put(SCAD_DATASCAD, s.get(DTSCPA).as_string());
			scadenza.put(SCAD_IMPORTO, importo.valore());
			scadenza.put(SCAD_TIPOPAG, partita.get(PART_TIPOPAG));
		}
  }
	if (game != NULL)
	{
		game->write();
		delete game;
	}
  TReport_book b;
	b.add(log);
	b.print_or_preview();
}


bool TImporta_sc::create()
{
  _msk = new TImporta_sc_mask();
         
  return TSkeleton_application::create();
}

bool TImporta_sc::destroy()
{
	delete _msk;
  return TApplication::destroy();
}

void TImporta_sc::main_loop()
{
  KEY	tasto;
	tasto = _msk->run();
  if (tasto == K_ENTER)
  {
    //genero il nome del file da caricare
    TFilename name = _msk->get(F_PATH);
    name.add(_msk->get(F_NAME));
		transfer(name);
  }   
}


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


int pi0001200 (int argc, char* argv[])
{
  TImporta_sc main_app;
  main_app.run(argc, argv, TR("Importazione saldaconto"));
  return true;
}