#pragma once

#include <assert.h>

#include <string>
#include <list>

using namespace std;

namespace Html {
	struct Node {
		typedef list< Node * > pointerList;

		enum Type {
			T_TAG,
			T_TEXT
		} type;
		
		Node *parent;
		pointerList subNodes;

		static struct Collector {
			pointerList elements;

			virtual ~Collector() {
				while( !pointerList.empty() ) {
					delete *pointerList.begin();
				}
			}
		} *collector;

		Node( Node *parent ) : parent( parent ) {
			assert( collector != 0 );
			collector->elements.push_back( this );
		}

		~Node() {
			if( parent ) {
				parent->subNodes.remove( this );
			}
			while( !subNodes.empty() ) {
				subNodes.begin().delete();
			}
			assert( collector != 0 );			
			collector->elements.remove( this );
		}
	};

	struct Element : Node {
		string tag;
		string attributes;
		string endTag;
	};

	struct Text : HtmlElement {
		string text;
	};

	struct Document {
		Node *root;
	};

	struct File {
		string file;
		const char *text;
		unsigned line;

		void ParseTag();
	};
