//	Zinc Application Framework - GMGMT.CPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#include "testevt.hpp"
#include <z_prst.hpp>

class GeometryTestWindow : public ZafWindow
{
public:
	GeometryTestWindow(int left, int top);
	GeometryTestWindow(GeometryTestWindow &copy);
	GeometryTestWindow(const ZafIChar *name, ZafObjectPersistence &persist);
	virtual ZafEventType Event(const ZafEventStruct &event);
	virtual ZafWindowObject *Duplicate(void) { return (new GeometryTestWindow(*this)); }
};

GeometryTestWindow::GeometryTestWindow(int left, int top) : ZafWindow(left, top, 60, 8)
{
	Add(new ZafBorder);
	Add(new ZafMaximizeButton);
	Add(new ZafMinimizeButton);
	Add(new ZafSystemButton);
	Add(new ZafTitle(new ZafStringData("Geometry")));
}

ZafEventType GeometryTestWindow::Event(const ZafEventStruct &event)
{
	ZafEventType ccode = event.type;

	switch (ccode)
	{
	// Store the window, then load a copy of it from the dat file.
	case TST_STORE:
		{
			ZafStorage *storage = new ZafStorage(ZAF_ITEXT("test.znc"), ZAF_FILE_CREATE | ZAF_FILE_READWRITE);
			ZafObjectPersistence *persist = new ZafObjectPersistence(storage, zafDefaultDataConstructor, zafDefaultObjectConstructor);
			Write(*persist);
			storage->Save();
			GeometryTestWindow *newWin = new GeometryTestWindow(StringID(), *persist);
			windowManager->Add(newWin);
			delete persist;
			delete storage;
		}
		break;

	case TST_DUPLICATE:
		{
			ZafWindowObject *newWin = Duplicate();
			windowManager->Add(newWin);
		}
		break;

	default:
		ccode = ZafWindow::Event(event);
		break;
	}
	return (ccode);
}

GeometryTestWindow::GeometryTestWindow(const ZafIChar *name, ZafObjectPersistence &persist) :
	ZafWindow(name, persist)
{
	// Nothing to do.
}

GeometryTestWindow::GeometryTestWindow(GeometryTestWindow &copy): ZafWindow(copy)
{
	// Nothing to do.
}

int ZafApplication::Main(void)
{
	// Ensure main() is linked properly.
	LinkMain();

	GeometryTestWindow *win1 = new GeometryTestWindow(1, 1);

	ZafGeometryManager *geo = new ZafGeometryManager;

	// Status bar.
	ZafStatusBar *stat = new ZafStatusBar(0, 0, 0, 1);
	ZafString *string = new ZafString(0, 0, 15, new ZafStringData("String"));
	stat->Add(string);
	ZafTime *time = new ZafTime(15, 0, 15, new ZafTimeData);
	stat->Add(time);
	ZafAttachment *attach = new ZafAttachment(time, ZAF_ATCF_RIGHT);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(string, ZAF_ATCF_RIGHT);
	attach->SetStretch(true);
	attach->SetReference(time);
	attach->SetOppositeSide(true);
	attach->SetOffset(1);
	geo->Add(attach);
	stat->Add(geo);
	win1->Add(stat);

	// Client objects.
	geo = new ZafGeometryManager;
	ZafButton *topLeft = new ZafButton(0, 0, 15, 1, new ZafStringData("Store"));
	topLeft->SetSendMessageWhenSelected(true);
	topLeft->SetValue(TST_STORE);
	attach = new ZafAttachment(topLeft, ZAF_ATCF_LEFT);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(topLeft, ZAF_ATCF_TOP);
	attach->SetOffset(0);
	geo->Add(attach);
	ZafRelativeConstraint *rel = new ZafRelativeConstraint(topLeft, ZAF_RLCF_RIGHT);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	rel = new ZafRelativeConstraint(topLeft, ZAF_RLCF_BOTTOM);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	win1->Add(topLeft);

	ZafButton *bottomLeft = new ZafButton(0, 2, 15, 1, new ZafStringData("Duplicate"));
	bottomLeft->SetSendMessageWhenSelected(true);
	bottomLeft->SetValue(TST_DUPLICATE);
	attach = new ZafAttachment(bottomLeft, ZAF_ATCF_LEFT);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(bottomLeft, ZAF_ATCF_BOTTOM);
	attach->SetOffset(0);
	geo->Add(attach);
	rel = new ZafRelativeConstraint(bottomLeft, ZAF_RLCF_RIGHT);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	rel = new ZafRelativeConstraint(bottomLeft, ZAF_RLCF_TOP);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	win1->Add(bottomLeft);

	ZafButton *topRight = new ZafButton(15, 0, 15, 1, new ZafStringData("top right"));
	attach = new ZafAttachment(topRight, ZAF_ATCF_RIGHT);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(topRight, ZAF_ATCF_TOP);
	attach->SetOffset(0);
	geo->Add(attach);
	rel = new ZafRelativeConstraint(topRight, ZAF_RLCF_LEFT);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	rel = new ZafRelativeConstraint(topRight, ZAF_RLCF_BOTTOM);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	win1->Add(topRight);

	ZafButton *bottomRight = new ZafButton(15, 2, 15, 1, new ZafStringData("bottom right"));
	attach = new ZafAttachment(bottomRight, ZAF_ATCF_RIGHT);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(bottomRight, ZAF_ATCF_BOTTOM);
	attach->SetOffset(0);
	geo->Add(attach);
	rel = new ZafRelativeConstraint(bottomRight, ZAF_RLCF_LEFT);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	rel = new ZafRelativeConstraint(bottomRight, ZAF_RLCF_TOP);
	rel->SetRatio(66);
	rel->SetStretch(true);
	geo->Add(rel);
	win1->Add(bottomRight);

	ZafText *text = new ZafText(0, 4, 10, 5, new ZafStringData("This is a sample text object with geometry management attached. "
		"The window should be divided into nine equally sized sections, similar to a tic-tac-toe board. "
		"The four corners should each have a button that completely fills "
		"that section.  This text object should occupy the entire center section, "
		"with each corner touching the inner corner of one of the buttons. "
		"There is also a status bar at the bottom of the window, with a time "
		"field that should stay at the right edge of the status bar and a string "
		"field that stretches to fill the rest of the status bar space.", 1024));
	text->Add(new ZafScrollBar(0, 0, 0, 0));
	attach = new ZafAttachment(text, ZAF_ATCF_TOP);
	attach->SetReference(topLeft);
	attach->SetOppositeSide(true);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_LEFT);
	attach->SetReference(topLeft);
	attach->SetOppositeSide(true);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_RIGHT);
	attach->SetReference(topRight);
	attach->SetOppositeSide(true);
	attach->SetOffset(0);
	attach->SetStretch(true);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_BOTTOM);
	attach->SetReference(bottomLeft);
	attach->SetOppositeSide(true);
	attach->SetOffset(0);
	attach->SetStretch(true);
	geo->Add(attach);
	win1->Add(text);

	win1->Add(geo);

	GeometryTestWindow *win2 = new GeometryTestWindow(5, 5);

	geo = new ZafGeometryManager;

	ZafButton *store = new ZafButton(1, 1, 15, 1, new ZafStringData("Store"));
	store->SetSendMessageWhenSelected(true);
	store->SetValue(TST_STORE);
	win2->Add(store);
	rel = new ZafRelativeConstraint(store, ZAF_RLCF_LEFT);
	rel->SetCenter(true);
	rel->SetRatio(50);
	geo->Add(rel);

	ZafButton *duplicate = new ZafButton(16, 1, 15, 1, new ZafStringData("Duplicate"));
	duplicate->SetSendMessageWhenSelected(true);
	duplicate->SetValue(TST_DUPLICATE);
	win2->Add(duplicate);

	attach = new ZafAttachment(duplicate, ZAF_ATCF_LEFT);
	attach->SetOffset(10);
	geo->Add(attach);
	attach = new ZafAttachment(duplicate, ZAF_ATCF_TOP);
	attach->SetOffset(2);
	geo->Add(attach);
	attach = new ZafAttachment(duplicate, ZAF_ATCF_RIGHT);
	attach->SetStretch(true);
	attach->SetOffset(10);
	geo->Add(attach);
	attach = new ZafAttachment(duplicate, ZAF_ATCF_BOTTOM);
	attach->SetStretch(true);
	attach->SetOffset(2);
	geo->Add(attach);
	ZafDimensionConstraint *dim = new ZafDimensionConstraint(duplicate, ZAF_DNCF_HEIGHT);
	dim->SetMinimum(3);
	dim->SetMaximum(7);
	geo->Add(dim);
	dim = new ZafDimensionConstraint(duplicate, ZAF_DNCF_WIDTH);
	dim->SetMinimum(10);
	dim->SetMaximum(50);
	geo->Add(dim);
	rel = new ZafRelativeConstraint(duplicate, ZAF_RLCF_LEFT);
	rel->SetCenter(true);
	rel->SetRatio(50);
	geo->Add(rel);

	text = new ZafText(0, 10, 40, 2, new ZafStringData("This window has two buttons "
		"and a text field on it.  The Store button should stay the same size, "
		"but always remain centered side-to-side.  The Duplicate button should "
		"stretch to stay centered side-to-side.  It should also stretch downward. "
		"It has minimum and maximum widths and heights, however.  This text "
		"field should fill the bottom of the window.  It has a minimum height, "
		"that will prevent it from shrinking to nothing.", 1024));
	text->Add(new ZafScrollBar(0, 0, 0, 0));
	win2->Add(text);
	attach = new ZafAttachment(text, ZAF_ATCF_TOP);
	attach->SetOppositeSide(true);
	attach->SetReference(duplicate);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_LEFT);
	attach->SetStretch(true);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_RIGHT);
	attach->SetStretch(true);
	attach->SetOffset(0);
	geo->Add(attach);
	attach = new ZafAttachment(text, ZAF_ATCF_BOTTOM);
	attach->SetStretch(true);
	attach->SetOffset(0);
	geo->Add(attach);
	dim = new ZafDimensionConstraint(text, ZAF_DNCF_HEIGHT);
	dim->SetMinimum(2);
	geo->Add(dim);

	win2->Add(geo);

	zafWindowManager->Add(win1);
	zafWindowManager->Add(win2);

	// Get the user input.
	Control();

	// Return success.
	return (0);
}


