#include <classes/Intuition/Screen.h>

#include <classes/exec/lists.h>

#pragma -
#include <pragma/intuition_lib.h>
#pragma +

ScreenC::ScreenC(Tag tag1Type, ...)
	: inittags((struct TagItem *) &tag1Type)
{
	screen_ob = NULL;
}

ScreenC::ScreenC(struct TagItem *tags)
	: inittags(tags)
{
	screen_ob = NULL;
}

ScreenC::ScreenC(const ScreenC &s)
	: inittags(s.inittags)
{
	screen_ob = NULL;
}

ScreenC::~ScreenC()
{
	close();
}

ScreenC &ScreenC::operator= (const ScreenC &s)
{
	if (this != &s)
	{
		close();
		inittags = s.inittags;
		screen_ob = NULL;
	};
	return *this;
}

VOID ScreenC::open(struct TagItem *tagList)
{
	if (screen_ob)
		return;
	TagItemC t = inittags;
	t.append(tagList);
	if ((screen_ob = OpenScreenTagList(NULL,t.tags())) == NULL)
		throw ScreenX();
}

BOOL ScreenC::close()
{
	if (screen_ob)
	{
		BOOL r = CloseScreen(screen_ob);
		if (r)
			screen_ob = NULL;
		return r;
	};
	return TRUE;
}

VOID ScreenC::toFront()
{
	if (screen_ob)
	{
		ScreenToFront(screen_ob);
	};
}

VOID ScreenC::toBack()
{
	if (screen_ob)
	{
		ScreenToBack(screen_ob);
	};
}

VOID ScreenC::move(WORD dx, WORD dy)
{
	if (screen_ob)
	{
		MoveScreen(screen_ob,dx,dy);
	};
}

VOID ScreenC::beep(BOOL all)
{
	if (all)
		DisplayBeep(NULL)
	else if (screen_ob)
		DisplayBeep(screen_ob);
}

VOID ScreenC::showTitle(BOOL infront)
{
	if (screen_ob)
	{
		ShowTitle(screen_ob,infront);
	};
}

// ************************************************************

PublicScreenC::PublicScreenC(STRPTR name)
{
	pubname = name;
}

PublicScreenC::~PublicScreenC()
{
	unlock();
}

VOID PublicScreenC::open(struct TagItem *tagList)
{
	if (screen_ob)
		return;
	if (!lock(NULL))
		throw ScreenX();
}

BOOL PublicScreenC::close()
{
	unlock();
	return TRUE;
}

BOOL PublicScreenC::lock(STRPTR name)
{
	if (!screen_ob)
	{
		if (name)
			screen_ob = LockPubScreen(name)
		else
			screen_ob = LockPubScreen(pubname);
		return screen_ob != NULL;
	};
	return FALSE;
}

VOID PublicScreenC::unlock()
{
	if (screen_ob)
	{
		UnlockPubScreen(NULL,screen_ob);
		screen_ob = NULL;
	};
}

// ************************************************************

DrawInfoC::DrawInfoC()
{
	di = NULL;
	screen = NULL;
}

DrawInfoC::DrawInfoC(ScreenC &s)
{
	di = NULL;
	screen = NULL;
	if (!getInfo(s))
		throw ScreenDrawInfoX();
}

DrawInfoC::~DrawInfoC()
{
	freeInfo();
}

struct DrawInfo *DrawInfoC::getInfo(ScreenC &s)
{
	freeInfo();
	if (!s.screen())
		throw ScreenDrawInfoX();
	screen = s.screen();
	di = GetScreenDrawInfo(screen);
	if (!di)
		throw ScreenDrawInfoX();
	return di;
}

VOID DrawInfoC::freeInfo()
{
	if (di)
	{
		FreeScreenDrawInfo(screen,di);
		di = NULL;
	};
}

// *************************************************************

PublicScreenListC::PublicScreenListC()
	: infos(sizeof(PublicScreenInfoC),20)
{
}

VOID PublicScreenListC::update()
{
	infos.clear();
	ListC *screenlist = (ListC *) LockPubScreenList();
	if (screenlist)
	{
		PublicScreenInfoC *psi;
		ListCursorC lc(*screenlist);
		while (!lc.isDone()) {
			psi = &(PublicScreenInfoC &) infos.addTail();
			psi->screenname = ((PubScreenNode *) lc.item())->psn_Node.ln_Name;
			lc.next();
		};
	};
	UnlockPubScreenList();
}
