/*******************************************************************************
 *	Node.cc		C Node Object
 *			T.Barnaby,	BEAM Ltd,	20/2/02
 *******************************************************************************
 */

#include	<stdio.h>
#include	<Node.h>

BString Node::nodeTypeName(Node::NodeType t){
	switch(t){
	case TNONE:	return "None";
	case TLIST:	return "List";
	case TIDENT:	return "Ident";
	case TTYPE:	return "Type";
	case TFUNC:	return "Func";
	case TFUNCPARAM:	return "FuncParam";
	case TSTRUCT:		return "Struct";
	case TSTRUCTITEM:	return "StructItem";
	case TINTERFACE:	return "Interface";
	case TMODULE:	return "Module";
	case TTYPELIST:	return "List";
	case TTYPEARRAY:	return "Array";
	case TDIR:	return "Dir";
	case TTYPEDOMAIN:	return "TypeDomain";
	case TCOMMENT:	return "Comment";
	case TENUM:	return "Enum";
	case TAPIVERSION:	return "ApiVersion";

	default:	return "Unknown";
	}
}

Node::Node(NodeType nodeType, BString name) : onodeType(nodeType), oname(name){
}

Node::~Node(){
	BIter	i;
	
	for(onodes.start(i); !onodes.isEnd(i); ){
		delete onodes[i];
		onodes.del(i);
	}
}

Node::NodeType Node::nodeType(){
	return onodeType;
}

BString Node::name(){
	return oname;
}

BList<Node*>& Node::nodes(){
	return onodes;
}

Node* Node::node(int n){
	BIter	i;
	
	i = onodes.goTo(n);
	return onodes.get(i);
}

Node* Node::append(Node* n){
	onodes.append(n);
	return this;
}

Node* Node::appendList(Node* n){
	BIter	i;
	
	for(n->onodes.start(i); !n->onodes.isEnd(i); n->onodes.next(i)){
		onodes.append(n->onodes[i]);
	}
	return this;
}

BString Node::str(){
	BIter	i;
	BString	s = nodeTypeName(onodeType) + "::" + oname + "{";
	
	for(onodes.start(i); !onodes.isEnd(i); onodes.next(i)){
		s = s + onodes[i]->str() + " ";
	}
	s = s + "}";
	return s;
}

NodeOp1::NodeOp1(NodeType nodeType, BString name, Node* arg1): Node(nodeType, name){
	nodes().append(arg1);
}

NodeOp2::NodeOp2(NodeType nodeType, BString name, Node* arg1, Node* arg2): Node(nodeType, name){
	nodes().append(arg1);
	nodes().append(arg2);
}

NodeOp3::NodeOp3(NodeType nodeType, BString name, Node* arg1, Node* arg2, Node* arg3): Node(nodeType, name){
	nodes().append(arg1);
	nodes().append(arg2);
	nodes().append(arg3);
}

NodeOp4::NodeOp4(NodeType nodeType, BString name, Node* arg1, Node* arg2, Node* arg3, Node* arg4): Node(nodeType, name){
	nodes().append(arg1);
	nodes().append(arg2);
	nodes().append(arg3);
	nodes().append(arg4);
}

#ifdef ZAP
Node* test1(){
	Node*	a1 = new Node("1");
	Node*	a2 = new Node("2");
	
	return new NodeOp2("+", a1, a2);
}

int main(){
	Node*	a;
	
	a = test1();
	
	printf("Node: %s\n", a->str().retStr());
}
#endif
