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

#include "maintest.hpp"

// This table contains the list of all attributes that can be set on this 
// object.  AttributeTable.count gets updated by GenericTestWin::Event().
// This list is used to create the attribute chack boxes in the attribute 
// list.
ListEntry ZAF_FARDATA GenericTestWin::AttributeTable[] =
{
	// ZafComboBox
	{ ZAF_ITEXT("View only"),       0, TST_TOGGLE_VIEW_ONLY },
	{ ZAF_ITEXT("Vertical scroll"),   0, TST_TOGGLE_VERTICAL_SCROLL },

	// ZafWindowObject
	{ ZAF_ITEXT("Bordered"),          0, TST_TOGGLE_BORDERED },
	{ ZAF_ITEXT("Visible *"),         0, TST_TOGGLE_VISIBLE },
	{ ZAF_ITEXT("Accept drop *"),     0, TST_TOGGLE_ACCEPT_DROP },
	{ ZAF_ITEXT("Auto update *"),     0, TST_TOGGLE_AUTOMATIC_UPDATE },
	{ ZAF_ITEXT("Changed *"),         0, TST_TOGGLE_CHANGED },
	{ ZAF_ITEXT("Copy Draggable *"),  0, TST_TOGGLE_COPY_DRAGGABLE },
	{ ZAF_ITEXT("Link Draggable *"),  0, TST_TOGGLE_LINK_DRAGGABLE },
	{ ZAF_ITEXT("Move Draggable *"),  0, TST_TOGGLE_MOVE_DRAGGABLE },
	{ ZAF_ITEXT("Focus *"),           0, TST_TOGGLE_FOCUS },
	{ ZAF_ITEXT("Noncurrent *"),     0, TST_TOGGLE_NONCURRENT },
	{ ZAF_ITEXT("Disabled *"),        0, TST_TOGGLE_DISABLED },
	{ ZAF_ITEXT("OSdraw"),            0, TST_TOGGLE_OSDRAW },
//	{ ZAF_ITEXT("Parentdraw border"), 0, TST_TOGGLE_PARENTDRAW_BORDER },
	{ ZAF_ITEXT("Parent palette"),    0, TST_TOGGLE_PARENTPALETTE },
//	{ ZAF_ITEXT("Parentdraw focus"),  0, TST_TOGGLE_PARENTDRAW_FOCUS },
//	{ ZAF_ITEXT("Selected *"),       0, TST_TOGGLE_SELECTED },
	{ ZAF_ITEXT("Edit mode"),       0, TST_TOGGLE_EDIT_MODE },
	{ ZAF_NULLP(ZafIChar),            0, 0 }
};

int CompareDescending(void *object1, void *object2)
{
	return (stricmp(((ZafWindowObject *)object2)->Text(), ((ZafWindowObject *)object1)->Text()));
}

// ---- Derived test object -------------------------------------------------

class TestObj : public ZafComboBox
{
public:
  	TestObj();
	ZafEventType Event(const ZafEventStruct &event);
};

TestObj::TestObj() : ZafComboBox(50, 1, 20, 3)
{
	// !!! MUST BE "TEST_OBJECT" so can initialize testObject pointer !!!
	SetStringID(ZAF_ITEXT("TEST_OBJECT"));
}

ZafEventType TestObj::Event(const ZafEventStruct &event)
{
	// Log the event and then pass to base class to be handled.
	ZafEventType ccode = LogicalEvent(event);
	GenericTestWin *testWin = DynamicPtrCast(parent, GenericTestWin);
	testWin->LogEvent(ccode);

	ccode = ZafComboBox::Event(event);

	if (ccode == S_CURRENT || ccode == S_NON_CURRENT)
	{
		ZafVtList *attrList= DynamicPtrCast(testWin->GetObject(ZAF_ITEXT("ATTR_LIST")), ZafVtList);
		attrList->GetObject((ZafNumberID)TST_TOGGLE_FOCUS)->SetSelected(Focus());
	}

	return (ccode);
}

// ---- Derived test window -------------------------------------------------

ObjectTestWin::ObjectTestWin() : GenericTestWin(1, 1, 80, 12)
{
	// The test object can place settings combo boxes, etc. in the area
	// 1, 8 (left, top) 47, 9 (right, bottom).

	// Test objects can be placed in the area to the right of the divider 
	// line.  So an area of 50, 1 (left, top) to 78, 9 (right, bottom) can
	// be used.  This area can be bigger or smaller simply by adjusting 
	// the size passed to the GenericTestWin constructor above.

	// Set the title text.
	SetText(ZAF_ITEXT("Combo"));

	// Add settings objects.
	Add(new ZafPrompt(1, 8, 15, new ZafStringData("# of new objects:")));
	ZafSpinControl *newObjSpin = new ZafSpinControl(18, 8, 8, new ZafIntegerData(1L));
	newObjSpin->SetStringID(ZAF_ITEXT("NEW_OBJ_SPIN"));
	newObjSpin->Add(new ZafInteger(0, 0, 0, new ZafIntegerData((long)0)));
	Add(newObjSpin);
	ZafButton *newObjButton = new ZafButton(27, 8, 10, 1, new ZafStringData("Add** ->"));
	newObjButton->SetAutoSize(false);
	newObjButton->SetValue(TST_ADD_OBJECTS);
	newObjButton->SetSendMessageWhenSelected(true);
	Add(newObjButton);

	// Create sort type combo box.
	ZafComboBox *sortTypeCombo = new ZafComboBox(1, 9, 20, 3);
	sortTypeCombo->SetStringID(ZAF_ITEXT("SORT_COMBO"));
	sortTypeCombo->SetViewOnly(true);
	sortTypeCombo->Add(new ZafScrollBar(0, 0, 0, 0, ZAF_NULLP(ZafScrollData)));
	ZafButton *attr = new ZafButton(0, 0, 15, 1, new ZafStringData("No sort *"));
	attr->SetButtonType(ZAF_FLAT_BUTTON);
	attr->SetHzJustify(ZAF_HZ_LEFT);
	attr->SetSendMessageWhenSelected(true);
	attr->SetValue(TST_SET_SORT_NONE);
	attr->SetStringID(ZAF_ITEXT("TST_SET_SORT_NONE"));
	sortTypeCombo->Add(attr);
	attr = new ZafButton(0, 0, 15, 1, new ZafStringData("Auto sort *"));
	attr->SetButtonType(ZAF_FLAT_BUTTON);
	attr->SetHzJustify(ZAF_HZ_LEFT);
	attr->SetSendMessageWhenSelected(true);
	attr->SetValue(TST_SET_SORT_AUTO);
	attr->SetStringID(ZAF_ITEXT("TST_SET_SORT_AUTO"));
	sortTypeCombo->Add(attr);
	attr = new ZafButton(0, 0, 15, 1, new ZafStringData("Reverse sort *"));
	attr->SetButtonType(ZAF_FLAT_BUTTON);
	attr->SetHzJustify(ZAF_HZ_LEFT);
	attr->SetSendMessageWhenSelected(true);
	attr->SetValue(TST_SET_SORT_REVERSE);
	attr->SetStringID(ZAF_ITEXT("TST_SET_SORT_REVERSE"));
	sortTypeCombo->Add(attr);

	Add(sortTypeCombo);

	// Add the test object.
	int cnt;
	testObject = new TestObj;
	ZafComboBox *combo = DynamicPtrCast(testObject, ZafComboBox);
	combo->Add(new ZafScrollBar(0, 0, 0, 0));
	for (cnt = 0; cnt < 10; cnt++)
	{
		ZafIChar buf[32];
		sprintf(buf, ZAF_ITEXT("Combo item %d"), cnt);
		ZafButton *comboObject = new ZafButton(0, 0, 15, 1, buf);
		comboObject->SetButtonType(ZAF_FLAT_BUTTON);
		comboObject->SetHzJustify(ZAF_HZ_LEFT);
		combo->Add(comboObject);
	}
	Add(testObject);

	// Add other objects needed to test the object.
	combo = new ZafComboBox(50, 8, 20, 3);
	combo->Add(new ZafScrollBar(0, 0, 0, 0));
	combo->SetAcceptDrop(true);
	combo->SetCopyDraggable(true);
	combo->SetMoveDraggable(true);
	for (cnt = 0; cnt < 10; cnt++)
	{
		ZafIChar buf[32];
		sprintf(buf, ZAF_ITEXT("Drag & drop %d"), cnt);
		ZafButton *comboObject = new ZafButton(0, 0, 15, 1, buf);
		comboObject->SetButtonType(ZAF_FLAT_BUTTON);
		comboObject->SetHzJustify(ZAF_HZ_LEFT);
		combo->Add(comboObject);
	}
	Add(combo);
}

ZafEventType ObjectTestWin::Event(const ZafEventStruct &event)
{
	ZafComboBox *combo = DynamicPtrCast(testObject, ZafComboBox);

	ZafEventType ccode = event.type;
	switch (ccode)
	{
	// TST_TOGGLE_*** sets testObject's attribute to the selected status of
	// the attribute check box.  It then updates the attribute check box
	// using the attribute accessor function to test if the attribute was
	// successfully set.
	case TST_TOGGLE_VERTICAL_SCROLL:
		{
			ZafScrollBar *vScroll = combo->list->VerticalScrollBar();

			if (!vScroll)
			{
				vScroll = new ZafScrollBar(0, 0, 0, 0);
				combo->Add(vScroll);
			}
			else
			{
				combo->Subtract(vScroll);
				delete vScroll;
			}
			attrList->GetObject((ZafNumberID)TST_TOGGLE_VERTICAL_SCROLL)->SetSelected(combo->list->VerticalScrollBar() ? true : false);

			// Make sure counts get updated.
			GenericTestWin::Event(event);
		}
		break;

	case TST_TOGGLE_VIEW_ONLY:
		{
			ZafWindowObject *attr = attrList->GetObject((ZafNumberID)TST_TOGGLE_VIEW_ONLY);
			combo->SetViewOnly(attr->Selected());
			attr->SetSelected(combo->ViewOnly());

			// Make sure counts get updated.
			GenericTestWin::Event(event);
		}
		break;

	case TST_ADD_OBJECTS:
		{
			static int newCnt = 1;
			ZafIChar buf[32];
			int addCnt = atoi(GetObject(ZAF_ITEXT("NEW_OBJ_SPIN"))->Text());

			for (int cnt = 0; cnt < addCnt; cnt++, newCnt++)
			{
				sprintf(buf, ZAF_ITEXT("New item %d"), newCnt);
				ZafButton *comboObject = new ZafButton(0, 0, 15, 1, buf);
				comboObject->SetButtonType(ZAF_FLAT_BUTTON);
				comboObject->SetHzJustify(ZAF_HZ_LEFT);
				combo->Add(comboObject);
			}
		}
		break;

	case TST_SET_SORT_NONE:
	case TST_SET_SORT_AUTO:
	case TST_SET_SORT_REVERSE:
		{
			if (ccode == TST_SET_SORT_NONE)
			{
				combo->SetCompareFunction(ZAF_NULLF(ZafCompareFunction));
				combo->SetAutoSortData(false);
			}
			else if (ccode == TST_SET_SORT_AUTO)
			{
				combo->SetCompareFunction(ZAF_NULLF(ZafCompareFunction));
				combo->SetAutoSortData(true);
				combo->Sort();
			}
			else if (ccode == TST_SET_SORT_REVERSE)
			{
				combo->SetCompareFunction((ZafCompareFunction)CompareDescending);
				combo->SetAutoSortData(false);
				combo->Sort();
			}

			ZafComboBox *sortCombo = DynamicPtrCast(GetObject(ZAF_ITEXT("SORT_COMBO")), ZafComboBox);
			if (!combo->AutoSortData() && !combo->CompareFunction())
				sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_NONE"))->SetSelected(true);
			else if (combo->AutoSortData())
				sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_AUTO"))->SetSelected(true);
			else if (combo->CompareFunction() == (ZafCompareFunction)CompareDescending)
				sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_REVERSE"))->SetSelected(true);
		}
		break;
		
	default:
		ccode = GenericTestWin::Event(event);
		break;
	}

	return (ccode);
}

void ObjectTestWin::SynchronizeAttributes()
{
	ZafComboBox *combo = DynamicPtrCast(testObject, ZafComboBox);
 
	// Preset attributes according to test object's settings.
	attrList->GetObject((ZafNumberID)TST_TOGGLE_VERTICAL_SCROLL)->SetSelected(combo->list->VerticalScrollBar() ? true : false);

	ZafComboBox *sortCombo = DynamicPtrCast(GetObject(ZAF_ITEXT("SORT_COMBO")), ZafComboBox);
	if (!combo->AutoSortData() && !combo->CompareFunction())
	{
		sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_NONE"))->SetSelected(true);
	}	
	else if (combo->AutoSortData())
  		sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_AUTO"))->SetSelected(true);
	else if (combo->CompareFunction() == (ZafCompareFunction)CompareDescending)
  		sortCombo->GetObject(ZAF_ITEXT("TST_SET_SORT_REVERSE"))->SetSelected(true);

	GenericTestWin::SynchronizeAttributes();
	attrList->GetObject((ZafNumberID)TST_TOGGLE_BORDERED)->SetDisabled(true);
}
