/* node.h -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2009 */

/*

Copyright (c) 2005-2009 Made to Order Software Corp.

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and
associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

*/

#include	"sswf/libsswf_as.h"

namespace sswf
{
namespace as
{



// NOTE: The attributes (Attrs) are defined in the second pass
//	 whenever we transform the identifiers in actual attribute
//	 flags. While creating the tree, the attributes are always
//	 set to 0.

class Node
{
public:
				Node(node_t type /*, NodePtr *shell*/);
				Node(const Node& source, const Node& parent);
				~Node();

	void			AddRef(void);
	void			Release(void);

	void			SetInputInfo(const Input *input);
	void			CopyInputInfo(const Node *input);
	long			GetPage(void) const { return f_page; }
	long			GetPageLine(void) const { return f_page_line; }
	long			GetParagraph(void) const { return f_paragraph; }
	long			GetLine(void) const { return f_line; }
	const String&		GetFilename(void) const { return f_filename; }

	const Data&		GetData(void) const
				{
					return f_data;
				}
	void			SetData(const Data& data)
				{
					f_data = data;
				}

	unsigned long		GetAttrs(void) const
				{
					return f_attrs;
				}
	void			SetAttrs(unsigned long attrs)
				{
					f_attrs = attrs;
				}
	bool			HasSideEffects(void) const;

	bool			IsLocked(void) const
				{
					return f_lock != 0;
				}
	void			Lock(void)
				{
					f_lock++;
				}
	void			Unlock(void)
				{
					AS_ASSERT(f_lock > 0);
					f_lock--;
				}
	void			SetOffset(int offset)
				{
					f_offset = offset;
				}
	int			GetOffset(void) const
				{
					return f_offset;
				}
	void			ReplaceWith(Node *node);
	void			DeleteChild(int index);
	void			AddChild(NodePtr& child);
	void			InsertChild(int index, NodePtr& child);
	void			SetChild(int index, NodePtr& child);
	int			GetChildCount(void) const
				{
					return f_count;
				}
	NodePtr&		GetChild(int index) const;
	void			SetParent(Node *parent)
				{
					if(parent != 0) {
						AS_ASSERT(!f_parent.HasNode());
						f_parent.SetNode(parent);
					}
					else {
						f_parent.ClearNode();
					}
				}
	NodePtr&		GetParent(void)
				{
					return f_parent;
				}
	void			SetLink(NodePtr::link_t index, NodePtr& link)
				{
					AS_ASSERT(index < NodePtr::LINK_max);
					if(link.HasNode()) {
						AS_ASSERT(!f_link[index].HasNode());
						f_link[index].SetNode(link);
					}
					else {
						f_link[index].ClearNode();
					}
				}
	NodePtr&		GetLink(NodePtr::link_t index)
				{
					AS_ASSERT(index < NodePtr::LINK_max);
					return f_link[index];
				}

	void			AddVariable(NodePtr& variable);
	int			GetVariableCount(void) const
				{
					return f_var_count;
				}
	NodePtr&		GetVariable(int index) const;

	void			AddLabel(NodePtr& label);
	int			GetLabelCount(void) const
				{
					return f_label_count;
				}
	NodePtr&		GetLabel(int index) const;
	NodePtr&		FindLabel(const String& name) const;

	void			Display(FILE *out, int indent, NodePtr *parent, char c) const;

private:
	void			Init(void);

	int			f_refcount;
	int			f_lock;

	long			f_page;
	long			f_page_line;
	long			f_paragraph;
	long			f_line;
	String			f_filename;

	Data			f_data;
	unsigned long		f_attrs;
	NodePtr			f_parent;
	int			f_offset;		// offset (index) in parent array of children
	int			f_count;
	int			f_max;
	NodePtr *		f_children;
	NodePtr			f_link[NodePtr::LINK_max];
	int			f_var_count;
	int			f_var_max;
	NodePtr *		f_variables;
	int			f_label_count;
	int			f_label_max;
	NodePtr *		f_labels;
};






};	// namespace as
};	// namespace sswf
