/******************************************************************************
 JXFileListTable.h

	Interface for the JXFileListTable class

	Copyright © 1998-99 by John Lindal.  All rights reserved.

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

#ifndef _H_JXFileListTable
#define _H_JXFileListTable

#include <JXTable.h>

class JError;
class JString;
class JRegex;
class JXImage;
class JXTEBase;
class JXTextMenu;

class JXFileListTable : public JXTable
{
public:

	JXFileListTable(JXScrollbarSet* scrollbarSet, JXContainer* enclosure,
					const HSizingOption hSizing, const VSizingOption vSizing,
					const JCoordinate x, const JCoordinate y,
					const JCoordinate w, const JCoordinate h);

	virtual ~JXFileListTable();

	JBoolean	AddFile(const JCharacter* fullName, JIndex* fullNameIndex = NULL);
	void		RemoveFile(const JCharacter* fullName);
	void		RemoveFiles(const JPtrArray<JString>& fileList);
	void		RemoveSelectedFiles();
	void		RemoveAllFiles();
	JString		GetFullName(const JIndex rowIndex) const;
	JBoolean	GetFullName(const JString& fileName, JString* fullName) const;

	const JPtrArray<JString>&	GetFullNameList() const;

	JBoolean	GetFilterRegex(JString* regexStr) const;
	JError		SetFilterRegex(const JCharacter* regexStr);
	void		ClearFilterRegex();

	JBoolean	HasSelection() const;
	JBoolean	GetSelection(JPtrArray<JString>* fileList) const;
	void		SelectSingleEntry(const JIndex index, const JBoolean scroll = kTrue);
	void		SelectAll();
	void		ClearSelection();

	JBoolean	GetEditMenuProvider(JXTEBase** te) const;
	void		SetEditMenuProvider(JXTEBase* te);

	JBoolean	WillAcceptFileDrop() const;
	void		ShouldAcceptFileDrop(const JBoolean accept = kTrue);

	JBoolean	BackspaceWillRemoveSelectedFiles() const;
	void		BackspaceShouldRemoveSelectedFiles(const JBoolean remove = kTrue);

	virtual void	HandleKeyPress(const int key, const JXKeyModifiers& modifiers);

protected:

	JCollection*	GetFullNameDataList() const;
	const JString&	GetFileName(const JIndex rowIndex) const;

	virtual void	TableDrawCell(JPainter& p, const JPoint& cell, const JRect& rect);

	virtual void	HandleMouseDown(const JPoint& pt, const JXMouseButton button,
									const JSize clickCount,
									const JXButtonStates& buttonStates,
									const JXKeyModifiers& modifiers);
	virtual void	HandleMouseDrag(const JPoint& pt, const JXButtonStates& buttonStates,
									const JXKeyModifiers& modifiers);
	virtual void	HandleMouseUp(const JPoint& pt, const JXMouseButton button,
								  const JXButtonStates& buttonStates,
								  const JXKeyModifiers& modifiers);

	virtual void	DNDInit(const JPoint& pt, const JXButtonStates& buttonStates,
							const JXKeyModifiers& modifiers);
	virtual void	DNDFinish(const JXContainer* target);
	virtual Atom	GetDNDAction(const JXContainer* target,
								 const JXButtonStates& buttonStates,
								 const JXKeyModifiers& modifiers);

	virtual JBoolean	WillAcceptDrop(const JArray<Atom>& typeList, Atom* action,
									   const Time time, const JXWidget* source);
	virtual void		HandleDNDDrop(const JPoint& pt, const JArray<Atom>& typeList,
									  const Atom action, const Time time,
									  const JXWidget* source);

	virtual JBoolean	ConvertSelection(const Atom name, const Atom requestType,
										 Atom* returnType, unsigned char** data,
										 JSize* dataLength, JSize* bitsPerBlock);
	virtual void		LostSelectionOwnership(const Atom selectionName);

	virtual void	ApertureResized(const JCoordinate dw, const JCoordinate dh);
	virtual void	Receive(JBroadcaster* sender, const Message& message);

private:

	enum DragType
	{
		kInvalidDrag,
		kSelectCellDrag,
		kDeselectCellDrag,
		kSelectRangeDrag,
		kWaitForDND
	};

private:

	JPtrArray<JString>*	itsFileList;			// full name of each file
	JPtrArray<JString>*	itsVisibleList;			// file name of each visible item
	JRegex*				itsRegex;				// can be NULL

	JBoolean			itsAcceptFileDropFlag;	// kTrue => accept drop of url/url
	JBoolean			itsBSRemoveSelFlag;		// kTrue => backspace removes selected files
	JSize				itsMaxStringWidth;
	JXImage*			itsFileIcon;
	JString*			itsKeyBuffer;
	JString*			itsClipBuffer;

	// dragging

	DragType			itsDragType;
	JPoint				itsMouseDownPt;
	JString*			itsDNDBuffer;

	// edit menu (copy, select all)

	JXTEBase*			itsEditMenuProvider;	// can be NULL; not owned
	JXTextMenu*			itsEditMenu;			// can be NULL; not owned

private:

	void	RebuildTable(const JBoolean maintainScroll = kFalse);
	void	FilterFile(const JIndex fileIndex);
	void	AdjustColWidths();

	JBoolean	ClosestMatch(const JString& prefixStr, JIndex* index) const;
	JIndex		RowIndexToFileIndex(const JIndex rowIndex) const;
	JBoolean	FileNameToFileIndex(const JString& name, JIndex* index) const;

	void	UpdateEditMenu();
	void	HandleEditMenu(const JIndex index);
	void	CopySelectedFileNames();

	void	CopyToDNDBuffer();

	// not allowed

	JXFileListTable(const JXFileListTable& source);
	const JXFileListTable& operator=(const JXFileListTable& source);

public:

	// JBroadcaster messages

	static const JCharacter* kProcessSelection;

	class ProcessSelection : public JBroadcaster::Message
		{
		public:

			ProcessSelection()
				:
				JBroadcaster::Message(kProcessSelection)
			{ };
		};
};


/******************************************************************************
 Accepting file drops

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

inline JBoolean
JXFileListTable::WillAcceptFileDrop()
	const
{
	return itsAcceptFileDropFlag;
}

inline void
JXFileListTable::ShouldAcceptFileDrop
	(
	const JBoolean accept
	)
{
	itsAcceptFileDropFlag = accept;
}

/******************************************************************************
 Backspace action

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

inline JBoolean
JXFileListTable::BackspaceWillRemoveSelectedFiles()
	const
{
	return itsBSRemoveSelFlag;
}

inline void
JXFileListTable::BackspaceShouldRemoveSelectedFiles
	(
	const JBoolean remove
	)
{
	itsBSRemoveSelFlag = remove;
}

/******************************************************************************
 GetFullNameList

	This is guaranteed to be sorted using JCompareStringsCaseInsensitive().

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

inline const JPtrArray<JString>&
JXFileListTable::GetFullNameList()
	const
{
	return *itsFileList;
}

/******************************************************************************
 GetFullNameDataList

	Derived classes can listen to this object and keep an array of extra
	data in sync with our information.

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

inline JCollection*
JXFileListTable::GetFullNameDataList()
	const
{
	return itsFileList;
}

/******************************************************************************
 GetFileName (protected)

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

inline const JString&
JXFileListTable::GetFileName
	(
	const JIndex rowIndex
	)
	const
{
	return *(itsVisibleList->NthElement(rowIndex));
}

/******************************************************************************
 GetEditMenuProvider

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

inline JBoolean
JXFileListTable::GetEditMenuProvider
	(
	JXTEBase** te
	)
	const
{
	*te = itsEditMenuProvider;
	return JI2B( itsEditMenuProvider != NULL );
}

#endif
