#pragma once
#include "Definitions.h"
#include <Engine/GGEMain.h>
#include <Utils/SGuid.h>
#include <Utils/OrderedCollection.h>
#include <string>

namespace gorgon {

	class File;

	class Base {
	public:

		Base() : parent(NULL), file(NULL)
		{
			AssignNewGUID();
		}

		void SetParent(Base &parent) {
			this->parent=&parent;
			file=parent.file;
		}
		Base &GetParent() const {
			return *parent;
		}
		bool HasParent() const {
			return parent!=NULL;
		}
		void RemoveParent() {
			parent=NULL;
		}

		////This function shall return Gorgon ID of this resource
		virtual GID::Type GetGID() const = 0;

		////This function should save this resource
		virtual void Save(std::ostream &) = 0;

		////This function shall prepare this resource to be used
		/// after file is loaded, default behavior is to pass
		/// the request to children
		virtual void Prepare(gge::GGEMain &main, File &file);
		////This function shall resolve links or similar constructs
		virtual void Resolve(File &file);
		////Useful when loading the same file twice
		virtual void RenewAllGUIDs() {
			AssignNewGUID();
			for(auto res=Subitems.First();res.IsValid();res.Next())
				res->RenewAllGUIDs();
		}

		////This function tests whether this object has the given utils::SGuid
		bool isEqual(const gge::utils::SGuid &guid) const { return guid==this->guid; }

		void AssignNewGUID() {
			guid=gge::utils::SGuid::CreateNew();
		}
		gge::utils::SGuid GetGuid() const {
			return guid;
		}
		void SetGuid(gge::utils::SGuid guid) {
			this->guid=guid;
		}
		void SetName(const std::string &value) {
			name = value;
		}
		std::string GetName() const {
			return name;
		}
		void SetCaption(const std::string &value) {
			caption = value;
		}
		std::string GetCaption() const {
			return caption;
		}

		////Searches the public children of this resource object
		virtual Base *FindObject(gge::utils::SGuid guid);



		////Subitems that this resource object have. Some of the sub items
		/// can be hidden therefore, this is not guaranteed to be complete
		gge::utils::OrderedCollection<Base> Subitems;
		
	protected:
		File *file;
		Base *parent;

		////utils::SGuid to identify this resource object
		gge::utils::SGuid guid;
		////Name of this resource object
		std::string name;
		////Caption of this resource object
		std::string caption;

		void parent_modified() {}
	};

}