/******************************************************************************
 GNBBaseNode.cc

	Copyright © 1999 by Glenn W. Bach. All rights reserved.

 *****************************************************************************/

#include "GNBBaseNode.h"
#include <GNBNoteNode.h>
#include <GNBCategoryNode.h>
#include <GNBToDoNode.h>

#include <JString.h>

#include <jAssert.h>


/******************************************************************************
 Constructor

******************************************************************************/

GNBBaseNode::GNBBaseNode
	(
	JNamedTreeNode* parent,
	const char* 	name,
	const JBoolean 	isBranch,
	Type 			type
	)
	:
	JNamedTreeNode(NULL, name, isBranch)
{
	itsType = type;
	if (parent != NULL)
		{
		parent->Append(this);
		}
}

GNBBaseNode::GNBBaseNode
	(
	Type 			type,
	JTree* 			tree,
	const char* 	name,
	const JBoolean 	isBranch
	)
	:
	JNamedTreeNode(tree, name, isBranch)
{
	itsType = type;
}


/******************************************************************************
 Destructor

******************************************************************************/

GNBBaseNode::~GNBBaseNode()
{
}

/******************************************************************************
 SaveNode (public)

 ******************************************************************************/

void
GNBBaseNode::SaveNode
	(
	ostream& 			os
	)
{
	if (!IsRoot())
		{
		os << GetName() << ' ';
		}
}

/******************************************************************************
 SaveBranch (public)

 ******************************************************************************/

void
GNBBaseNode::SaveBranch
	(
	ostream& 			os
	)
{
	assert(IsOpenable());
	SaveNode(os);
	const JSize count = GetChildCount();
	os << count << ' ';
	for (JSize i = 1; i <= count; i++)
		{
		JTreeNode* jnode = GetChild(i);
		GNBBaseNode* node = dynamic_cast(GNBBaseNode*, jnode);
		assert(node != NULL);
		JBoolean branch = node->IsOpenable();
		os << branch << ' ';
		os << (int)node->GetType() << ' ';
		if (branch)
			{
			node->SaveBranch(os);
			}
		else
			{
			node->SaveNode(os);
			}
		}
}

/******************************************************************************
 ReadBranchSetup (public)

 ******************************************************************************/

void
GNBBaseNode::ReadBranchSetup
	(
	istream& 			is,
	const JFileVersion 	version
	)
{
	assert(IsOpenable());
	JTree* tree;
	JBoolean ok = GetTree(&tree);
	assert(ok);
	ReadNodeSetup(is, version);
	JSize count;
	is >> count;
	for (JSize i = 1; i <= count; i++)
		{
		JBoolean branch;
		is >> branch;
		if (version == 0)
			{
			if (branch)
				{
				GNBCategoryNode* node = 
					new GNBCategoryNode(tree, "");
				assert(node != NULL);
				Append(node);
				node->ReadBranchSetup(is,version);
				}
			else
				{
				GNBNoteNode* node = 
					new GNBNoteNode(tree, "", 0);
				assert(node != NULL);
				Append(node);
				node->ReadNodeSetup(is, version);
				}
			}
		else if (version > 0)
			{
			int type;
			is >> type;
			GNBBaseNode* bnode;
			if (type == kCategoryNode)
				{
				GNBCategoryNode* node = 
					new GNBCategoryNode(tree, "");
				assert(node != NULL);
				Append(node);
				bnode = node;
				}
			else if (type == kNoteNode)
				{
				GNBNoteNode* node = 
					new GNBNoteNode(tree, "", 0);
				assert(node != NULL);
				Append(node);
				bnode = node;
				}
			else if (type == kToDoNode)
				{
				GNBToDoNode* node = 
					new GNBToDoNode(tree, "");
				assert(node != NULL);
				Append(node);
				bnode = node;
				}
			if (branch)
				{
				bnode->ShouldBeOpenable(branch);
				bnode->ReadBranchSetup(is,version);
				}
			else
				{
				bnode->ReadNodeSetup(is, version);
				}
			}
		}
}

/******************************************************************************
 ReadNodeSetup (public)

 ******************************************************************************/

void
GNBBaseNode::ReadNodeSetup
	(
	istream& 			is,
	const JFileVersion 	version
	)
{
	if (IsRoot())
		{
		return;
		}
	JString name;
	is >> name;
	SetName(name);
}

/******************************************************************************
 DiscardNode (public)

 ******************************************************************************/

void
GNBBaseNode::DiscardNode()
{

}

/******************************************************************************
 DiscardBranch (public)

 ******************************************************************************/

void
GNBBaseNode::DiscardBranch()
{
	assert(IsOpenable());
	const JSize count = GetChildCount();
	for (JSize i = count; i >= 1; i--)
		{
		JTreeNode* jnode = GetChild(i);
		GNBBaseNode* node = dynamic_cast(GNBBaseNode*, jnode);
		assert(node != NULL);
		JBoolean branch = node->IsOpenable();
		if (branch)
			{
			node->DiscardBranch();
			}
		else
			{
			node->DiscardNode();
			}
		delete node;
		}

}

/******************************************************************************
 FindChildNode (public)

 ******************************************************************************/

JBoolean
GNBBaseNode::FindChildNode
	(
	const JFAID_t 	id, 
	JTreeNode** 	node
	)
{
	assert(IsOpenable());
	const JSize count = GetChildCount();
	for (JSize i = 1; i <= count; i++)
		{
		JTreeNode* jnode = GetChild(i);
		JBoolean branch = jnode->IsOpenable();
		if (branch)
			{
			GNBBaseNode* bnode = dynamic_cast(GNBBaseNode*, jnode);
			assert(bnode != NULL);
			JBoolean found = bnode->FindChildNode(id, node);
			if (found)
				{
				return found;
				}
			}
		else
			{
			GNBNoteNode* nnode = dynamic_cast(GNBNoteNode*, jnode);
			assert(nnode != NULL);
			if (nnode->GetID() == id)
				{
				*node = nnode;
				return kTrue;
				}
			}
		}
	return kFalse;
}
