#pragma once

#include "Base.h"

namespace gorgon {

	class Folder;

	Folder *LoadFolder(Base *parent, File &File, std::istream &Data, int Size);

	class Folder : public Base {
		friend class File;
		friend Folder *LoadFolder(Base *parent, File &File, std::istream &Data, int Size);
	public:

		Folder() : SignificantNames(false) {
		}

		Folder(const std::string &caption) : SignificantNames(false) {
			this->caption=caption;
		}

		//if you run into problems with dynamic_cast use CGet instead
		template <typename T_>
		T_ &Get(const std::string &Index) {
			for(auto it=Subitems.First();it.IsValid();it.Next()) {
				if(it->GetName()==Index)
					return dynamic_cast<T_&>(*it);
			}
			throw std::runtime_error("Requested item cannot be found");
		}

		//if you run into problems with dynamic_cast use CGetPtr instead
		template <typename T_>
		T_ *GetPtr(const std::string & Index) {
			for(auto it=Subitems.First();it.IsValid();it.Next()) {
				if(it->GetName()==Index)
					return dynamic_cast<T_*>(it.CurrentPtr());
			}

			return NULL;
		}

		//try to use Get instead of this
		template <typename T_>
		T_ &CGet(const std::string & Index) {
			for(auto it=Subitems.First();it.IsValid();it.Next()) {
				if(it->GetName()==Index)
					return (T_&)(*it);
			}

			throw std::runtime_error("Requested item cannot be found");
		}

		//try to use GetPtr instead of this
		template <typename T_>
		T_ *CGetPtr(const std::string & Index) {
			for(auto it=Subitems.First();it.IsValid();it.Next()) {
				if(it->GetName()==Index)
					return (T_*)it.CurrentPtr();
			}

			return NULL;
		}

		//if you run into problems with dynamic_cast use CGet instead
		template <typename T_>
		T_ &Get(int Index) {
			return dynamic_cast<T_&>(Subitems[Index]);
		}

		//if you run into problems with dynamic_cast use CGetPtr instead
		template <typename T_>
		T_ *GetPtr(int Index) {
			return dynamic_cast<T_*>(Subitems(Index));
		}

		//try to use Get instead of this
		template <typename T_>
		T_ &CGet(int Index) {
			return (T_&)(Subitems[Index]);
		}

		//try to use GetPtr instead of this
		template <typename T_>
		T_ *CGetPtr(int Index) {
			return (T_*)(Subitems(Index));
		}

		int GetCount() const {
			return Subitems.GetCount();
		}

		void Remove(gorgon::Base *item) {
			Subitems.Remove(item);
		}

		void Delete(gorgon::Base *item) {
			Subitems.Delete(item);
		}

		void RemoveAll() {
			Subitems.Clear();
		}

		void DeleteAll() {
			Subitems.Destroy();
		}

		////01010000h, (System, Folder)
		virtual GID::Type GetGID() const { return gge::resource::GID::Folder; }

		virtual void Save(std::ostream &);

		void Add(Base &item) {
			item.SetParent(*this);
			Subitems.Add(item);
		}

		void Add(Base *item) {
			if(item) Add(*item);
		}

		bool SignificantNames;

	protected:
		
	};

}
