#if !defined(BRLISTBX_H) && !defined(__BEDRC__)
#define BRLISTBX_H
//========================================================================================
//
//     File:			BRListBx.h
//     Release Version:	$ 1.0d1 $
//
//     Creation Date:	October 1991
//
//     COPYRIGHT 1991-93 SYMANTEC CORPORATION. ALL RIGHTS RESERVED. UNPUBLISHED -- RIGHTS
//     RESERVED UNDER THE COPYRIGHT LAWS OF THE UNITED STATES. USE OF COPYRIGHT NOTICE IS
//     PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION OR DISCLOSURE.
//
//     THIS SOFTWARE Contains PROPRIETARY AND CONFIDENTIAL INFORMATION OF SYMANTEC
//     CORPORATION. USE, DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE PRIOR
//     EXPRESS WRITTEN PERMISSION OF SYMANTEC CORPORATION.
//
//     RESTRICTED RIGHTS LEGEND
//     Use, duplication, or disclosure by the Government is subject to restrictions as Set
//     forth in subparagraph (c)(l)(ii) of the Rights in Technical Data and Computer
//     Software clause at DFARS 252.227-7013. Symantec Corporation, 10201 Torre Avenue,
//     Cupertino, CA 95014.
//
//========================================================================================

#ifndef BRLISTBX_K
#include "BRListBx.k"
#endif

#ifndef BRCONTRO_H
#include "BRContro.h"
#endif

#ifndef BROWCNV_H
#include "BrOwCnv.h"
#endif

#ifndef BRSUPDEF_H
#include "BRSupDef.h"
#endif

#ifndef BRDEBUG_H
#include "BRDebug.h"
#endif

#ifndef BCCOLL_H
#include "BCColl.h"
#endif

#if defined(BR_BUILD_MAC) && !defined(__LISTS__)
#include <Lists.h>
#endif

#if defined(BR_BUILD_WIN) && !defined(__DOS_H)
#include <dos.h>
#endif


//========================================================================================
// Forward class declarations
//========================================================================================

class BR_CListBox;
class BR_CListBoxBase;
class BR_CEntryListBox;
class BR_CItemHelper;


//========================================================================================
// Constants
//========================================================================================

const short kOwnerDrawDefProcID = 1;
const short kMaxClassNameLength = 64;


//========================================================================================
// CLASS BR_CFileListFillHelper
//========================================================================================

class BR_CFileListFillHelper : public BR_CObject
{
public:
	BR_CFileListFillHelper(BR_CListBoxBase* listBox);
	~BR_CFileListFillHelper();

	virtual unsigned short FillList(const BR_TString<BR_Char>& filePattern,
									unsigned short flags);

private:
	BR_CListBoxBase* fListBox;

#ifdef BR_BUILD_WIN
public:
	enum Attribute
	{
		kNormal = FA_NORMAL, kReadOnly = FA_RDONLY, kHidden = FA_HIDDEN, kSystem = FA_SYSTEM, kLabel = FA_LABEL, kDirectory = FA_DIREC, kArchive = FA_ARCH
	};
#endif

};


//========================================================================================
// CLASS BR_CStringListFillHelper
//========================================================================================

class BR_CStringListFillHelper : public BR_CObject
{
public:
	BR_CStringListFillHelper(BR_CListBoxBase* listBox);
	~BR_CStringListFillHelper();

	virtual unsigned short FillList(BR_CStringList& stringList);
	virtual unsigned short FillList(BR_CModule& module,
									BR_ResourceId resourceId);

private:
	BR_CListBoxBase* fListBox;
};


//========================================================================================
// STRUCT BR_SDispatchListDefProc
//
//		This is the structure of the list def proc that is used to dispatch a routine
//		in Bedrock that actually implements the list def proc. This structure is used
//		to patch up the destination address of the jump instruction to point to the
//		Bedrock routine.
//
//========================================================================================

struct BR_SDispatchListDefProc
{
	short fBranchInstruction;
	short fFlags;
	unsigned char fResourceType[6];
	short fResourcdID;
	short fVersion;
	short fJmpInstruction;
	void* fJmpAddress;
};


//========================================================================================
// STRUCT BR_SListBoxBaseResource
//========================================================================================

struct BR_SListBoxBaseResource : BR_SControlResource
{
};


//========================================================================================
//	CLASS BR_CListBoxBase
//
//		This is an abstract class for list boxes and fEntryArray list boxes. It defines
//		the protocol common to both list boxes and fEntryArray list boxes.
//========================================================================================

class BR_CListBoxBase : public BR_CControl
{
public:
	typedef unsigned short int ItemIndex;

	// The following methods define the public interface for list boxes. Implementation
	// for each of these methods must be defined by derived classes.

	virtual ItemIndex AddItem(BR_CObject* item) = 0;
	virtual ItemIndex FindItem(const BR_CObject& item,
							   ItemIndex firstIndex) const = 0;
	virtual ItemIndex FindItemBeginningWith(const BR_TString<BR_Char>& text,
											ItemIndex firstIndex) const;
	virtual ItemIndex GetCount() const = 0;
	virtual ItemIndex GetCurrentSelection() const = 0;
	virtual BR_CObject* GetItem(ItemIndex index) const = 0;
	virtual BR_CView* GetItemEnclosure() const = 0;
	virtual ItemIndex GetNoItemsSelected() const = 0;
	virtual ItemIndex GetSelectedItems(BC_TCollection<ItemIndex> &selectedItems) const = 0;
	virtual void GetTextFromItem(ItemIndex index,
								 BR_TString<BR_Char>& text) const = 0;
	virtual ItemIndex GetTopItem() const = 0;
	virtual ItemIndex InsertItem(ItemIndex index,
								 BR_CObject* item) = 0;
	virtual BR_Boolean IsItemSelected(ItemIndex itemNo) const = 0;
	virtual ItemIndex RemoveItem(ItemIndex itemNo) = 0;
	virtual void RemoveAll();
	virtual void Reset();
	virtual void SelectItem(ItemIndex itemNo) = 0;
	virtual void SelectRange(ItemIndex firstItem,
							 ItemIndex lastItem) = 0;
	virtual void SetCurrentSelection(ItemIndex itemNo) = 0;
	virtual void SetTopItem(ItemIndex itemNo) = 0;
	virtual void UnselectItem(ItemIndex itemNo) = 0;
	virtual void UnselectRange(ItemIndex firstItem,
							   ItemIndex lastItem) = 0;

	// The following methods provide implementation sharing for all list boxes.

	virtual BR_Boolean GetDeleteOnRemoval() const;
	virtual void SetDeleteOnRemoval(BR_Boolean deleteOnRemoval);

protected:
	BR_CListBoxBase(BR_CView* enclosure,
					BR_CBureaucrat* supervisor,
					BR_CItemHelper* itemHelper,
					BR_Distance width,
					BR_Distance height,
					BR_Coordinate x,
					BR_Coordinate y,
					ViewSizing horizontalSizing,
					ViewSizing verticalSizing,
					ViewId viewId,
					ViewStyle style);

	BR_CListBoxBase(BR_CView* enclosure,
					BR_CBureaucrat* supervisor,
					const BR_CModule& module,
					BR_SResource& viewResource);

	~BR_CListBoxBase();

	virtual void DeleteItem(BR_CObject* itemPtr);

private:
	BR_Boolean fDeleteOnRemoval;

#ifdef BR_BUILD_WIN
protected:
	// Some helper methods to take advantage of some implementation sharing.
	unsigned short SendListMsg(WORD message,
							   WORD itemIndex,
							   BR_CObject* item) const;
	unsigned short SendListMsg(WORD message,
							   WORD itemIndex,
							   long lParam) const;
	unsigned short SendListMsg(WORD message,
							   WORD item) const;
#endif

	BR_SETCLASSNAME(BR_CListBoxBase);
};

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
// BR_CListBoxBase::SendListMsg
//----------------------------------------------------------------------------------------

inline unsigned short BR_CListBoxBase::SendListMsg(WORD message,
												   WORD itemIndex,
												   BR_CObject* item) const
{
	return (unsigned short)::SendMessage(GetPlatformWindow(), message, itemIndex, (long)item);
}

//----------------------------------------------------------------------------------------
// BR_CListBoxBase::SendListMsg
//----------------------------------------------------------------------------------------

inline unsigned short BR_CListBoxBase::SendListMsg(WORD message,
												   WORD itemIndex,
												   long lParam) const
{
	return (unsigned short)::SendMessage(GetPlatformWindow(), message, itemIndex, lParam);
}

//----------------------------------------------------------------------------------------
// BR_CListBox::SendListMsg
//----------------------------------------------------------------------------------------

inline unsigned short BR_CListBoxBase::SendListMsg(WORD message,
												   WORD item) const
{
	return (unsigned short)::SendMessage(GetPlatformWindow(), message, item, 0L);
}
#endif


//========================================================================================
//	CLASS BR_CListBox
//========================================================================================

class BR_CListBox : public BR_CListBoxBase
{
	friend BR_CItemHelper;
	friend BR_CEntryListBox;

public:
	BR_CListBox(BR_CView* enclosure,
				BR_CBureaucrat* supervisor,
				BR_CItemHelper* itemHelper,
				BR_Distance width,
				BR_Distance height,
				BR_Coordinate x,
				BR_Coordinate y,
				ViewSizing horizontalSizing,
				ViewSizing verticalSizing,
				ViewId viewId,
				ViewStyle style);

	BR_CListBox(BR_CView* enclosure,
				BR_CBureaucrat* supervisor,
				const BR_CModule& module,
				BR_SResource& viewResource);

	virtual~ BR_CListBox();

	virtual ItemIndex AddItem(BR_CObject* item);
	virtual ItemIndex FindItem(const BR_CObject& item,
							   ItemIndex firstIndex = 0) const;
	virtual ItemIndex GetCount() const;
	virtual ItemIndex GetCurrentSelection() const;
	virtual BR_CObject* GetItem(ItemIndex index) const;
	virtual BR_CView* GetItemEnclosure() const;
	virtual ItemIndex GetNoItemsSelected() const;
	virtual ItemIndex GetSelectedItems(BC_TCollection<ItemIndex> &selectedItems) const;
	virtual void GetTextFromItem(ItemIndex index,
								 BR_TString<BR_Char>& text) const;
	virtual ItemIndex GetTopItem() const;
	virtual ItemIndex InsertItem(ItemIndex index,
								 BR_CObject* item);
	virtual BR_Boolean IsItemSelected(ItemIndex itemNo) const;
	virtual ItemIndex RemoveItem(ItemIndex itemNo);
	virtual void SelectItem(ItemIndex itemNo);
	virtual void SelectRange(ItemIndex firstItem,
							 ItemIndex lastItem);
	virtual void SetCurrentSelection(ItemIndex itemNo);
	virtual void SetTopItem(ItemIndex itemNo);
	virtual void UnselectItem(ItemIndex itemNo);
	virtual void UnselectRange(ItemIndex firstItem,
							   ItemIndex lastItem);

protected:
	virtual void AdoptItemHelper(BR_CItemHelper* itemHelper);
	BR_CItemHelper* GetItemHelper() const;
	void HandleDelete(ItemIndex itemNo);

private:
	void InitializeItemSize();

	BR_Boolean fHaveItemSize;
	long fWidth, fHeight;
	BR_CItemHelper* fItemHelper;

#ifdef BR_BUILD_MAC
public:
	friend BR_CMacCompareObjectHelper;

	ListHandle fListBox;						// Mac listbox handle
	BR_Boolean fSorted;							// Sort the items?
	BR_Boolean fFramed;							// Draw a box around it

	void AddScrollControls();
	virtual void DoClick(const BR_CPoint& point,
						 KeyModifiers keyFlags);
	virtual void Draw(BR_CCanvas &canvas, const BR_CRectangle& area);
	ListHandle GetHandle() const;
	void InitListBox(ViewStyle style);
	void RemoveScrollControls();
	void SetHandle(ListHandle handle);
	virtual void SetMacCtlRect(const Rect& rect);

private:
	static pascal short CompProc(char* celldata,
								 char* testdata,
								 short cellLen,
								 short testLen);
	static pascal void OwnerDrawDefProc(short message,
										Boolean Select,
										const Rect& rect,
										Cell cell,
										short dataOffset,
										short dataLength,
										ListHandle handle);
	static Handle PreLoadDefProc();

	static BR_CListBox* fListBoxDoingCompare;
	static Handle fDefProc;
#endif

#ifdef BR_BUILD_WIN
public:
	// These two methods are inherited
	long Dispatch(WORD message,
				  WORD wParam,
				  long lParam,
				  BR_Boolean callDefaultProc = TRUE);
	long DoDefaultProc(WORD message,
					   WORD wParam,
					   long lParam);
	void SetRedraw(BR_Boolean redraw);
#endif

	BR_SETCLASSNAME(BR_CListBox);
};

//----------------------------------------------------------------------------------------
// BR_CListBox::GetItemHelper
//----------------------------------------------------------------------------------------

inline BR_CItemHelper* BR_CListBox::GetItemHelper() const
{
	BR_ASSERT(fItemHelper != NULL);
	return fItemHelper;
}

#ifdef BR_BUILD_MAC
//----------------------------------------------------------------------------------------
// BR_CListBox::GetHandle
//----------------------------------------------------------------------------------------

inline ListHandle BR_CListBox::GetHandle() const
{
	return fListBox;
}

//----------------------------------------------------------------------------------------
// BR_CListBox::SetHandle
//----------------------------------------------------------------------------------------

inline void BR_CListBox::SetHandle(ListHandle handle)
{
	fListBox = handle;
}
#endif

#ifdef BR_BUILD_WIN
//----------------------------------------------------------------------------------------
// BR_CListBox::SetRedraw
//----------------------------------------------------------------------------------------

inline void BR_CListBox::SetRedraw(BR_Boolean redraw)
{
	::SendMessage(GetPlatformWindow(), WM_SETREDRAW, redraw, 0);
}
#endif

#endif

