/*******************************************************************************
 *	Gen.cc		Default output
 *			T.Barnaby,	BEAM Ltd,	12/9/03
 *******************************************************************************
 */
#define	DEBUG	1

#include <stdio.h>
#include <stdarg.h>
#include <strings.h>
#include <Gen.h>
#include <bidl.h>

FileIndent::FileIndent(){
	oindent = 0;
}

void FileIndent::indentMore(){
	oindent++;
}

void FileIndent::indentLess(){
	if(--oindent < 0)
		oindent = 0;
}

int FileIndent::writeLine(BString line){
	BString	s;
	int	i = oindent;

	while(i--)
		s = s + "\t";
	s = s + line;
	return writeString(s);
}

Gen::Gen(){
	ouseBObjects = 0;
}

Gen::~Gen(){
}

int Gen::setUseBObjects(int on){
	int	ret = ouseBObjects;

	ouseBObjects = on;

	return ret;	
}

int Gen::getUseBObjects(){
	return ouseBObjects;
}

BString Gen::getTypeName(Node* n, int data){
	BString	typeName;
	
	if(ouseBObjects){
		if(n->nodeType() == Node::TTYPELIST){
			return BString("BObjListVar<") + getTypeName(n->node(0), data) + ">";
		}
		else {
			typeName = n->name();
			if(typeName == "Int32"){
				if(data)
					return "BObjInt";
				else
					return "Int32";
			}
			else if(typeName == "Bool"){
				if(data)
					return "BObjInt";
				else
					return "Int32";
			}
			else if(typeName == "String"){
				if(data)
					return "BObjString";
				else
					return "BString";
			}
			else if(typeName == "Error")	return "BError";
			else if(typeName == "Date")	return "BObjDate";
			else if(typeName == "DateTime")	return "BObjDateTime";
			else if(typeName == "Id")	return "BObjId";
			else if(typeName == "ObjData")	return "BObjData";
			else return typeName;
		}
	}
	else {
		if(n->nodeType() == Node::TTYPELIST){
			return BString("BList<") + getTypeName(n->node(0), data) + ">";
		}
		else if(n->nodeType() == Node::TTYPEARRAY){
			return BString("BArray<") + getTypeName(n->node(0), data) + ">";
		}
		else {
			typeName = n->name();
			if(typeName == "Int32"){
				return "Int32";
			}
			else if(typeName == "Bool"){
				return "Int32";
			}
			else if(typeName == "String"){
				return "BString";
			}
			else if(typeName == "Error")	return "BError";
			else if(typeName == "Date")	return "BObjDate";
			else if(typeName == "DateTime")	return "BObjDateTime";
			else if(typeName == "Id")	return "BObjId";
			else if(typeName == "ObjData")	return "BObjData";
			else return typeName;
		}
	}
}

int Gen::isRawType(Node* n){
	BString	typeName;
	Type*	t;
	BIter	i;

	typeName = n->name();
//	printf("isRawType: %d %s\n", n->nodeType(), typeName.retStr());

	if(n->nodeType() == Node::TTYPEARRAY){
		return 0;
	}
	else if(n->nodeType() == Node::TTYPE){
		if(typeName == "Int8")		return 1;
		else if(typeName == "UInt8")	return 1;
		else if(typeName == "Int16")	return 1;
		else if(typeName == "UInt16")	return 1;
		else if(typeName == "Int32")	return 1;
		else if(typeName == "UInt32")	return 1;
		else if(typeName == "Bool")	return 1;
		else if(typeName == "String")	return 0;
		else if(typeName == "Error")	return 0;
		else if(typeName == "Date")	return 0;
		else if(typeName == "DateTime")	return 0;
		else if(typeName == "Id")	return 0;
		else if(typeName == "ObjData")	return 0;
		else {
			if((t = gtypelist.search(typeName)) && (t->node())){
				return isRawType(t->node());
			}
			else{
				return 0;
			}
		}
	}
	else if(n->nodes().number()){
		for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
			if(!isRawType(n->nodes()[i]))
				return 0;
		}

		return 1;
	}
	else {
		return 1;
	}
}

int Gen::useCopyType(Node* n){
	BString	typeName;

	if(n->nodeType() == Node::TTYPE){
		typeName = n->name();
		
		if((typeName == "String") || (typeName == "Error"))
			return 1;
	}
	
	return isRawType(n);
}
