#include <stdio.h>
#include	<Carbon/Carbon.h>

#define SYD_OSX 1
#include	"sy2types.h"

#define MGAEXT_CARBON_LIB 1
#include	"cm_xx_mga.h"
#include	"mgaclient.h"
#include	"xx_pgm_dict.st"
#include	"xx_xx_mgadict.st"

enum {
	// tipi PN
	T_GENERICO	= 1,
	T_IVA		= 2,
	T_IVACEE	= 3,
	T_CORRISP	= 4,
	T_CORRVENT	= 5
};

enum {
	// tipi causali contabili
	TPCC_GENERICO	= 1,
	TPCC_IVA_FORN	= 2,
	TPCC_NC_FORN	= 3,
	TPCC_IVA_CLI	= 4,
	TPCC_NC_CLI		= 5,
	TPCC_CORRISP	= 6
};

enum {
	// tipo gestione IVA
	TPGI_NOWORRY		= 1,
	TPGI_IVA_IMMED		= 2,
	TPGI_IVA_DIFFE		= 3,
	TPGI_INCASSO_DIFFE	= 4
};



#define QUERYTIMEINSECS 3


long last_ticks = -1;
long last_num_doc = 333;


MGAClientStats cs_data[30];

static int mga_console_callback(int cmd, int mgaaction, long par1, long par2, int wpar);
static int SpinProc(XNETLocalNameServerInfo *p, long par);
static int add_pn_IVA(void);
static int add_pn_generica(void);
static int add_documento_fiscale(void);
static char *l2s(char *s, long fln);

#ifdef SYD_WIN
#define WPU_TickCount()	((GetTickCount() * 6) / 100)
#else
#define WPU_TickCount()	TickCount()
#endif

#define MGAMAXTCPSERVER	20

XNETLocalNameServerInfo MGAEXTSERVERLIST[MGAMAXTCPSERVER];

int main (int argc, const char * argv[]) {
	int err, i, n, cardlen, xxerr, xc;
	long logres, user_recid, dbname;
	char uname[50], mgauser[40], password[20], mgakw[16], tableidstr[16], codecf[16], ipstr[32];
	char actkey[64];
	MGAServerStats thestats;
	long mgaextlibversion;
	
	long scanid;
	int num, ii, numclients;
	union {
		CARD_MGCF cf;
		CARD_MGSK sk;
		CARD_MGMG mg;
		CARD_MGRI ri;
		CARD_MGRO ro;
		CARD_MGRA ra;
		CARD_MGRM rm;
	} therec;
		
	printf ("Welcome to MGA Console!\n\n");
	
	if ((mgaextlibversion = MGAExtOpenServices(0)) >= 0) {
		if (mgaextlibversion != MGAEXTLIB_VERSION) {
			printf ("La versione della MGAEXTLIB e' errata!\n\n");
			goto xit_wrong_version;
		}
		
		
		MGAInit(/*mga_console_callback*/ nil);
		if ((xxerr = MGAStart(2, 0, MGARTFL_API_MODE)) >= 0) {
			
			if ((n = MGAGetServerList(&MGAEXTSERVERLIST[0], MGAMAXTCPSERVER, QUERYTIMEINSECS, SpinProc, MGA_TCP_MAX_MULTIPROGRAMS, MGA_TCP_OFFSET_MULTIPROGRAMS, WPU_TickCount())) > 0) {
				
				for (i = 0; i < n; i++) {
					sprintf(ipstr, "%d.%d.%d.%d", ((MGAEXTSERVERLIST[i].IPaddress) >> 24) & 0xff,\
							((MGAEXTSERVERLIST[i].IPaddress) >> 16) & 0xff,\
							((MGAEXTSERVERLIST[i].IPaddress) >> 8) & 0xff,\
							(MGAEXTSERVERLIST[i].IPaddress) & 0xff);
					printf ("\n%d -> %20.20s - %-20s IP: %s (%d/%d)\n", i, MGAEXTSERVERLIST[i].serverName, MGAEXTSERVERLIST[i].serverEntity, ipstr, MGAEXTSERVERLIST[i].connPort, MGAEXTSERVERLIST[i].regPort);
				}
				printf ("\n99 -> exit\n");
				
				printf("\n<Enter the number of the server to login> ");
				scanf("%d", &i);
				
				if (i != 99) {
					MGASetServer(&MGAEXTSERVERLIST[i]);
					
					// la chiave di attivazione che segue è valida per il programma DEMO
					// per far funzionare il login con un altro server sara' necessaria una
					// chiave di attivazione abbinata ad esso (quella di un client)
					
					
					printf("\n<Enter the activation key ('*' for demo)> ");
					scanf("%s", actkey);
					if (actkey[0] == '*') {
						strcpy(actkey, "EQSYYZ-NMG9MG-8FCQUT-AWJ8N8-25");
					}
					
					
					if ((logres = MGAExtLogin(actkey)) >= 0) {
						//mga_udp->chan_num = logres;
						printf ("Login OK.\n");
						
						if (MGANeedsUserName() != MGA_TBPU_DISABLED) {
						username_retry:
							printf("\n<Enter the username> ");
							scanf("%40s", uname);
							memset(mgauser, ' ', sizeof(mgauser));
							memmove(mgauser, uname, strlen(uname));
							printf("\n<Enter the password> ");
							scanf("%16s", password);
							memset(mgakw, ' ', sizeof(mgakw));
							memmove(mgakw, password, strlen(password));
							if ((err = MGAAuthenticateUser(uname, mgakw, &user_recid)) < 0) {
								printf ("!! error %d in MGAAuthenticateUser!\n", err);
								goto username_retry;
							}
							printf ("User Authentication OK.\n");
						}
						
						for (;;) {
							printf ("\n 0 - Logout\n");
							printf (" 1 - List DBCF             2 - List DBSK\n");
							printf (" 3 - List one table        4 - Get DBCF data from key\n");
							printf (" 5 - Add \"Prima nota IVA\"  6 - Add \"Prima nota Generica\"\n");
							printf (" 7 - MGAClientStats        8 - Test server\n");
							printf (" 9 - Stress server        10 - List ROWS\n");
							
							printf("\n<?> ");
							scanf("%d", &i);
							
							if (i == 0) break;
							
							switch (i) {
								case 1:
									dbname = 'DBCF';
									cardlen = sizeof(therec.cf);
									break;
								case 2:
									dbname = 'DBSK';
									cardlen = sizeof(therec.sk);
									break;
								case 3:
									printf("\n<Enter table ID> ");
									scanf("%4s", tableidstr);
									dbname = *(long *)tableidstr;
#ifdef SYD_WIN
									FlipDWordInd(&dbname);
#endif
									cardlen = sizeof(therec.sk);
									break;
								case 4:
									printf("\n<Enter key> ");
									scanf("%6s", tableidstr);
									// normalizziamo il codice a sei caratteri
									memset(codecf, ' ', sizeof(therec.cf.hCFCD));
									memmove(codecf, tableidstr, strlen(tableidstr));
									for (xc = 0; xc < sizeof(therec.cf.hCFCD); xc++) {
										codecf[xc] = toupper(codecf[xc]);
									}
									if ((xxerr = MGAGetArchFromKey('DBCF', 1, codecf, sizeof(therec.cf.hCFCD), &therec.cf, sizeof(therec.cf))) >= 0) {
										printf ("\nDBCF data OK: %40.40s - %40.40s\n\n", therec.cf.hCFDE, therec.cf.hCFLO);
									}
									else {
										printf("key %6.6s NOT FOUND! - err %d.\n", codecf, xxerr);
									}
									break;
								case 5:
									xxerr = add_pn_IVA();
									if (xxerr >= 0) {
										printf("\"Prima nota IVA\" added successfully\n\n", xxerr);
									}
									else {
										printf("Error %d adding \"Prima nota IVA\"\n\n", xxerr);
									}
									break;
								case 6:
									//xxerr = add_documento_fiscale();
									xxerr = add_pn_generica();
									if (xxerr >= 0) {
										printf("\"Prima nota Generica\" added successfully\n\n", xxerr);
									}
									else {
										printf("Error %d adding \"Prima nota Generica\"\n\n", xxerr);
									}
									break;
								case 7:
									if ((numclients = MGAGetClientStats(&cs_data[0])) >= 0) {
										printf("MGAGetClientStats ok %d clients\n\n", numclients);
										for (ii = 0; ii < numclients; ii++) {
											printf("#%2.2d - %4.4s * %s - %d \n", ii + 1, l2s(nil, cs_data[ii].mgadata.current_state), cs_data[ii].clientrec.u.rec.MachineName, cs_data[ii].mgadata.current_state);
										}
										printf("\n");
									}
									else {
										printf("Error %d in MGAGetClientStats\n\n", numclients);
									}
									break;
								case 8:
								case 9:
								{
									Sy2SimpleStopWatchData servertmr;
									long elapsed_time_in_ms, numreq;
									
									numreq = 0;
									//while (!WPU_Button()) {
									for (;;) {
										if (MGAGetAsyncModifiers() == (SY2_MOD_CTL | SY2_MOD_SHIFT)) break;
										
										MGAOpenSimpleStopWatch(&servertmr, 1);
										MGAStartSimpleStopWatch(&servertmr);
										xxerr = MGADeclareClientState(0);
										elapsed_time_in_ms = MGAGetSimpleStopWatch(&servertmr) / 1000;
										printf("#%8.8d returned: %d in %6.6d msec.\n", ++numreq, xxerr, elapsed_time_in_ms);
										if (i == 8) {
											for (;;) if ((MGAGetSimpleStopWatch(&servertmr) / 1000) > 4000) break;
										}
										MGAStopSimpleStopWatch(&servertmr);
									}
								}
									break;
								case 10:
								{
									int azienda;
									short numrow;
									long reclen, theref, *qtap;
									// CARD_MGRA radata;
									
									printf("\n<Enter DBID (for example DBRA)> ");
									scanf("%4s", tableidstr);
									dbname = *(long *)tableidstr;
#ifdef SYD_WIN
									FlipDWordInd(&dbname);
#endif
									printf("\n<Enter Numint> ");
									scanf("%d", &theref);
									
									printf("\n<Enter Azienda (1 based)> ");
									scanf("%d", &azienda);
									
									if (azienda <= 0) {
										azienda = 1;
									}
									
									
									// theref = 3490;
									MGAClientSetCurrentAzienda(azienda);
									switch (dbname) {
										case 'DBRI':
											reclen = sizeof(CARD_MGRI);
											qtap = (long *)&therec.ri.hRIQT[2];
											break;
										case 'DBRO':
											reclen = sizeof(CARD_MGRO);
											qtap = (long *)&therec.ro.hROQT[2];
											break;
										case 'DBRA':
											reclen = sizeof(CARD_MGRA);
											qtap = (long *)&therec.ra.hRAQT[2];
											break;
										case 'DBRM':
											reclen = sizeof(CARD_MGRM);
											qtap = (long *)&therec.rm.hRMQT[2];
											break;
										default:
											printf("DBID not yet supported!!\n");
											goto abort_10;
											break;
									}
									
									for (numrow = 1; numrow < 100; numrow++) {
										if (MGAGetNthDetail(dbname, theref, numrow, &therec, reclen) >= 0) {
											/***
											 if (numrow == 6) {
											 radata.hRARN = 2;
											 xxerr = MGAPutRecordFromRecID('DBRA', 0, &radata, sizeof(radata));
											 printf("MGAPutRecordFromRecID = %d\n", xxerr);
											 radata.hRARN = 3;
											 xxerr = MGAPutRecordFromRecID('DBRA', 0, &radata, sizeof(radata));
											 printf("MGAPutRecordFromRecID = %d\n", xxerr);
											 radata.hRARN = 4;
											 xxerr = MGAPutRecordFromRecID('DBRA', 0, &radata, sizeof(radata));
											 printf("MGAPutRecordFromRecID = %d\n", xxerr);
											 }
											 ***/
											printf("ref = %4.4d row = %4.4d %16.16s %40.40s %4.4d\n", theref, numrow, therec.ra.hRACA, therec.ra.hRADE, *qtap);
										}
									}
								}
								abort_10:
									break;
									
									/**
									 {
									 FILEHANDLE fh;
									 FileSpec fs;
									 
									 FAFileSpecFromFullPathName(&fs, "Macintosh HD:Tibet:mgatl192724240500.txt", true);
									 //FASetFileSpec(&fs, nil, FA_SETALL, 0, 0, "Macintosh HD:mgatl192724240500.txt");
									 fh = FAOpen(&fs, FA_RDPERM);
									 if ((xxerr = FAError(fh)) >= 0) {
									 printf("faopen ok\n");
									 FAClose(fh);
									 }
									 else {
									 printf("error in faopen: %d\n", xxerr);
									 }
									 }
									 ***/
							}
							
							// qui eseguiamo i primi tre comandi
							if (i >= 1 && i <= 3) {
								if ((xxerr = MGAGetServerStats(&thestats)) >= 0) {
									printf ("\nCurrent number of requests: %d\n", thestats.num_reqs);
								}
								else {
									printf ("!!!! errore %d in MGAGetServerStats !!!!\n", xxerr);
								}
								if ((scanid = MGAScanOpen(dbname, 1)) > 0) {
									printf ("\nMGAScanOpen OK.\n");
									num = 0;
									while (MGAScanNext(dbname, scanid, &therec, cardlen) >= 0) {
										if (dbname == 'DBCF') {
											printf ("%4.4d: %6.6s - %40.40s\n", ++num, therec.cf.hCFCD, therec.cf.hCFDE);
										}
										else if (dbname == 'DBSK') {
											printf ("%4.4d: %10.10s - %40.40s\n", ++num, therec.sk.hPCCD, therec.sk.hPCDE);
										}
										else {
											printf ("%4.4d: %40.40s\n", ++num, therec.sk.hPCCD);
										}
									}
									MGAScanClose(scanid);
									printf ("\nMGAScanClose OK.\n");
								}
								else {
									printf ("\nMGAScanOpen failed - err %d.\n", scanid);
								}
								
								if ((xxerr = MGAGetServerStats(&thestats)) >= 0) {
									printf ("\nCurrent number of requests: %d\n", thestats.num_reqs);
								}
								else {
									printf ("!!!! errore %d in MGAGetServerStats !!!!\n", xxerr);
								}
							}
							
						}
						MGALogout();
						printf ("Logged OUT.\n");
					}
					else {
						printf ("!!!! errore %d in MGALogin !!!!\n", logres);
						printf ("scrivi qualcosa e enter per uscire....\n", logres);
						scanf("%s", actkey);
					}
				}
				
			}
			else {
				printf ("Server non trovato!\n");
			}
			
			MGAEnd();
		}
		else {
			printf ("!!!! errore %d in MGAStart !!!!\n", xxerr);
		}
	xit_wrong_version:
		MGAExtCloseServices();
	}
	else {
		printf ("!!!! errore %d in MGAOpenExternalServices !!!!\n", mgaextlibversion);
	}
	return 0;
}


static int
SpinProc(XNETLocalNameServerInfo *p, long par)
{
	long xxticks, togo;
	
	xxticks = WPU_TickCount() - par;
	
	if ((xxticks % 15) == 0) {
		if (xxticks != last_ticks) {
			togo = QUERYTIMEINSECS*60 - xxticks;
			printf("querying server... %4.4d ticks to go\n", togo);
		}
		last_ticks = xxticks;
	}
	return(0);
}

static int
add_pn_generica(void)
{
	int res = 0;
	CARD_HGEN header_pn_gen;
	CARD_RGEN row_pn_gen;
	
	memset(&header_pn_gen, 0, sizeof(header_pn_gen));
	
	header_pn_gen.hMOTI = T_GENERICO;
	// long hMOFL;
	MGAStringToDate("311293", 6, 1, &header_pn_gen.hMODT);				// data di reg. 31/12/93
	memmove(header_pn_gen.hMOCA, "AA  ", sizeof(header_pn_gen.hMOCA));	// codice causale contabile
	memset(header_pn_gen.hMOND, ' ', sizeof(header_pn_gen.hMOND));		// numero documento (VUOTO per esempio)
	header_pn_gen.hMODD = header_pn_gen.hMODT;							// data documento uguale a data registrazione
	memset(header_pn_gen.hPAAG, ' ', sizeof(header_pn_gen.hPAAG));		// codice agente (VUOTO per esempio)
	// per ora niente IVA differita
	header_pn_gen.hMOGI = TPGI_NOWORRY;
	// long hMOFD;
	// unsigned char hMOTV[8];
	
	memset(&row_pn_gen, 0, sizeof(row_pn_gen));
	
	memmove(row_pn_gen.hRNDA, "01.01.01  ", sizeof(row_pn_gen.hRNDA));				// codice dare
	memmove(row_pn_gen.hRNAV, "01.01.02  ", sizeof(row_pn_gen.hRNAV));				// codice avere
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "101000", strlen("101000"), row_pn_gen.hRNID);	// importo dare 101.000
	MGACopyFixed(row_pn_gen.hRNID, VAL_FIX_LEN, row_pn_gen.hRNIA, VAL_FIX_LEN);		// idem per importo avere
	// nessun rif. partita aperta
	// char hRNAP[12];
	memmove(row_pn_gen.hRNDE, "Prova da MGAConsole     ", sizeof(row_pn_gen.hRNDE));	// descrizione
	
	if ((res = MGAAddMasterDetail('DBPN', T_GENERICO, &header_pn_gen, sizeof(header_pn_gen), &row_pn_gen, sizeof(row_pn_gen), 1, -1, nil)) >= 0) {	// per controllo
		res = MGAAddMasterDetail('DBPN', T_GENERICO, &header_pn_gen, sizeof(header_pn_gen), &row_pn_gen, sizeof(row_pn_gen), 1, 0, nil);
	}
	
	return(res);
}


static int
add_pn_IVA(void)
{
	int res = 0;
	
	CARD_HIVA header_pn_iva;
	CARD_RIVA row_pn_iva;
	char numstr[32];
	
	memset(&header_pn_iva, 0, sizeof(header_pn_iva));
	
	header_pn_iva.hMOTI = T_IVA;
	// long hMOFL;
	MGAStringToDate("311293", 6, 1, &header_pn_iva.hMODT);				// data di reg. 31/12/93
	memmove(header_pn_iva.hMOCA, "FV  ", sizeof(header_pn_iva.hMOCA));	// codice causale contabile
	// utilizziamo un numero progressivo per non duplicare le partite aperte
	MGABinToCString(sizeof(last_num_doc), (Sy2UBYTE *)&last_num_doc, numstr, sizeof(numstr), nil);
	last_num_doc++;
	memset(header_pn_iva.hMOND, ' ', sizeof(header_pn_iva.hMOND));		// numero documento
	memmove(header_pn_iva.hMOND, numstr, strlen(numstr));
	header_pn_iva.hMODD = header_pn_iva.hMODT;							// data documento uguale a data registrazione
	// questi (se vuoti) vengono assegnati in automatico
	memset(header_pn_iva.hMORI, ' ', sizeof(header_pn_iva.hMORI));		// cod registro IVA
	// long hMONP;														// protocollo IVA
	memmove(header_pn_iva.hMOCP, "RB3     ", sizeof(header_pn_iva.hMOCP));	// codice cond. pagamento
	memset(header_pn_iva.hMOCN, ' ', sizeof(header_pn_iva.hMOCN));	// niente incasso automatico
	memmove(header_pn_iva.hMOCF, "CA0001    ", sizeof(header_pn_iva.hMOCF));	// codice partita
	// nessun rif. partita aperta
	// char hMOAP[12];
	memset(header_pn_iva.hPAAG, ' ', sizeof(header_pn_iva.hPAAG));		// codice agente (VUOTO per esempio)
	// per ora niente IVA differita
	header_pn_iva.hMOGI = TPGI_NOWORRY;
	// long hMOFD;
	
	memset(&row_pn_iva, 0, sizeof(row_pn_iva));
	
	memmove(row_pn_iva.hRNCP, "20.01.01  ", sizeof(row_pn_iva.hRNCP));				// codice dare
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "101000", strlen("101000"), row_pn_iva.hRNIM);	// importo imponibile 101.000
	memmove(row_pn_iva.hRNCI, "19  ", sizeof(row_pn_iva.hRNCI));					// codice IVA
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "19190", strlen("19190"), row_pn_iva.hRNIV);		// importo imponibile 19.190
	memmove(row_pn_iva.hRNDE, "Prova da MGAConsole     ", sizeof(row_pn_iva.hRNDE));	// descrizione
	
	if ((res = MGAAddMasterDetail('DBPN', T_IVA, &header_pn_iva, sizeof(header_pn_iva), &row_pn_iva, sizeof(row_pn_iva), 1, -1, nil)) >= 0) {	// per controllo
		res = MGAAddMasterDetail('DBPN', T_IVA, &header_pn_iva, sizeof(header_pn_iva), &row_pn_iva, sizeof(row_pn_iva), 1, 0, nil);
	}
	
	return(res);
}



static int
add_documento_fiscale(void)
{
	int res = 0;
	
	CARD_MGDF header_df;
	CARD_MGRI row_df;
	CARD_MGCF cfdata;
	int cferr;
	
	memset(&header_df, 0, sizeof(header_df));
	
	// hDFNI; viene assegnato dal server
	memmove(header_df.hDFTD, "01", 2);									// vedi la tabella "tipologie documenti"
	header_df.hDFTI = 1;												// 1 ddt - 2 fattura - 3 nota credito
	//long hDFNR; potremmo assegnare un numero provvisorio, comunque viene assegnato al momento della conferma della stampa
	memset(header_df.hDFSU, ' ', sizeof(header_df.hDFSU));				// nessun suffisso
	MGAStringToDate("311202", 6, 1, &header_df.hDFDT);					// data del doc. 31/12/02
	memmove(header_df.hDFCC, "CA0001", 6);								// codice del cliente
	memmove(header_df.hDFKD, header_df.hDFCC, sizeof(header_df.hDFKD));	// destino uguale a fatturazione
	if ((cferr = MGAGetRecordFromKey('DBCF', 1, header_df.hDFCC, sizeof(header_df.hDFCC), &cfdata, sizeof(cfdata))) >= 0) {
		memmove(header_df.hDFDY, cfdata.hCFDE, sizeof(header_df.hDFDY));
		memmove(header_df.hDFDS, cfdata.hCFDS, sizeof(header_df.hDFDS));
		memmove(header_df.hDFIN, cfdata.hCFIN, sizeof(header_df.hDFIN));
		memmove(header_df.hDFLO, cfdata.hCFLO, sizeof(header_df.hDFLO));
		memmove(header_df.hDFCP, cfdata.hCFCP, sizeof(header_df.hDFCP));
		memmove(header_df.hDFPR, cfdata.hCFPR, sizeof(header_df.hDFPR));
		memmove(header_df.hDFPI, cfdata.hCFPI, sizeof(header_df.hDFPI));
		
		memmove(header_df.hDFDD, cfdata.hCFDE, sizeof(header_df.hDFDD));
		memmove(header_df.hDFDX, cfdata.hCFDS, sizeof(header_df.hDFDX));
		memmove(header_df.hDFDI, cfdata.hCFIN, sizeof(header_df.hDFDI));
		memmove(header_df.hDFDL, cfdata.hCFLO, sizeof(header_df.hDFDL));
		memmove(header_df.hDFCD, cfdata.hCFCP, sizeof(header_df.hDFCD));
		memmove(header_df.hDFPD, cfdata.hCFPR, sizeof(header_df.hDFPD));
	}
	else {
		printf("\nDBCF MGAGetArchFromKey failed - err %d.\n", cferr);
		// fai qualcosa ...
	}
	
	memset(header_df.hDFSC, ' ', sizeof(header_df.hDFSC));				// nessuno sconto in testata
	
	header_df.hDFAS = 1;		// addebito spese 1 = NO - 2 = SI
	memset(header_df.hDFAG, ' ', sizeof(header_df.hDFAG));				// nessun agente
	// hDFLS; nessun listino
	memset(header_df.hDFRF, ' ', sizeof(header_df.hDFRF));				// nessun riferimento ordine
	header_df.hDFRG = 1;		// raggr. ddt  1 = NO - 2 = SI
	header_df.hDFBF = 2;		// ddt da fatturare?  1 = NO - 2 = SI
	
	memset(header_df.hDFPG, ' ', sizeof(header_df.hDFPG));				// azzera il campo
	memmove(header_df.hDFPG, "RD3", 3);									// vedi la tabella "cond. pagamento"
	
	memset(header_df.hDFCB, ' ', sizeof(header_df.hDFCB));				// nessuna banca cliente
	memset(header_df.hDFBA, ' ', sizeof(header_df.hDFBA));				// nessun banca azienda
	
	memset(header_df.hDFAE, ' ', sizeof(header_df.hDFAE));				// azzera il campo
	memmove(header_df.hDFAE, "Cartoni", 7);								// aspetto esteriore
	
	header_df.hDFNC = 10;												// numero colli
	
	memset(header_df.hDFPT, ' ', sizeof(header_df.hDFPT));				// azzera il campo
	memmove(header_df.hDFPT, "franco", 6);								// porto
	
	memset(header_df.hDFPS, ' ', sizeof(header_df.hDFPS));				// azzera il campo
	memmove(header_df.hDFPS, "10 kg", 5);								// peso
	
	memset(header_df.hDFVO, ' ', sizeof(header_df.hDFVO));				// nessun volume
	
	
	header_df.hDFCM = 1;		// chi trasporta   1 = Mittente - 2 = destin. - 3 - vettore
	memset(header_df.hDFVT, ' ', sizeof(header_df.hDFVT));				// nessun vettore 1
	memset(header_df.hDFV2, ' ', sizeof(header_df.hDFV2));				// nessun vettore 2
	
	// niente spese
	//unsigned char hDFSI[2][8];
	//unsigned char hDFST[2][8];
	//unsigned char hDFSN[2][8];
	//unsigned char hDFSV[2][8];
	//unsigned char hDFSB[2][8];
	
	//Sy2Date hDFDA; nessuna data inizio trasporto
	//Sy2Time hDFOR; nessuna ora inizio trasporto
	
	memmove(header_df.hDFCA, "SCCL", 4);								// codice causale di magazzino
	
	memset(header_df.hDFCT, ' ', sizeof(header_df.hDFCT));				// azzera il campo
	memmove(header_df.hDFCT, "vendita", 7);								// causale del trasporto
	
	
	memmove(header_df.hDFMU, "01", 2);								// magazzino uscita
	memmove(header_df.hDFME, "01", 2);								// magazzino entrata
	memmove(header_df.hDFDU, "01", 2);								// tit. deposito uscita
	memmove(header_df.hDFDE, "01", 2);								// tit. deposito entrata
	
	//char hDFNO[60]; niente note
	memset(header_df.hDFVA, ' ', sizeof(header_df.hDFVA));				// nessuna valuta
	//unsigned char hDFUC[2][8]; quindi nessun cambio
	//long hDFNB; gestito dal server
	//Sy2Date hDFDB; gestito dal server
	
	memmove(header_df.hDFCN, "FV  ", 4);								// codice causale contabile
	
	//char hDFAD[12]; nessun rif. partite aperte
	
	memset(header_df.hDFZO, ' ', sizeof(header_df.hDFZO));				// abbinare eventuale codice zona a scopo statistico
	
	header_df.hDFSD = 1;	// scad. differito? 1 = NO - 2 = SI
	//long hDFN1;
	//long hDFF1;
	memset(header_df.hDFU1, ' ', sizeof(header_df.hDFU1));	
	//Sy2Date hDFD1;
	//unsigned char hDFM1[2][8];
	memset(header_df.hDFC1, ' ', sizeof(header_df.hDFC1));
	//unsigned char hDFX1[2][8];
	//long hDFN2;
	//long hDFF2;
	memset(header_df.hDFU2, ' ', sizeof(header_df.hDFU2));	
	//Sy2Date hDFD2;
	//unsigned char hDFM2[2][8];
	memset(header_df.hDFC2, ' ', sizeof(header_df.hDFC2));
	//unsigned char hDFX2[2][8];
	
	memset(header_df.hDFE3, ' ', sizeof(header_df.hDFE3));	// nessuna fattura scaduta 1
	//Sy2Date hDFD3;
	//unsigned char hDFT3[2][8];
	memset(header_df.hDFE4, ' ', sizeof(header_df.hDFE4));	// nessuna fattura scaduta 2
	//Sy2Date hDFD4;
	//unsigned char hDFT4[2][8];
	
	//unsigned char hDFCL[2][8];
	//unsigned char hDFCO[2][8];
	//unsigned char hDFII[2][8];
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "1000,50", strlen("1000,50"), header_df.hDFIM[1]);	// importo imponib. 1000,50
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "1937238", strlen("1937238"), header_df.hDFIM[0]);	// importo imponib. lit.
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "200,10", strlen("200,10"), header_df.hDFIV[1]);	// importo IVA 200,10
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "387448", strlen("387448"), header_df.hDFIV[0]);	// importo IVA lit.
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "1200,60", strlen("1200,60"), header_df.hDFTO[1]);	// importo totale 1200,60
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "2324686", strlen("2324686"), header_df.hDFTO[0]);	// importo totale lit.
	
	//short hDFSF;
	//short hDFIC;
	
	// nessuna scad. preimpostata
	//struct CARD__NXS {
	//	Sy2Date hDFS1;
	//	unsigned char hDFI1[2][8];
	//}	hDFXS[12];
	
	//long hDFFL;
	//long hDFNF;
	//char hDFFS[2];
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "1000,50", strlen("1000,50"), header_df.hRINI[1]);	// importo imponib. prima aliq. iva 1000,50
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "1937238", strlen("1937238"), header_df.hRINI[0]);	// importo imponib.  prima aliq. iva lit.
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "200,10", strlen("200,10"), header_df.hRIIV[1]);	// importo IVA  prima aliq. iva 200,10
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "387448", strlen("387448"), header_df.hRIIV[0]);	// importo IVA  prima aliq. iva lit.
	
	memmove(header_df.hRIAI, "20  ", 4);								// codice prima aliq. iva
	
	memset(header_df.hDFGS, ' ', sizeof(header_df.hDFGS));				// nessun accordo quadro
	memset(header_df.hDFCG, ' ', sizeof(header_df.hDFCG));				// abbinare eventuale codice raggr. a scopo statistico
	
	
	memset(&row_df, 0, sizeof(row_df));
	
	
	//long hRIDN; assegnato dal server
	//short hRIRN; assegnato dal server
	//long hRICR; assegnato dal server
	
	memset(row_df.hRICA, ' ', sizeof(row_df.hRICA));				// azzera il campo
	memmove(row_df.hRICA, "FL0190", 6);								// codice articolo
	
	memset(row_df.hRIDE, ' ', sizeof(row_df.hRIDE));				// azzera il campo
	memmove(row_df.hRIDE, "ATTACCO TIPO 1", 14);								// descrizione articolo
	
	memmove(row_df.hRIUM, "PZ  ", 4);								// unita' di misura
	
	MGABufToFixed(QTA_FIX_LEN, 0, 0, "15", strlen("15"), row_df.hRIQT);	// qta
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "110,90", strlen("110,90"), row_df.hRIPU[1]);	// importo unitario
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "214732", strlen("214732"), row_df.hRIPU[0]);	// importo unitario lit.
	
	memset(row_df.hRISC, ' ', sizeof(row_df.hRISC));				// no sconto di riga
	
	memmove(row_df.hRICI, "20  ", 4);								// codice aliquota iva
	
	memset(row_df.hRICP, ' ', sizeof(row_df.hRICP));				// azzera il campo
	memmove(row_df.hRICP, "20.01.01", 8);							// codice controp. contabile
	
	memset(row_df.hRICV, ' ', sizeof(row_df.hRICV));				// no valuta di riga
	
	//long hRINO; nessun ordine da evadere
	//short hRIRO;
	//long hRINP;
	
	memset(row_df.hRIAG, ' ', sizeof(row_df.hRIAG));				// no agente
	//unsigned char hRIPC[4];
	//unsigned char hRIPV[4];
	
	
	memset(row_df.hRICT, ' ', sizeof(row_df.hRICT));				// azzera il campo
	memmove(row_df.hRICT, "051A", 4);								// codice aliquota iva
	
	memset(row_df.hRIRI, ' ', sizeof(row_df.hRIRI));				// nessun rif. interno
	
	memset(row_df.hRITP, ' ', sizeof(row_df.hRITP));				// nessuna tipologia
	
	//unsigned char hRIMA[4];
	
	MGACopyFixed(row_df.hRIPU[1], VAL_FIX_LEN, row_df.hRIVA[1], VAL_FIX_LEN);		// importo unitario netto uguale a importo unitario
	MGACopyFixed(row_df.hRIPU[0], VAL_FIX_LEN, row_df.hRIVA[0], VAL_FIX_LEN);		// importo unitario netto lit.
	
	MGACopyFixed(row_df.hRIQT, QTA_FIX_LEN, row_df.hRIQF, QTA_FIX_LEN);		// qta fiscale uguale a qta
	
	MGACopyFixed(row_df.hRIVA[1], VAL_FIX_LEN, row_df.hRIVF[1], VAL_FIX_LEN);		// importo unitario fiscale uguale a importo unitario netto
	MGACopyFixed(row_df.hRIVA[0], VAL_FIX_LEN, row_df.hRIVF[0], VAL_FIX_LEN);		// importo unitario fiscale lit.
	
	MGABufToFixed(VAL_FIX_LEN, 2, 0, "133,08", strlen("133,08"), row_df.hRIVI[1]);	// importo unitario iva inclusa
	MGABufToFixed(VAL_FIX_LEN, 0, 0, "257678", strlen("257678"), row_df.hRIVI[0]);	// importo unitario iva inclusa lit.
	
	MGABufToFixed(PRC_FIX_LEN, 2, 0, "20,00", strlen("20,00"), row_df.hRIPI);	// percentuale IVA
	//long hRINL;
	//unsigned char hRIQL[6];
	row_df.hRIFL = 0x000f;	// stampa la riga su tutti i documenti
	//short hRIRM;
	//unsigned char hRIPA[2][8]; eventuale costo di acquisto per la riga in esame
	//unsigned char hRIPR[2][8]; eventuale prezzo di vendita per la riga in esame
	
	memset(row_df.hRIGS, ' ', sizeof(row_df.hRIGS));				// nessun accordo quadro
	
	//unsigned char hRIPM[2][8]; eventuale costo di riferimento per la riga in esame
	
	
	
	if ((res = MGAAddMasterDetail('DBDF', 0, &header_df, sizeof(header_df), &row_df, sizeof(row_df), 1, -1, nil)) >= 0) {	// per controllo
		res = MGAAddMasterDetail('DBDF', 0, &header_df, sizeof(header_df), &row_df, sizeof(row_df), 1, 0, nil);
	}
	
	return(res);
}

static char localstring[6];

static char *l2s(char *s, long fln)
{
	union {
		long a;
		char b[6];
	} u;
	char *os;
	
	if (s == 0) s = localstring;
	os = s;
	u.a = fln;
#ifdef	SYD_WIN
	*s++ = u.b[3];
	*s++ = u.b[2];
	*s++ = u.b[1];
	*s++ = u.b[0];
#else
	*s++ = u.b[0];
	*s++ = u.b[1];
	*s++ = u.b[2];
	*s++ = u.b[3];
#endif
	*s = 0;
	return(os);
}

static int
mga_console_callback(int cmd, int mgaaction, long par1, long par2, int wpar)
{
	register int res = 0;
	
	switch (cmd) {
		case MGACB_GET_STRING:
			switch(par1) {
				case 'ADMI':
					strcpy((char *)par2, "*Amministratore");
					break;
				default:
					*(char *)par2 = '\0';
					break;
			}
			break;
		case MGACB_INTERNAL_EXCEPTION:
			printf("MGA Internal Exception %d / %d", par1, par2);
			break;
		case MGACB_IDLE:
			//#ifndef SYD_WIN
			//		{
			//			EventRecord ev;
			//
			//			WaitNextEvent(0, &ev, 0, 0);
			//		}
			//#endif
			break;
	}
	return(res);
}
