/******************************************************************************
 JTable.h

	Interface for the JTable class

	Copyright © 1996 by John Lindal. All rights reserved.

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

#ifndef _H_JTable
#define _H_JTable

#include <JRunArray.h>
#include <JPtrArray.h>
#include <JRect.h>
#include <jColor.h>

class JTableData;
class JTableSelection;
class JPainter;
class JPagePrinter;

class JTable : virtual public JBroadcaster
{
public:

	JTable(const JCoordinate defRowHeight, const JCoordinate defColWidth,
		   const JColorIndex borderColor, const JColorIndex selectionColor);

	virtual ~JTable();

	void	SetTableData(const JTableData* data);

	JSize		GetRowCount() const;
	JCoordinate	GetRowHeight(const JIndex index) const;
	void		SetRowHeight(const JIndex index, const JCoordinate rowHeight);
	void		SetAllRowHeights(const JCoordinate rowHeight);
	JCoordinate	GetDefaultRowHeight() const;
	void		SetDefaultRowHeight(const JCoordinate defRowHeight);

	JSize		GetColCount() const;
	JCoordinate	GetColWidth(const JIndex index) const;
	void		SetColWidth(const JIndex index, const JCoordinate colWidth);
	void		SetAllColWidths(const JCoordinate colWidth);
	JCoordinate	GetDefaultColWidth() const;
	void		SetDefaultColWidth(const JCoordinate defColWidth);

	JBoolean	GetCell(const JPoint& pt, JPoint* cell) const;
	JRect		GetCellRect(const JPoint& cell) const;

	JTableSelection&		GetTableSelection();
	const JTableSelection&	GetTableSelection() const;

	virtual JBoolean	IsSelectable(const JPoint& cell,
									 const JBoolean forExtend) const;
	void				SelectSingleCell(const JPoint& cell,
										 const JBoolean scroll = kTrue);
	JBoolean			GetNextSelectableCell(JPoint* cell, const JPoint& delta,
											  const JBoolean forExtend) const;

	virtual JBoolean	IsEditable(const JPoint& cell) const;
	void				BeginEditing(const JPoint& cell, const JBoolean scrollToCell = kTrue);
	void				ShiftEditing(const JCoordinate dx, const JCoordinate dy,
									 const JBoolean scrollToCell = kTrue);
	JBoolean			EndEditing();
	void				CancelEditing();

	JBoolean	IsEditing() const;
	JBoolean	GetEditedCell(JPoint* editCell) const;

	void	Print(JPagePrinter& p,
				  const JBoolean printRowHeader = kTrue,
				  const JBoolean printColHeader = kTrue);

	void	GetRowBorderInfo(JCoordinate* lineWidth, JColorIndex* color) const;
	void	SetRowBorderInfo(const JCoordinate lineWidth, const JColorIndex color);

	void	GetColBorderInfo(JCoordinate* lineWidth, JColorIndex* color) const;
	void	SetColBorderInfo(const JCoordinate lineWidth, const JColorIndex color);

	JColorIndex	GetSelectionColor() const;
	void		SetSelectionColor(const JColorIndex color);

	void	SetRowHeader(JTable* table);
	void	SetColHeader(JTable* table);

	JBoolean	RowIndexValid(const JIndex index) const;
	JBoolean	ColIndexValid(const JIndex index) const;
	JBoolean	CellValid(const JPoint& cell) const;

	virtual JBoolean	TableScrollToCell(const JPoint& cell,
										  const JBoolean centerInDisplay = kFalse) = 0;

	// automatically called by JAuxTableData

	void	RegisterAuxData(JTableData* auxData);
	void	RemoveAuxData(JTableData* auxData);

protected:

	enum DrawOrder
	{
		kDrawByRow,
		kDrawByCol
	};

protected:

	virtual void	TableRefresh() = 0;
	virtual void	TableRefreshRect(const JRect& rect) = 0;
	void			TableRefreshCell(const JPoint& cell);
	void			TableRefreshCell(const JIndex row, const JIndex col);
	void			TableRefreshCellRect(const JRect& cellRect);
	void			TableRefreshRow(const JIndex index);
	void			TableRefreshCol(const JIndex index);

	void			SetDrawOrder(const DrawOrder order);
	void			TableDraw(JPainter& p, const JRect& r,
							  const JBoolean drawLowerRightBorder = kFalse);
	virtual void	TableDrawCell(JPainter& p, const JPoint& cell, const JRect& rect) = 0;
	virtual void	TablePrepareToDrawRow(const JIndex rowIndex,
										  const JIndex firstCol, const JIndex lastCol);
	virtual void	TablePrepareToDrawCol(const JIndex colIndex,
										  const JIndex firstRow, const JIndex lastRow);
	JBoolean		Paginate(const JCoordinate pageWidth, const JCoordinate pageHeight,
							 const JBoolean userPrintRowHeader,
							 JArray<JCoordinate>* rowBreakpts, JBoolean* printRowHeader,
							 const JBoolean userPrintColHeader,
							 JArray<JCoordinate>* colBreakpts, JBoolean* printColHeader) const;
	void			HilightIfSelected(JPainter& p, const JPoint& cell,
									  const JRect& rect) const;

	void	InsertRow(const JIndex index, const JCoordinate rowHeight = 0);
	void	PrependRow(const JCoordinate rowHeight = 0);
	void	AppendRow(const JCoordinate rowHeight = 0);
	void	RemoveRow(const JIndex index);
	void	RemoveAllRows();
	void	MoveRow(const JIndex origIndex, const JIndex newIndex);

	void	InsertCol(const JIndex index, const JCoordinate colWidth = 0);
	void	PrependCol(const JCoordinate colWidth = 0);
	void	AppendCol(const JCoordinate colWidth = 0);
	void	RemoveCol(const JIndex index);
	void	RemoveAllCols();
	void	MoveCol(const JIndex origIndex, const JIndex newIndex);

	void				TableSetBounds(const JCoordinate w, const JCoordinate h);
	void				TableAdjustBounds(const JCoordinate dw, const JCoordinate dh);
	virtual void		TableSetGUIBounds(const JCoordinate w, const JCoordinate h) = 0;
	virtual void		TableSetScrollSteps(const JCoordinate hStep,
											const JCoordinate vStep) = 0;

	virtual JBoolean	CreateInputField(const JPoint& cell, const JRect& cellRect);
	virtual JBoolean	ExtractInputData(const JPoint& cell);
	virtual void		DeleteInputField();
	virtual void		PlaceInputField(const JCoordinate x, const JCoordinate y);
	virtual void		MoveInputField(const JCoordinate dx, const JCoordinate dy);
	virtual void		SetInputFieldSize(const JCoordinate w, const JCoordinate h);
	virtual void		ResizeInputField(const JCoordinate dw, const JCoordinate dh);

	virtual JCoordinate	GetPrintHeaderHeight(JPagePrinter& p) const;
	virtual JCoordinate	GetPrintFooterHeight(JPagePrinter& p) const;
	virtual void		DrawPrintHeader(JPagePrinter& p, const JCoordinate headerHeight);
	virtual void		DrawPrintFooter(JPagePrinter& p, const JCoordinate footerHeight);

	JBoolean	IsDraggingSelection() const;
	void		SetSelectionBehavior(const JBoolean allowMultiple,
									 const JBoolean allowDiscont);
	void		BeginSelectionDrag(const JPoint& cell, const JBoolean extendSelection,
								   const JBoolean selectDiscont);
	void		ContinueSelectionDrag(const JPoint& cell);
	void		FinishSelectionDrag();
	JBoolean	HandleSelectionKeyPress(const JCharacter key,
										const JBoolean extendSelection);

	virtual void	Receive(JBroadcaster* sender, const Message& message);

private:

	struct BorderInfo
	{
		JCoordinate	width;
		JColorIndex	color;

		BorderInfo(const JCoordinate w, const JColorIndex c)
			:
			width(w), color(c)
		{ };
	};

	enum SelDragType
	{
		kInvalidDrag,
		kSelectSingleDrag,
		kSelectCellDrag,
		kDeselectCellDrag,
		kSelectRangeDrag
	};

private:

	DrawOrder	itsDrawOrder;

	JCoordinate	itsWidth;
	JCoordinate	itsHeight;

	JCoordinate	itsDefRowHeight;
	JCoordinate	itsDefColWidth;

	JRunArray<JCoordinate>*	itsRowHeights;
	JRunArray<JCoordinate>*	itsColWidths;

	const JTableData*			itsTableData;
	JTableSelection*			itsTableSelection;
	JPtrArray<JBroadcaster>*	itsAuxDataList;		// we don't own the objects in the list

	BorderInfo	itsRowBorderInfo;
	BorderInfo	itsColBorderInfo;
	JColorIndex	itsSelectionColor;

	// used when printing

	JTable* itsRowHdrTable;
	JTable*	itsColHdrTable;

	// used while editing contents of a cell

	JBoolean	itsIsEditingFlag;
	JPoint		itsEditCell;

	// used while dragging selection

	SelDragType	itsSelDragType;
	JPoint		itsPrevSelDragCell;
	JBoolean	itsAllowSelectMultipleFlag;
	JBoolean	itsAllowSelectDiscontFlag;

private:

	void	AdjustToTableData();

	JBoolean	GetVisibleRange(const JCoordinate min, const JCoordinate max,
								JRunArray<JCoordinate>& lengths,
								const JCoordinate borderWidth,
								JIndex* firstIndex, JIndex* lastIndex) const;
	JBoolean	Paginate(const JCoordinate stripLength,
						 JRunArray<JCoordinate>& lengths,
						 const JCoordinate borderWidth,
						 JArray<JCoordinate>* breakpts) const;
	void		PrintPage(JPainter& p, const JPoint& topLeft, const JPoint& botRight,
						  const JPoint& offset, const JBoolean drawFrame);

	JBoolean	GetCellIndex(const JCoordinate coord, JRunArray<JCoordinate>& lengths,
							 const JCoordinate borderWidth, JIndex* index) const;
	void		GetCellBoundaries(const JIndex index, JRunArray<JCoordinate>& lengths,
								  const JCoordinate borderWidth,
								  JCoordinate* min, JCoordinate* max) const;

	void	TableDrawRowBorders(JPainter& p, const JRect& r,
								const JIndex firstRow, const JIndex lastRow,
								const JBoolean drawBottomBorder);
	void	TableDrawColBorders(JPainter& p, const JRect& r,
								const JIndex firstCol, const JIndex lastCol,
								const JBoolean drawRightBorder);

	// not allowed

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

public:

	// JBroadcaster messages

	static const JCharacter* kRowHeightChanged;
	static const JCharacter* kAllRowHeightsChanged;
	static const JCharacter* kRowInserted;
	static const JCharacter* kRowRemoved;
	static const JCharacter* kAllRowsRemoved;
	static const JCharacter* kRowMoved;
	static const JCharacter* kRowBorderWidthChanged;

	static const JCharacter* kColWidthChanged;
	static const JCharacter* kAllColWidthsChanged;
	static const JCharacter* kColInserted;
	static const JCharacter* kColRemoved;
	static const JCharacter* kAllColsRemoved;
	static const JCharacter* kColMoved;
	static const JCharacter* kColBorderWidthChanged;

	static const JCharacter* kPrepareForTableDataMessage;	// message from JTableData
	static const JCharacter* kPrepareForTableDataChange;	// about to switch to different JTableData
	static const JCharacter* kTableDataChanged;				// now using different JTableData

protected:

	// base classes for JBroadcaster messages

	class RowMessage : public JBroadcaster::Message
		{
		public:

			RowMessage(const JCharacter* type, const JIndex index,
					   const JCoordinate rowHeight)
				:
				JBroadcaster::Message(type),
				itsIndex(index),
				itsRowHeight(rowHeight)
				{ };

			JIndex
			GetIndex() const
			{
				return itsIndex;
			};

			JCoordinate
			GetRowHeight() const
			{
				return itsRowHeight;
			};

		private:

			JIndex		itsIndex;
			JCoordinate	itsRowHeight;
		};

	class ColMessage : public JBroadcaster::Message
		{
		public:

			ColMessage(const JCharacter* type, const JIndex index,
					   const JCoordinate colWidth)
				:
				JBroadcaster::Message(type),
				itsIndex(index),
				itsColWidth(colWidth)
				{ };

			JIndex
			GetIndex() const
			{
				return itsIndex;
			};

			JCoordinate
			GetColWidth() const
			{
				return itsColWidth;
			};

		private:

			JIndex		itsIndex;
			JCoordinate	itsColWidth;
		};

	class RowColMoved : public JBroadcaster::Message
		{
		public:

			RowColMoved(const JCharacter* type,
						const JIndex origIndex, const JIndex newIndex)
				:
				JBroadcaster::Message(type),
				itsOrigIndex(origIndex),
				itsNewIndex(newIndex)
				{ };

			void	AdjustIndex(JIndex* index) const;

			JIndex
			GetOrigIndex() const
			{
				return itsOrigIndex;
			};

			JIndex
			GetNewIndex() const
			{
				return itsNewIndex;
			};

		private:

			JIndex	itsOrigIndex;
			JIndex	itsNewIndex;
		};

	class BorderWidthChanged : public JBroadcaster::Message
		{
		public:

			BorderWidthChanged(const JCharacter* type,
							   const JCoordinate origBorderWidth,
							   const JCoordinate newBorderWidth)
				:
				JBroadcaster::Message(type),
				itsOrigWidth(origBorderWidth),
				itsNewWidth(newBorderWidth)
				{ };

			JCoordinate
			GetOrigBorderWidth() const
			{
				return itsOrigWidth;
			};

			JCoordinate
			GetNewBorderWidth() const
			{
				return itsNewWidth;
			};

		private:

			JCoordinate	itsOrigWidth;
			JCoordinate	itsNewWidth;
		};

public:

	// row messages

	class RowHeightChanged : public JBroadcaster::Message
		{
		public:

			RowHeightChanged(const JIndex index, const JCoordinate origRowHeight,
							 const JCoordinate newRowHeight)
				:
				JBroadcaster::Message(kRowHeightChanged),
				itsIndex(index),
				itsOrigRowHeight(origRowHeight),
				itsNewRowHeight(newRowHeight)
				{ };

			JIndex
			GetIndex() const
			{
				return itsIndex;
			};

			JCoordinate
			GetOrigRowHeight() const
			{
				return itsOrigRowHeight;
			};

			JCoordinate
			GetNewRowHeight() const
			{
				return itsNewRowHeight;
			};

		private:

			JIndex		itsIndex;
			JCoordinate	itsOrigRowHeight;
			JCoordinate	itsNewRowHeight;
		};

	class AllRowHeightsChanged : public JBroadcaster::Message
		{
		public:

			AllRowHeightsChanged(const JCoordinate rowHeight)
				:
				JBroadcaster::Message(kAllRowHeightsChanged),
				itsRowHeight(rowHeight)
				{ };

			JCoordinate
			GetNewRowHeight() const
			{
				return itsRowHeight;
			};

		private:

			JCoordinate itsRowHeight;
		};

	class RowInserted : public RowMessage
		{
		public:

			RowInserted(const JIndex index, const JCoordinate rowHeight)
				:
				RowMessage(kRowInserted, index, rowHeight)
				{ };

			void	AdjustIndex(JIndex* index) const;

			void
			AdjustCell(JPoint* cell) const
			{
				JIndex rowIndex = cell->y;
				AdjustIndex(&rowIndex);
				cell->y = rowIndex;
			};
		};

	class RowRemoved : public RowMessage
		{
		public:

			RowRemoved(const JIndex index, const JCoordinate rowHeight)
				:
				RowMessage(kRowRemoved, index, rowHeight)
				{ };

			JBoolean	AdjustIndex(JIndex* index) const;

			JBoolean
			AdjustCell(JPoint* cell) const
			{
				JIndex rowIndex   = cell->y;
				const JBoolean ok = AdjustIndex(&rowIndex);
				cell->y           = rowIndex;
				return ok;
			};
		};

	class AllRowsRemoved : public JBroadcaster::Message
		{
		public:

			AllRowsRemoved()
				:
				JBroadcaster::Message(kAllRowsRemoved)
				{ };
		};

	class RowMoved : public RowColMoved
		{
		public:

			RowMoved(const JIndex origIndex, const JIndex newIndex)
				:
				RowColMoved(kRowMoved, origIndex, newIndex)
				{ };

			void
			AdjustCell(JPoint* cell) const
			{
				JIndex rowIndex = cell->y;
				AdjustIndex(&rowIndex);
				cell->y = rowIndex;
			};
		};

	class RowBorderWidthChanged : public BorderWidthChanged
		{
		public:

			RowBorderWidthChanged(const JCoordinate origBorderWidth,
								  const JCoordinate newBorderWidth)
				:
				BorderWidthChanged(kRowBorderWidthChanged,
								   origBorderWidth, newBorderWidth)
				{ };
		};

	// column messages

	class ColWidthChanged : public JBroadcaster::Message
		{
		public:

			ColWidthChanged(const JIndex index, const JCoordinate origColWidth,
							const JCoordinate newColWidth)
				:
				JBroadcaster::Message(kColWidthChanged),
				itsIndex(index),
				itsOrigColWidth(origColWidth),
				itsNewColWidth(newColWidth)
				{ };

			JIndex
			GetIndex() const
			{
				return itsIndex;
			};

			JCoordinate
			GetOrigColWidth() const
			{
				return itsOrigColWidth;
			};

			JCoordinate
			GetNewColWidth() const
			{
				return itsNewColWidth;
			};

		private:

			JIndex		itsIndex;
			JCoordinate	itsOrigColWidth;
			JCoordinate	itsNewColWidth;
		};

	class AllColWidthsChanged : public JBroadcaster::Message
		{
		public:

			AllColWidthsChanged(const JCoordinate colWidth)
				:
				JBroadcaster::Message(kAllColWidthsChanged),
				itsColWidth(colWidth)
				{ };

			JCoordinate
			GetNewColWidth() const
			{
				return itsColWidth;
			};

		private:

			JCoordinate itsColWidth;
		};

	class ColInserted : public ColMessage
		{
		public:

			ColInserted(const JIndex index, const JCoordinate colWidth)
				:
				ColMessage(kColInserted, index, colWidth)
				{ };

			void	AdjustIndex(JIndex* index) const;

			void
			AdjustCell(JPoint* cell) const
			{
				JIndex colIndex = cell->x;
				AdjustIndex(&colIndex);
				cell->x = colIndex;
			};
		};

	class ColRemoved : public ColMessage
		{
		public:

			ColRemoved(const JIndex index, const JCoordinate colWidth)
				:
				ColMessage(kColRemoved, index, colWidth)
				{ };

			JBoolean	AdjustIndex(JIndex* index) const;

			JBoolean
			AdjustCell(JPoint* cell) const
			{
				JIndex colIndex   = cell->x;
				const JBoolean ok = AdjustIndex(&colIndex);
				cell->x           = colIndex;
				return ok;
			};
		};

	class AllColsRemoved : public JBroadcaster::Message
		{
		public:

			AllColsRemoved()
				:
				JBroadcaster::Message(kAllColsRemoved)
				{ };
		};

	class ColMoved : public RowColMoved
		{
		public:

			ColMoved(const JIndex origIndex, const JIndex newIndex)
				:
				RowColMoved(kColMoved, origIndex, newIndex)
				{ };

			void
			AdjustCell(JPoint* cell) const
			{
				JIndex colIndex = cell->x;
				AdjustIndex(&colIndex);
				cell->x = colIndex;
			};
		};

	class ColBorderWidthChanged : public BorderWidthChanged
		{
		public:

			ColBorderWidthChanged(const JCoordinate origBorderWidth,
								  const JCoordinate newBorderWidth)
				:
				BorderWidthChanged(kColBorderWidthChanged,
								   origBorderWidth, newBorderWidth)
				{ };
		};

	// other messages

	class PrepareForTableDataMessage : public JBroadcaster::Message
		{
		public:

			PrepareForTableDataMessage(const JBroadcaster::Message& message)
				:
				JBroadcaster::Message(kPrepareForTableDataMessage),
				itsMessage(message)
				{ };

			const JBroadcaster::Message&
			GetMessage() const
			{
				return itsMessage;
			};

		private:

			const JBroadcaster::Message&	itsMessage;
		};

	class PrepareForTableDataChange : public JBroadcaster::Message
		{
		public:

			PrepareForTableDataChange()
				:
				JBroadcaster::Message(kPrepareForTableDataChange)
				{ };
		};

	class TableDataChanged : public JBroadcaster::Message
		{
		public:

			TableDataChanged()
				:
				JBroadcaster::Message(kTableDataChanged)
				{ };
		};
};


/******************************************************************************
 GetRowCount

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

inline JSize
JTable::GetRowCount()
	const
{
	return itsRowHeights->GetElementCount();
}

/******************************************************************************
 RowIndexValid

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

inline JBoolean
JTable::RowIndexValid
	(
	const JIndex index
	)
	const
{
	return JConvertToBoolean( 1 <= index && index <= GetRowCount() );
}

/******************************************************************************
 GetRowHeight

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

inline JCoordinate
JTable::GetRowHeight
	(
	const JIndex index
	)
	const
{
	return itsRowHeights->GetElement(index);
}

/******************************************************************************
 GetDefaultRowHeight

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

inline JCoordinate
JTable::GetDefaultRowHeight()
	const
{
	return itsDefRowHeight;
}

/******************************************************************************
 Row manipulations

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

inline void
JTable::PrependRow
	(
	const JCoordinate rowHeight
	)
{
	InsertRow(1, rowHeight);
}

inline void
JTable::AppendRow
	(
	const JCoordinate rowHeight
	)
{
	InsertRow(GetRowCount()+1, rowHeight);
}

/******************************************************************************
 GetColCount

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

inline JSize
JTable::GetColCount()
	const
{
	return itsColWidths->GetElementCount();
}

/******************************************************************************
 ColIndexValid

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

inline JBoolean
JTable::ColIndexValid
	(
	const JIndex index
	)
	const
{
	return JConvertToBoolean( 1 <= index && index <= GetColCount() );
}

/******************************************************************************
 GetColWidth

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

inline JCoordinate
JTable::GetColWidth
	(
	const JIndex index
	)
	const
{
	return itsColWidths->GetElement(index);
}

/******************************************************************************
 GetDefaultColWidth

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

inline JCoordinate
JTable::GetDefaultColWidth()
	const
{
	return itsDefColWidth;
}

/******************************************************************************
 Column manipulations

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

inline void
JTable::PrependCol
	(
	const JCoordinate colWidth
	)
{
	InsertCol(1, colWidth);
}

inline void
JTable::AppendCol
	(
	const JCoordinate colWidth
	)
{
	InsertCol(GetColCount()+1, colWidth);
}

/******************************************************************************
 CellValid

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

inline JBoolean
JTable::CellValid
	(
	const JPoint& cell
	)
	const
{
	return JConvertToBoolean( RowIndexValid(cell.y) && ColIndexValid(cell.x) );
}

/******************************************************************************
 SetDrawOrder (protected)

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

inline void
JTable::SetDrawOrder
	(
	const DrawOrder order
	)
{
	itsDrawOrder = order;
}

/******************************************************************************
 Default sizes

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

inline void
JTable::SetDefaultRowHeight
	(
	const JCoordinate defRowHeight
	)
{
	itsDefRowHeight = defRowHeight;
	TableSetScrollSteps(itsDefColWidth  + itsColBorderInfo.width,
						itsDefRowHeight + itsRowBorderInfo.width);
}

inline void
JTable::SetDefaultColWidth
	(
	const JCoordinate defColWidth
	)
{
	itsDefColWidth = defColWidth;
	TableSetScrollSteps(itsDefColWidth  + itsColBorderInfo.width,
						itsDefRowHeight + itsRowBorderInfo.width);
}

/******************************************************************************
 Border info (protected)

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

inline void
JTable::GetRowBorderInfo
	(
	JCoordinate*	lineWidth,
	JColorIndex*	color
	)
	const
{
	*lineWidth = itsRowBorderInfo.width;
	*color     = itsRowBorderInfo.color;
}

inline void
JTable::GetColBorderInfo
	(
	JCoordinate*	lineWidth,
	JColorIndex*	color
	)
	const
{
	*lineWidth = itsColBorderInfo.width;
	*color     = itsColBorderInfo.color;
}

/******************************************************************************
 Table bounds (protected)

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

inline void
JTable::TableSetBounds
	(
	const JCoordinate w,
	const JCoordinate h
	)
{
	itsWidth  = w;
	itsHeight = h;
	TableSetGUIBounds(itsWidth, itsHeight);
}

inline void
JTable::TableAdjustBounds
	(
	const JCoordinate dw,
	const JCoordinate dh
	)
{
	itsWidth  += dw;
	itsHeight += dh;
	TableSetGUIBounds(itsWidth, itsHeight);
}

/******************************************************************************
 Refresh (protected)

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

inline void
JTable::TableRefreshCell
	(
	const JPoint& cell
	)
{
	TableRefreshRect(GetCellRect(cell));
}

inline void
JTable::TableRefreshCell
	(
	const JIndex row,
	const JIndex col
	)
{
	TableRefreshRect(GetCellRect(JPoint(col,row)));
}

inline void
JTable::TableRefreshRow
	(
	const JIndex index
	)
{
	TableRefreshCellRect(JRect(index, 1, index+1, GetColCount()+1));
}

inline void
JTable::TableRefreshCol
	(
	const JIndex index
	)
{
	TableRefreshCellRect(JRect(1, index, GetRowCount()+1, index+1));
}

/******************************************************************************
 Row and column headers (protected)

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

inline void
JTable::SetRowHeader
	(
	JTable* table
	)
{
	itsRowHdrTable = table;
}

inline void
JTable::SetColHeader
	(
	JTable* table
	)
{
	itsColHdrTable = table;
}

/******************************************************************************
 GetTableSelection

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

inline JTableSelection&
JTable::GetTableSelection()
{
	return *itsTableSelection;
}

inline const JTableSelection&
JTable::GetTableSelection()
	const
{
	return *itsTableSelection;
}

/******************************************************************************
 Selection color

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

inline JColorIndex
JTable::GetSelectionColor()
	const
{
	return itsSelectionColor;
}

inline void
JTable::SetSelectionColor
	(
	const JColorIndex color
	)
{
	itsSelectionColor = color;
	TableRefresh();
}

/******************************************************************************
 IsEditing

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

inline JBoolean
JTable::IsEditing()
	const
{
	return itsIsEditingFlag;
}

/******************************************************************************
 IsDraggingSelection

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

inline JBoolean
JTable::IsDraggingSelection()
	const
{
	return JI2B( itsSelDragType != kInvalidDrag );
}

/******************************************************************************
 SetSelectionBehavior (protected)

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

inline void
JTable::SetSelectionBehavior
	(
	const JBoolean allowMultiple,
	const JBoolean allowDiscont
	)
{
	itsAllowSelectMultipleFlag = allowMultiple;
	itsAllowSelectDiscontFlag  = allowDiscont;
}

#endif
