#include "../File.h"
#include "../Font.h"
#include "Textbox.h"

using gge::resource::ReadFrom;

namespace gorgon { namespace widgets {


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


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

		WriteTo(out, Duration);
		if(Font)
			SaveObject(out, *Font);
		else {
			gge::Font f;
			SaveObject(out, f);
		}
		WriteLink(InnerBorder, out);
		WriteLink(OuterBorder, out);
		WriteLink(Sound, out);
		if(SelectedFont)
			SaveObject(out, *SelectedFont);
		else {
			gge::Font f;
			SaveObject(out, f);
		}
		WriteLink(Overlay, out);

		WriteEnd(out, propstart);


		WriteNames(out, *this, gge::widgets::GID::Textbox_Element_Names, gge::widgets::GID::Textbox_Element_Name);
		WriteSubItems(out, *this);		


		WriteEnd(out, start);
	}

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

		if(InnerBorder || OuterBorder || Font)
			return;

		file.FindObject(innerborder, InnerBorder);
		file.FindObject(outerborder, OuterBorder);
		Font=new gge::Font((gge::Font)font);
		if(!Font->Theme)
			gge::utils::CheckAndDelete(Font);

		SelectedFont=new gge::Font((gge::Font)selectedfont);
		if(!SelectedFont->Theme)
			gge::utils::CheckAndDelete(SelectedFont);

		file.FindObject(sound, Sound);
		file.FindObject(overlay, Overlay);
	}

	TextboxElement *LoadTextboxElement(Base *parent, File &file, std::istream &in, int Size) {
		TextboxElement &te=*new TextboxElement;
		if(parent)
			te.SetParent(*parent);
		else
			te.RemoveParent();

		std::vector<namecaption> names;

		LoadEntries(in, Size, file, te, [&](GID::Type &gid, int size) -> bool {
			if(gid==gge::widgets::GID::Textbox_Element_Props) {
				ReadFrom(in, te.Duration);

				ReadFrom<int>(in);//gid
				int sz=ReadFrom<int>(in);//size
				te.font=gorgon::FontInitiator::Load(file, in, sz);

				te.innerborder.Load(in);
				te.outerborder.Load(in);
				te.sound.Load(in);

				ReadFrom<int>(in);
				sz=ReadFrom<int>(in);
				te.selectedfont=gorgon::FontInitiator::Load(file, in, sz);

				te.overlay.Load(in);

				return true;
			}
			else if(gid==gge::widgets::GID::Textbox_Element_Names) {
				LoadNames(in, size, names, gge::widgets::GID::Textbox_Element_Name);

				return true;
			}

			return false;
		}, names);

		return &te;
	}

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


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

		WriteLink(TypeSound, out);
		WriteTo(out, (int)Pointer);
		WriteLink(Selection, out);
		WriteLink(CaretPlace, out);
		WriteLink(Caret, out);
		WriteTo(out, DefaultSize);
		WriteTo(out, (int)Align);
		WriteLink(Scroller, out);
		WriteTo(out, AlphaAnimation);

		WriteLink(Normal, out);
		WriteLink(Hover, out);
		WriteLink(Focused, out);
		WriteLink(Disabled, out);

		WriteLink(NormalToHover, out);
		WriteLink(NormalToFocused, out);
		WriteLink(HoverToFocused, out);
		WriteLink(NormalToDisabled, out);

		WriteLink(HoverToNormal, out);
		WriteLink(FocusedToNormal, out);
		WriteLink(FocusedToHover, out);
		WriteLink(DisabledToNormal, out);

		WriteEnd(out, propstart);


		WriteNames(out, *this, gge::widgets::GID::Textbox_Names, gge::widgets::GID::Textbox_Name);
		WriteSubItems(out, *this);		


		WriteEnd(out, start);
	}

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

		if(Normal)
			return;

		file.FindObject(scroller, Scroller);
		file.FindObject(selection, Selection);
		file.FindObject(typesound, TypeSound);
		Placeholder *cp;
		file.FindObject(caretplace, cp);
		if(cp) {
			gge::utils::CheckAndDelete(CaretPlace);
			CaretPlace=cp;
		}
		file.FindObject(caret, Caret);


		file.FindObject(normal, Normal);

		file.FindObject(hover, Hover);

		file.FindObject(focused, Focused);

		file.FindObject(disabled, Disabled);


		file.FindObject(normaltohover, NormalToHover);

		file.FindObject(normaltofocused, NormalToFocused);

		file.FindObject(normaltodisabled, NormalToDisabled);

		file.FindObject(hovertofocused, HoverToFocused);


		file.FindObject(hovertonormal, HoverToNormal);

		file.FindObject(focusedtonormal, FocusedToNormal);

		file.FindObject(disabledtonormal, DisabledToNormal);

		file.FindObject(focusedtohover, FocusedToHover);

		updatemapping();
	}

	Textbox* LoadTextbox(Base *parent, File &file, std::istream &in, int Size) {
		Textbox &txt=*new Textbox;
		if(parent)
			txt.SetParent(*parent);
		else
			txt.RemoveParent();

		std::vector<namecaption> names;

		LoadEntries(in, Size, file, txt, [&](GID::Type &gid, int size) -> bool {
			if(gid==gge::widgets::GID::Textbox_Element_Props) {
				txt.typesound.Load(in);
				txt.Pointer=(gge::Pointer::PointerType)ReadFrom<int>(in);
				txt.selection.Load(in);
				txt.caretplace.Load(in);
				txt.caret.Load(in);
				ReadFrom(in, txt.DefaultSize);
				txt.Align=(gge::Alignment::Type)ReadFrom<int>(in);
				txt.scroller.Load(in);
				ReadFrom(in, txt.AlphaAnimation);

				txt.normal.Load(in);
				txt.hover.Load(in);
				txt.focused.Load(in);
				txt.disabled.Load(in);

				txt.normaltohover.Load(in);
				txt.normaltofocused.Load(in);
				txt.hovertofocused.Load(in);
				txt.normaltodisabled.Load(in);

				txt.hovertonormal.Load(in);
				txt.focusedtonormal.Load(in);
				txt.focusedtohover.Load(in);
				txt.disabledtonormal.Load(in);

				return true;
			}
			else if(gid==gge::widgets::GID::Textbox_Names) {
				LoadNames(in, size, names, gge::widgets::GID::Textbox_Name);

				return true;
			}

			return false;
		}, names);

		return &txt;
	}


}}
