/*******************************************************************************
 *	BIdl.cc		BEAM IDL Compiler
 *			T.Barnaby,	BEAM Ltd,	2/5/03
 *******************************************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <strings.h>
#include <bidl.h>
#include <GenBoap.h>
#include <GenBData.h>
#include <GenBDataPy.h>
#include <GenBDataMySql.h>

#define	DEBUG	1

/* External Functions used */
extern	int	yyparse();
extern	int	column, line;

BString		fileName;
TypeList	gtypelist;	// Ctypes list
Node*		result;

static void print(FILE* file, int tab, const char* fmt, ...){
	va_list	ap;
	
	va_start(ap, fmt);
	while(tab--)
		fprintf(file, "  ");
	vfprintf(file, fmt, ap);
}

void produceTree(Node* n, FILE* file, int tab){
	BIter	i;
	
	print(file, tab, "%s %s {\n", Node::nodeTypeName(n->nodeType()).retStr(), n->name().retStr());
	for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
		if(n->nodes()[i])
			produceTree(n->nodes()[i], file, tab + 1);
		else {
			print(file, tab + 1, "Null none {\n");
			print(file, tab + 1, "}\n");
		}
	}
	print(file, tab, "}\n");
}

int usage(){
	fprintf(stderr, "Usage: bidl [options] infile -o outfile\n");
	fprintf(stderr, "\t-m <mode>\t- Mode of operation (boap,bdata)\n");
	fprintf(stderr, "\t-b\t- Generate code for BEAM Objects\n");
	return 1;
}

int main(int argc, char **argv) {
	int		ret = 0;
	BString		inFileName;
	FILE*		fileDebug;
	int		a;
	BString		preProcessCmd = "cpp ";
	BString		baseFileName;
	BString		mode = "boap";
	Gen*		gen;
	int		n;
	int		flagBeamObjects = 0;

	if(argc == 1)
		return usage();

	for(a = 1; a < argc; a++){
		if(argv[a][0] == '-'){
			switch(argv[a][1]){
			case 'm':	mode = argv[++a];	break;
			case 'b':	flagBeamObjects = 1;	break;
			default:	return usage();
			}
		}
		else {
			inFileName = argv[a];
		}
	}

	// Setup mode of operation
	if(mode == "bdata"){
		gen = new GenBData;
	}
	else if(mode == "bdatapy"){
		gen = new GenBDataPy;
	}
	else if(mode == "bdatamysql"){
		gen = new GenBDataMySql;
	}
	else if(mode == "boap"){
		gen = new GenBoap;
	}
	else {
		fprintf(stderr, "Error: Unknown mode: %s\n", mode.retStr());
		return 1;
	}
	
	gen->setUseBObjects(flagBeamObjects);
	
	baseFileName = inFileName;
	if((n = baseFileName.findReverse('/')) >= 0)
		baseFileName = baseFileName.subString(n + 1, -1);
	if((n = baseFileName.findReverse('.')) >= 0)
		baseFileName = baseFileName.subString(0, n);
	
	// Preprocess input file
	preProcessCmd = preProcessCmd + " -nostdinc -C" + " -I/usr/beam/idl " + inFileName + " tmp.cpp";
	system(preProcessCmd);
	
	if(freopen("tmp.cpp", "r", stdin) == NULL){
		fprintf(stderr, "Unable to open: %s\n", inFileName.retStr());
		return 1;
	}

	
	// Process the input file
	if(ret = yyparse())
		return 1;

#if DEBUG
	if((fileDebug = fopen("bidl.i", "w")) == NULL){
		fprintf(stderr, "Unable to open: %s\n", "bidl.i");
		return 1;
	}
	fprintf(fileDebug, "TreeView:\n");
	produceTree(result, fileDebug, 0);
	fclose(fileDebug);
#endif

	gen->produce(result, baseFileName);

	unlink("tmp.cpp");	
	fclose(stdin);

	return ret;
}
