#pragma once

#include <Widgets/Definitions.h>
#include <Widgets/Basic/BorderData.h>
#include "../Base.h"
#include "../File.h"
#include "../Game/Animation.h"
#include "ResizableObject.h"
#include "Rectangle.h"
#include "Line.h"

namespace gorgon { namespace widgets {

	class BorderData;

	BorderData *LoadBorderData(Base *parent, File &file, std::istream &in, int Size);

	class BorderData : public gge::widgets::BorderDataResource, public Base {
		friend BorderData *LoadBorderData(gorgon::Base *parent, File &file, std::istream &in, int Size);
	public:

		BorderData() {
			Padding=0;
			Margins=0;
			AutoBorderWidth=true;
			BorderWidth=0;
		}

		virtual void Save(std::ostream &out) {
			auto start=WriteObjectStart(out, *this);


			auto propstart=WriteSectionStart(out, gge::widgets::GID::BorderData_Props);

			WriteLink(object, out);
			WriteTo(out, Margins);
			WriteTo(out, Padding);
			WriteTo(out, BorderWidth);
			WriteTo(out, (int)AutoBorderWidth);

			WriteEnd(out, propstart);

			WriteNames(out, *this, gge::widgets::GID::BorderData_Names, gge::widgets::GID::BorderData_Name);
			WriteSubItems(out, *this);


			WriteEnd(out, start);
		}

		virtual GID::Type GetGID() const {
			return gge::widgets::BorderDataResource::GetGID();
		}

		virtual void SetProvider(ResizableObject &object)  {
			gge::widgets::BorderDataResource::SetProvider(object);
		}

		static BorderData &CreateRectangleChainFrom(const std::string &templte, bool AutoBorder=false) {
			BorderData &bd=*new BorderData;
			ResizableObject &object=*new ResizableObject;
			Rectangle &rect=*new Rectangle;
			rect.ImportPNGs(templte);
			object.SetProvider(rect);
			object.gorgon::Base::Subitems.Add(rect);
			bd.SetProvider(object);
			bd.gorgon::Base::Subitems.Add(object);

			bd.AutoBorderWidth=false;
			return bd;
		}

		static BorderData &CreateLineChainFrom(const std::string &templte, bool AutoBorder=false, bool vertical=false) {
			BorderData &bd=*new BorderData;
			ResizableObject &object=*new ResizableObject;
			Line &line=*new Line;
			line.ImportPNGs(templte);
			if(vertical) line.Orientation=line.Vertical;
			object.SetProvider(line);
			object.gorgon::Base::Subitems.Add(line);
			object.SizeController=gge::graphics::SizeController2D::SingleMiddleCenter;
			bd.SetProvider(object);
			bd.gorgon::Base::Subitems.Add(object);

			bd.AutoBorderWidth=false;
			return bd;
		}

		static BorderData &CreateImageChainFrom(const std::string &filename, bool AutoBorder=false) {
			BorderData &bd=*new BorderData;
			ResizableObject &object=*new ResizableObject;
			Image &img=*new Image;
			img.ImportPNG(filename);
			object.SetProvider(img);
			object.gorgon::Base::Subitems.Add(img);
			object.SizeController=gge::graphics::SizeController2D::TileFit;
			bd.SetProvider(object);
			bd.gorgon::Base::Subitems.Add(object);

			bd.AutoBorderWidth=false;
			return bd;
		}

		virtual void Prepare(gge::GGEMain &main, File &file) {
			Base::Prepare(main,file);

			if(!object)
				object		= dynamic_cast<ResizableObject*>(file.Root().FindObject(target));
		}

		using gorgon::Base::Subitems;
	protected:

		virtual void SetProvider(gge::widgets::ResizableObjectResource &object)  {
			if(!dynamic_cast<gorgon::Base*>(&object))
				throw std::runtime_error("You may only add line resources derived from gorgon::Base");


			gge::widgets::BorderDataResource::SetProvider(object);
		}

	};	


}}
