#include "../File.h"
#include "../Font.h"
#include "Panel.h"
#include "BorderData.h"
#include <Resource/ResizableObject.h>
#include "../Extended/Sound.h"
#include "Checkbox.h"

using gge::resource::ReadFrom;

namespace gorgon { namespace widgets {


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


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

		WriteTo(out, Duration);

		WriteLink(InnerBorder, out);
		WriteLink(OuterBorder, out);
		WriteLink(ScrollingBorder, out);

		WriteLink(Resizer, out);
		WriteLink(ResizerPlace, out);

		WriteTo(out, int(255-Opacity));
		WriteTo(out, int(255-BGOpacity));

		WriteLink(TitleBorder, out);
		WriteLink(DialogButtonBorder, out);
		
		WriteLink(Sound, out);

		WriteLink(Overlay, out);

		WriteEnd(out, propstart);


		WriteNames(out, *this, gge::widgets::GID::Panel_Element_Names, gge::widgets::GID::Panel_Element_Name);
		WriteSubItems(out, *this);		


		WriteEnd(out, start);
	}

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

		if(InnerBorder || OuterBorder || ScrollingBorder || Resizer || TitleBorder || DialogButtonBorder || Overlay)
			return;

		file.FindObject(innerborder, InnerBorder);
		file.FindObject(outerborder, OuterBorder);
		file.FindObject(scrollingborder, ScrollingBorder);
		file.FindObject(resizer, Resizer);
		file.FindObject(resizerplace, ResizerPlace);
		file.FindObject(titleborder, TitleBorder);
		file.FindObject(sound, Sound);
		file.FindObject(overlay, Overlay);
	}

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

		std::vector<namecaption> names;

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

				pe.innerborder.Load(in);
				pe.outerborder.Load(in);
				pe.scrollingborder.Load(in);

				pe.resizer.Load(in);
				pe.resizerplace.Load(in);

				pe.Opacity=255-ReadFrom<int>(in);
				pe.BGOpacity=255-ReadFrom<int>(in);

				pe.titleborder.Load(in);
				pe.dialogbuttonborder.Load(in);
				pe.sound.Load(in);
				pe.overlay.Load(in);

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

				return true;
			}

			return false;
		}, names);

		return &pe;
	}



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


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

		WriteTo(out, (int)Pointer);
		WriteTo(out, DefaultSize);

		WriteLink(Scroller, out);
		WriteLink(TitleLabel, out);
		WriteLink(TitleButton, out);
		WriteLink(TitleButtonPlace, out);

		WriteLink(DialogButton, out);
		WriteLink(DialogButtonPlace, out);

		WriteTo(out, AlphaAnimation);

		WriteLink(Normal, out);
		WriteLink(Active, out);
		WriteLink(Moving, out);
		WriteLink(Disabled, out);

		WriteLink(NormalToActive, out);
		WriteLink(ActiveToMoving, out);
		WriteLink(NormalToDisabled, out);

		WriteLink(ActiveToNormal, out);
		WriteLink(MovingToActive, out);
		WriteLink(DisabledToNormal, out);

		WriteEnd(out, propstart);


		WriteNames(out, *this, gge::widgets::GID::Panel_Names, gge::widgets::GID::Panel_Name);
		WriteSubItems(out, *this);


		WriteEnd(out, start);
	}

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

		if(Normal)
			return;

		file.FindObject(scroller, Scroller);

		file.FindObject(titlelabel, TitleLabel);
		file.FindObject(titlebutton, TitleButton);
		file.FindObject(titlebuttonplace, TitleButtonPlace);

		file.FindObject(dialogbutton, DialogButton);
		file.FindObject(dialogbuttonplace, DialogButtonPlace);


		file.FindObject(normal, Normal);
		file.FindObject(active, Active);
		file.FindObject(moving, Moving);
		file.FindObject(disabled, Disabled);


		file.FindObject(normaltoactive, NormalToActive);
		file.FindObject(normaltodisabled, NormalToDisabled);
		file.FindObject(activetomoving, ActiveToMoving);


		file.FindObject(activetonormal, ActiveToNormal);
		file.FindObject(disabledtonormal, DisabledToNormal);
		file.FindObject(movingtoactive, MovingToActive);

		updatemapping();

	}

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

		std::vector<namecaption> names;

		LoadEntries(in, Size, file, pnl, [&](GID::Type &gid, int size) -> bool {
			if(gid==gge::widgets::GID::Panel_Props) {
				pnl.Pointer=(gge::Pointer::PointerType)ReadFrom<int>(in);
				ReadFrom(in, pnl.DefaultSize);
				pnl.scroller.Load(in);
				pnl.titlelabel.Load(in);
				pnl.titlebutton.Load(in);
				pnl.titlebuttonplace.Load(in);
				pnl.dialogbutton.Load(in);
				pnl.dialogbuttonplace.Load(in);

				ReadFrom(in, pnl.AlphaAnimation);

				pnl.normal.Load(in);
				pnl.active.Load(in);
				pnl.moving.Load(in);
				pnl.disabled.Load(in);

				pnl.normaltoactive.Load(in);
				pnl.activetomoving.Load(in);
				pnl.normaltodisabled.Load(in);

				pnl.activetonormal.Load(in);
				pnl.movingtoactive.Load(in);
				pnl.disabledtonormal.Load(in);

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

				return true;
			}

			return false;
		}, names);

		return &pnl;
	}



}}
