/******************************************************************************
 SyGFileTreeTable.h

	Interface for the SyGFileTreeTable class

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

#ifndef _H_SyGFileTreeTable
#define _H_SyGFileTreeTable

#include "JXNamedTreeListWidget.h"

#include <JXCursor.h>
#include <JString.h>

#include "SyGFileTreeNode.h"
#include "SyGColUtils.h"

class JXMenuBar;
class JXImage;
class SyGFileTreeList;
class SyGFileTreeUpdateTask;
class SyGFileTree;
class JXTextMenu;
class GXTreeViewOptionsDialog;
class SyGSet;
class istream;
class SyGRunCmdDialog;
class JXToolBar;

class SyGFileTreeTable : public JXNamedTreeListWidget
{
public:

	static SyGFileTreeTable* Create(JXMenuBar* menuBar,
		SyGFileTree* fileTree,
		SyGFileTreeList* treeList,
		SyGSet* set,
		JXScrollbarSet* scrollbarSet,
		JXContainer* enclosure,
		const HSizingOption hSizing, const VSizingOption vSizing,
		const JCoordinate x, const JCoordinate y,
		const JCoordinate w, const JCoordinate h);
	
	virtual ~SyGFileTreeTable();

	void UpdateDisplay();
	void InitializeColumns();
	void InitializeColumns(istream& is);
	void SavePreferences(ostream& os);
	void InitDirs(istream& is);
	void SaveDirState(ostream& os);
	void SaveAsDefault();
	void SelectAll();
	void MakeLinks();
	void SelectName(const JCharacter* name);
	void DoSelectName(const JCharacter* name);
	
	const JString& 	GetCurrentPath();
	virtual void 	HandleKeyPress(const int key,
						const JXKeyModifiers&   modifiers);
					
	virtual void	HandleShortcut(const int key,	// must call inherited
						const JXKeyModifiers& modifiers);

	void CreateNewDirectory();

	void MoveSelectedToTrash();
	void DeleteSelected();
	void DuplicateSelected();

	void PerformOpen();

	void WindowIconified();
	void WindowDeiconified();

	void ViewManPage();
	void RunCommand();

	JString 	GetColTitle(const JIndex index) const;
	JCoordinate	GetBufferWidth(const JIndex index) const;
	JBoolean	IsCurrentCol(const JIndex index) const;
	void		SetCurrentCol(const JIndex index);

	void		LoadToolBarDefaults(JXToolBar* toolBar);

	JBoolean	HasSelection() const;
	JBoolean	HasSelectionAndFocus() const;
	
protected:

	SyGFileTreeTable(JXMenuBar* menuBar,
		SyGFileTree* fileTree,
		SyGFileTreeList* treeList,
		SyGSet* set,
		JXScrollbarSet* scrollbarSet,
		JXContainer* enclosure,
		const HSizingOption hSizing, const VSizingOption vSizing,
		const JCoordinate x, const JCoordinate y,
		const JCoordinate w, const JCoordinate h);

	virtual void 		Receive(JBroadcaster* sender, const Message& message);
	virtual void		Draw(JXWindowPainter& p, const JRect& rect);
	
	virtual JBoolean 	GetImage(const JIndex index, const JXImage** image) const;
	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);

	// Drag-and-drop

	virtual JBoolean 	WillAcceptDrop(const JArray<Atom>& typeList, 
										Atom* action,const Time time, 
										const JXWidget*		source);
	virtual void	 	HandleDNDHere(const JPoint& pt, const JXWidget* source);
	virtual void 		HandleDNDLeave();
	virtual void 		HandleDNDDrop(const JPoint& pt, const JArray<Atom>& typeList,
									  const Atom action, const Time time, 
									  const JXWidget* source);
	virtual Atom		GetDNDAction(const JXContainer* target,
									  const JXButtonStates& buttonStates,
									  const JXKeyModifiers& modifiers);
	virtual void		GetDNDAskActions(const JXButtonStates& buttonStates,
									  const JXKeyModifiers& modifiers,
									  JArray<Atom>* askActionList,
									  JPtrArray<JString>* askDescriptionList);
	virtual void		HandleDNDResponse(const JXContainer* target,
									  const JBoolean dropAccepted, const Atom action);

	virtual void		LostSelectionOwnership(const Atom selectionName);
	virtual JBoolean 	ConvertSelection(const Atom name,const Atom requestType,
										 Atom* returnType, unsigned char** data,
										JSize* dataLength, JSize* bitsPerBlock);
	virtual void		DNDInit(const JPoint& pt, const JXButtonStates& buttonStates,
							const JXKeyModifiers& modifiers);
	virtual void		DNDFinish(const JXContainer* target);

	// end DND

	virtual void		AdjustToTree();
	virtual JSize		GetMinCellWidth(const JPoint& cell) const;
	virtual JCoordinate GetAvailableWidth() const;
	virtual void 		TableDrawCell(JPainter &, 
								const JPoint& cell, const JRect& rect);
								
	virtual JBoolean	ExtractInputData(const JPoint& cell);
	virtual JBoolean 	NewNameOK(const JIndex index, const JString& newName);
	JBoolean			Remove(const JString& src);
	
	void 				InsertFMTreeCol(const GFMColType type);
	void 				RemoveFMTreeCol(const GFMColType type);
	
	virtual void 		DoubleClickIcon(const JIndex index, const JXKeyModifiers& modifiers);
	
private:

	JIndex GetNearestDirIndex(const JIndex index);

	void HandleTreeMenu(const JIndex index);
	void UpdateTreeMenu();
	void Delete(const JString& src);
	void GetViewPreferences();
	void SetPreferences(JBoolean prefs[]);
	void GetPreferences(JBoolean prefs[]);
	void PerformAction(const JIndex index, const JBoolean altDir, 
					   const JBoolean altFile, const JBoolean cntlFile = kFalse);
	void HandleShortcutMenu(const JIndex index);
	void UpdateShortcutMenu();
	void SelectClosest();
	void CopyToDNDBuffer();

	JBoolean 	PointInNode(const JIndex index, const JPoint pt);
	JCoordinate	TableToTreeCell(const JIndex index, const JCoordinate position) const;
	
private:

	JXTextMenu* itsTreeMenu;
	JXTextMenu* itsShortcutMenu;
	JXTextMenu*	itsEditMenu;	// we don't own this.

	JBoolean 				itsLongDisplay;
	SyGFileTreeUpdateTask* 	itsFileUpdateTask;
	JXImage* 				itsExecutableIcon;
	JXImage* 				itsSelectedBranchIcon;
	JXImage* 				itsBranchIcon;
	JXImage* 				itsOpenSelectedBranchIcon;
	JXImage* 				itsSelectedFileIcon;
	JXImage* 				itsFileIcon;
	JXImage* 				itsSelectedExecIcon;
	JBoolean 				itsDndCellIsBranch;
	JIndex 					currentDndHereIndex;
	JIndex 					itsDndStartIndex;
	SyGFileTreeList* 		itsFileTreeList;
	SyGFileTree*			itsFileTree;
	unsigned char 			itsVisibleColsMask;
	
	JBoolean 	itsVisibleCols[5];
	JPoint 		itsDownPt;
	JBoolean 	itsDownInCell;
	JBoolean 	itsClearIfNotDND;
	SyGSet* 	itsSet;
	JString		itsTextBuffer;
	JBoolean	itsWaitingToEdit;
	JBoolean	itsRunOnSelected;
	JString		itsRunFile;

	SyGRunCmdDialog*	itsRunDialog;
	
// Selection

	JCursorIndex 	itsDNDCursor;
	JCursorIndex 	itsDNDCopyCursor;
	JCursorIndex 	itsDNDAskCursor;
	JString* 		itsDNDBuffer;

// Drag painter

	JBoolean 	itsDraggingRect;
	JPoint 		itsStartPt;
	JPoint 		itsPrevPt;
	JBoolean	itsUpdateWhileDragging;

// Sort type
	GFMColType	itsCurrentColType;
	
private:

	void	GetRunCommand();
	void	StartRunCommand();
	void	SetCurrentCol(const GFMColType type);

	void	UpdateEditMenu();
	void	HandleEditMenu(const JIndex item);

	void	GetCellString(const JPoint cell, JString* str) const;

	JBoolean	DuplicateCell(const JPoint cell, JArray<JIndex>* nodes);
	void		MoveCellToTrash(const JPoint cell);
	JBoolean	DeleteCell(const JPoint cell);
	JBoolean	MakeLinkToCell(const JPoint cell, JArray<JIndex>* nodes);

	// not allowed

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

public:

	// Collaborator messages

	static const JCharacter* kGXFMColInserted;
	static const JCharacter* kGXFMColRemoved;
	
	class GXFMColInserted : public JBroadcaster::Message
		{
		public:
			GXFMColInserted(const JString& name, const JCoordinate bufferWidth, 
				const JIndex index, const JCoordinate width)
			:
			JBroadcaster::Message(kGXFMColInserted),
			itsName(name),
			itsBufferWidth(bufferWidth),
			itsIndex(index),
			itsColWidth(width)
			{ };
			
			const JString&
			GetName() const
			{
				return itsName;
			};
			
			JCoordinate
			GetBufferWidth() const
			{
				return itsBufferWidth;
			};
			
			JIndex
      		GetIndex() const
      		{
     	 		return itsIndex;
     		};
     		
			JCoordinate
			GetColWidth() const
			{
				return itsColWidth;
			}
						
		private:
		
			const JString& itsName;
			JCoordinate itsBufferWidth;
			JIndex itsIndex;
			JCoordinate itsColWidth;
		};
		
	class GXFMColRemoved : public JBroadcaster::Message
		{
		public:
			GXFMColRemoved(const JIndex index)
			:
			JBroadcaster::Message(kGXFMColRemoved),
			itsIndex(index)
			{ };
			
			JIndex
      		GetIndex() const
      		{
     	 		return itsIndex;
     		};
			
		private:
		
			JIndex itsIndex;
		};

};



#endif
