/******************************************************************************
 JFloatBufferTableData.cc

	Class to buffer a table of numbers as JStrings so drawing the table
	will be faster.

	BASE CLASS = JStringTableData

	Copyright © 1996 John Lindal. All rights reserved.

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

#include <JFloatBufferTableData.h>
#include <JFloatTableData.h>
#include <JString.h>
#include <jAssert.h>

/******************************************************************************
 Constructor

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

JFloatBufferTableData::JFloatBufferTableData
	(
	const JFloatTableData*	floatData,
	const int				precision
	)
	:
	JStringTableData(),
	itsPrecision(precision)
{
	itsFloatData = floatData;
	ListenTo(itsFloatData);
}

/******************************************************************************
 Destructor

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

JFloatBufferTableData::~JFloatBufferTableData()
{
}

/******************************************************************************
 Receive (virtual protected)

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

void
JFloatBufferTableData::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	// element data changed

	if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
		message.Is(JTableData::kRectChanged))
		{
		const JTableData::RectChanged* info =
			dynamic_cast(const JTableData::RectChanged*, &message);
		assert( info != NULL );
		UpdateRect(info->GetRect());
		}

	// rows changed

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kRowInserted))
		{
		const JTableData::RowInserted* info =
			dynamic_cast(const JTableData::RowInserted*, &message);
		assert( info != NULL );
		const JIndex index = info->GetIndex();
		InsertRow(index);
		UpdateRow(index);
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kRowDuplicated))
		{
		const JTableData::RowDuplicated* info =
			dynamic_cast(const JTableData::RowDuplicated*, &message);
		assert( info != NULL );
		DuplicateRow(info->GetOrigIndex(), info->GetNewIndex());
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kRowRemoved))
		{
		const JTableData::RowRemoved* info =
			dynamic_cast(const JTableData::RowRemoved*, &message);
		assert( info != NULL );
		RemoveRow(info->GetIndex());
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kAllRowsRemoved))
		{
		RemoveAllRows();
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kRowMoved))
		{
		const JTableData::RowMoved* info =
			dynamic_cast(const JTableData::RowMoved*, &message);
		assert( info != NULL );
		MoveRow(info->GetOrigIndex(), info->GetNewIndex());
		}

	// columns changed

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kColInserted))
		{
		const JTableData::ColInserted* info =
			dynamic_cast(const JTableData::ColInserted*, &message);
		assert( info != NULL );
		const JIndex index = info->GetIndex();
		InsertCol(index);
		UpdateCol(index);
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kColDuplicated))
		{
		const JTableData::ColDuplicated* info =
			dynamic_cast(const JTableData::ColDuplicated*, &message);
		assert( info != NULL );
		DuplicateCol(info->GetOrigIndex(), info->GetNewIndex());
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kColRemoved))
		{
		const JTableData::ColRemoved* info =
			dynamic_cast(const JTableData::ColRemoved*, &message);
		assert( info != NULL );
		RemoveCol(info->GetIndex());
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kAllColsRemoved))
		{
		RemoveAllCols();
		}

	else if (sender == const_cast<JFloatTableData*>(itsFloatData) &&
			 message.Is(JTableData::kColMoved))
		{
		const JTableData::ColMoved* info =
			dynamic_cast(const JTableData::ColMoved*, &message);
		assert( info != NULL );
		MoveCol(info->GetOrigIndex(), info->GetNewIndex());
		}

	// something else

	else
		{
		JStringTableData::Receive(sender, message);
		}
}

/******************************************************************************
 UpdateRow (private)

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

void
JFloatBufferTableData::UpdateRow
	(
	const JIndex index
	)
{
	const JSize count = GetColCount();
	JPoint cell(1,index);
	for (JIndex i=1; i<=count; i++)
		{
		cell.x = i;
		UpdateCell(cell);
		}
}

/******************************************************************************
 UpdateCol (private)

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

void
JFloatBufferTableData::UpdateCol
	(
	const JIndex index
	)
{
	const JSize count = GetRowCount();
	JPoint cell(index,1);
	for (JIndex i=1; i<=count; i++)
		{
		cell.y = i;
		UpdateCell(cell);
		}
}

/******************************************************************************
 UpdateRect (private)

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

void
JFloatBufferTableData::UpdateRect
	(
	const JRect& r
	)
{
	for (JIndex x=r.left; x < (JIndex) r.right; x++)
		{
		for (JIndex y=r.top; y < (JIndex) r.bottom; y++)
			{
			UpdateCell(JPoint(x,y));
			}
		}
}

/******************************************************************************
 UpdateCell (private)

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

void
JFloatBufferTableData::UpdateCell
	(
	const JPoint& cell
	)
{
	const JFloat value = itsFloatData->GetElement(cell);
	const JString valueStr(value, itsPrecision);
	SetElement(cell, valueStr);
}
