
#include <classes/layouter/windows.h>
#include <classes/layouter/boopsigadgets.h>
#include <classes/layouter/decorgadgets.h>
#include <classes/exec/libraries.h>
#pragma header

class SelectWindowCloseC : public WindowCloseHandlerC {
public:
	SelectWindowCloseC(class SelectWindowC &);
	VOID close();
private:
	class SelectWindowC &select;
};

class SelectListEventC : public GadgetEventC {
public:
	SelectListEventC() : GadgetEventC(), _exit(FALSE) { };
	VOID up(WindowC *w, GadgetC *, IntuiMessageC * );
	VOID keyDown(WindowC *w, GadgetC *g, IntuiMessageC *m);
	BOOL exit() { return _exit; };
protected:
	BOOL _exit;
};

class SelectOkEventC : public GadgetEventC {
public:
	SelectOkEventC() : GadgetEventC(), _exit(FALSE) { };
	VOID up(WindowC *, GadgetC *, IntuiMessageC * );
	BOOL exit() { return _exit; };
protected:
	BOOL _exit;
};

class SelectCancelEventC : public GadgetEventC {
public:
	SelectCancelEventC() : GadgetEventC(), _exit(FALSE) { };
	VOID up(WindowC *, GadgetC *, IntuiMessageC * );
	BOOL exit() { return _exit; };
protected:
	BOOL _exit;
};

class SelectWindowC : public StandardWindowC {
public:
	SelectWindowC(GTIDCMPortC &, ScreenC &);
	~SelectWindowC();
	VOID setList(EListC *);
	ENodeC *selected();
	virtual BOOL select();
	virtual BOOL ok();
	virtual BOOL cancel();
	virtual VOID update();
	ENodeC *selectModal(SignalsC &, EListC *, WindowListC *);
protected:
	EListC *eList;
private:
	PatterniC framepattern;
	LBBevelboxC frame;
	LBBevelboxC clear;
	SelectListEventC listEvent;
	LBListviewC listview;
	TransparentGroupLayoutC buttons;
	SelectOkEventC okEvent;
	SelectCancelEventC cancelEvent;
	LBIButtonC okButton, cancelButton;
	GeometryGroupC frameG;
	GeometryGroupC clearG;
	GeometryC listviewG;
	GeometryGroupC buttonsG;
	GeometryC okG, cancelG;
	SelectWindowCloseC wch;
	GadgetKeyHandlerC keys;
};

SelectWindowC::SelectWindowC(GTIDCMPortC &p, ScreenC &s)
	: StandardWindowC(p,s,&okButton,
		WA_SizeBBottom,TRUE,
		WA_SizeBRight,FALSE,
		TAG_END),
	  framepattern(
	   PIA_Standard,1,
	   IA_FGPen,SHINEPEN,
	   IA_BGPen,BACKGROUNDPEN,
	   TAG_END),
	  frame(*this,NULL,&framepattern,LAYOUT_AUTOSIZE,LAYOUT_AUTOSIZE,
	   BBA_Frame,FALSE,
	   TAG_END),
	  clear(*this,NULL,NULL,LAYOUT_AUTOSIZE,LAYOUT_AUTOSIZE,
	   BBA_Frame,TRUE,
	   IA_FrameType,FRAME_DEFAULT,
	   IA_Recessed,TRUE,
	   IA_EdgesOnly,FALSE,
	   TAG_END),
	  listEvent(),
	  listview(&listEvent,*this,LAYOUT_AUTOSIZE,LAYOUT_AUTOSIZE,
	   GA_RelVerify,TRUE,
	   TAG_END),
	  buttons(),
	  okEvent(),
	  cancelEvent(),
	  okButton(&okEvent,*this,LAYOUT_AUTOSIZE,LAYOUT_AUTOSIZE,
	   GA_Text,"_OK",
	   GA_RelVerify,TRUE,
	   TAG_END),
	  cancelButton(&cancelEvent,*this,LAYOUT_AUTOSIZE,LAYOUT_AUTOSIZE,
	   GA_Text,"_Abbrechen",
	   GA_RelVerify,TRUE,
	   TAG_END),
	  frameG(frame,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0),
	  clearG(clear,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0),
	  listviewG(listview,
	   LAYOUT_GROUP,NULL,0,LAYOUT_OPPBORDER,&buttonsG,-2,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0),
	  buttonsG(buttons,
	   LAYOUT_SIZE,NULL,0,LAYOUT_GROUP,NULL,0,
	   LAYOUT_GROUP,NULL,0,LAYOUT_GROUP,NULL,0),
	  okG(okButton,
	   LAYOUT_SIZE,NULL,0,LAYOUT_GROUP,NULL,0,
	   LAYOUT_PROCENTCENTER,NULL,20,LAYOUT_MAXSIZE,NULL,0),
	  cancelG(cancelButton,
	   LAYOUT_SIZE,NULL,0,LAYOUT_GROUP,NULL,0,
	   LAYOUT_PROCENTCENTER,&okG,80,LAYOUT_MAXSIZE,NULL,0),
	  wch(*this),
	  keys(*this)
{
	titlegadgets.add(frame);
	titlegadgets.add(clear);
	gadgets.add(listview);
	gadgets.add(okButton);
	gadgets.add(cancelButton);
	innerGeo.add(frameG);
	frameG.add(clearG);
	clearG.add(listviewG);
	clearG.add(buttonsG);
	buttonsG.add(okG);
	buttonsG.add(cancelG);
	okButton.disable(TRUE);
	keys.add("-rcommand -shift -upstroke a",cancelButton);
}

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

VOID SelectWindowC::setList(EListC *l)
{
	eList = l;
}

ENodeC *SelectWindowC::selected()
{
	ULONG i = listview.selected();
	if (i == ~0 || eList == NULL)
		return NULL;
	return eList->find(i);
}

BOOL SelectWindowC::select()
{
	okButton.disable(listview.selected() == ~0);
	return FALSE;
}

BOOL SelectWindowC::ok()
{
	close();
	return TRUE;
}

BOOL SelectWindowC::cancel()
{
	close();
	return TRUE;
}

VOID SelectWindowC::update()
{
	listview.setList(eList);
}

ENodeC *SelectWindowC::selectModal(SignalsC &sc, EListC *l, WindowListC *wl)
{
	setList(l);
	update();
	open();
	if (wl)
	{
		wl->setBusy(TRUE,this);
	};
	sc.loop();
	if (wl)
	{
		wl->setBusy(FALSE,this);
	};
	return selected();
}

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

SelectWindowCloseC::SelectWindowCloseC(SelectWindowC &s)
	: WindowCloseHandlerC(s),
	  select(s)
{
}

VOID SelectWindowCloseC::close()
{
	_exit = select.cancel();
}

VOID SelectListEventC::up(WindowC *w, GadgetC *, IntuiMessageC * )
{
	_exit = ((SelectWindowC *) w)->select();
}

VOID SelectListEventC::keyDown(WindowC *, GadgetC *g, IntuiMessageC *m)
{
	((BListC *) g)->setAttrs(m->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) ? LSA_Prev : LSA_Next,0);
};

VOID SelectOkEventC::up(WindowC *w, GadgetC *, IntuiMessageC * )
{
	_exit = ((SelectWindowC *) w)->ok();
}

VOID SelectCancelEventC::up(WindowC *w, GadgetC *, IntuiMessageC * )
{
	_exit = ((SelectWindowC *) w)->cancel();
}

LibraryBaseErrC GadToolsBase("gadtools.library",37);
LibraryBaseErrC UtilityBase("utility.library",37);
LibraryBaseErrC CxBase("commodities.library",37);
LibraryBaseErrC LayersBase("layers.library",37);
LibraryBaseErrC WorkbenchBase("workbench.library",37);

void  main()
{
	if (!LibraryBaseC::areAllOpen())
		return;

	// diese Klasse empfängt und verarbeitet alle Signale
	SignalsC sc;

	// öffentlichen Standardbildschirm sperren
	PublicScreenC screen();
	if (!screen.lock(NULL))
		return;

	// der IDCMPort (in der GadTools Version) für die Fenster
	GTIDCMPortC port;
	sc.add(port);

	GadgetUpHandlerC uphandler();
	port.add(uphandler);

	// Das Fenster
	SelectWindowC window(port,screen);

	// noch einen Ctrl C HandlerC zur Sicherheit einhängen
	CtrlCHandlerC ctrlchandler;
	sc.add(ctrlchandler);

	ENodeC m1("1. Element"),m2("2. Element"),m3("3. Element");
	EListC list;
	list.addTail(m1);
	list.addTail(m2);
	list.addTail(m3);

	window.selectModal(sc,&list,NULL);

}
