/******************************************************************************
 JXCursorMarkTable.cc

	BASE CLASS = JXEditTable

	Copyright © 1997 by Glenn W. Bach. All rights reserved.

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

#include <JXCursorMarkTable.h>

#include <JXWindowDirector.h>
#include <JXWindow.h>
#include <JXColormap.h>

#include <J2DPlotWidget.h>

#include <JPagePrinter.h>
#include <JFontManager.h>
#include <JFontStyle.h>
#include <JString.h>

#include <jGlobals.h>
#include <JMinMax.h>

#include <jAssert.h>

const JSize kDefaultSize = kJDefaultFontSize;

const JCoordinate kDefColWidth  = 120;
const JCoordinate kHMarginWidth = 5;

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

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

JXCursorMarkTable::JXCursorMarkTable
	(
	J2DPlotWidget* 		plot,
	JXScrollbarSet*		scrollbarSet,
	JXContainer*		enclosure,
	const HSizingOption	hSizing,
	const VSizingOption	vSizing,
	const JCoordinate	x,
	const JCoordinate	y,
	const JCoordinate	w,
	const JCoordinate	h
	)
	:
	JXTable(1,kDefColWidth, scrollbarSet, enclosure,
				hSizing,vSizing, x,y, w,h)
{
	itsPlot = plot;
	AppendCol(kDefColWidth);
	AppendCol(kDefColWidth);
	SetColBorderInfo(1, GetColormap()->GetGray80Color());
	SetRowBorderInfo(1, GetColormap()->GetGray80Color());
	
	const JFontManager* fm = GetFontManager();
	JSize lineHeight = fm->GetLineHeight(JGetDefaultFontName(), kDefaultSize, JFontStyle());
	AppendRow(lineHeight + 2);
	
	ListenTo(plot);
}

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

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

JXCursorMarkTable::~JXCursorMarkTable()
{
}

/******************************************************************************
 TableDrawCell (virtual protected)


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

void
JXCursorMarkTable::TableDrawCell
	(
	JPainter&		p,
	const JPoint&	cell,
	const JRect&	rect
	)
{
	p.SetFont(JGetDefaultFontName(), kDefaultSize, JFontStyle());
	JRect r = rect;
	r.left += kHMarginWidth;
	r.right -= kHMarginWidth;
	if (cell.y == 1)
		{
		JString str;
		if (cell.x == 1)
			{
			str = "X Marks";
			}
		else
			{
			str = "Y Marks";
			}
		p.String(r, str, JPainter::kHAlignCenter, JPainter::kVAlignCenter);
		}
	else 
		{
		if (cell.x == 1)
			{
			if ((JCoordinate)(itsPlot->GetXMarkCount()) >= cell.y - 1)
				{
				JFloat value = itsPlot->GetXMarkValue(cell.y - 1);
				JString str(value);
				p.String(r, str, JPainter::kHAlignLeft, JPainter::kVAlignCenter);
				}
			}
		else
			{
			if ((JCoordinate)(itsPlot->GetYMarkCount()) >= cell.y - 1)
				{
				JFloat value = itsPlot->GetYMarkValue(cell.y - 1);
				JString str(value);
				p.String(r, str, JPainter::kHAlignLeft, JPainter::kVAlignCenter);
				}
			}
		}
}

/*******************************************************************************
 Receive
 

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

void
JXCursorMarkTable::Receive
	(
	JBroadcaster* sender,
	const JBroadcaster::Message& message
	)
{	
	if (sender == itsPlot && message.Is(J2DPlotWidget::kCursorMarked))
		{
		JXWindowDirector* dir = GetWindow()->GetDirector();
		if (!dir->IsActive())
			{
			dir->Activate();
			}
		AdjustTable();
		}
	else if (sender == itsPlot && message.Is(J2DPlotWidget::kMarkRemoved))
		{
		JXWindowDirector* dir = GetWindow()->GetDirector();
		if (!dir->IsActive())
			{
			dir->Activate();
			}
		AdjustTable();
		}
	else
		{
		JXTable::Receive(sender, message);
		}
}

/*******************************************************************************
 AdjustTable
 

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

void
JXCursorMarkTable::AdjustTable()
{
	JSize xCount = itsPlot->GetXMarkCount();
	JSize yCount = itsPlot->GetYMarkCount();
	if (yCount > 0 || xCount > 0)
		{
		JSize count = JMax(xCount, yCount) + 1;
		if (GetRowCount() < count)
			{
			const JFontManager* fm = GetFontManager();
			JSize lineHeight = 
				fm->GetLineHeight(JGetDefaultFontName(), kDefaultSize, JFontStyle());
			
			for (JSize i = GetRowCount(); i < count; i++)
				{
				AppendRow(lineHeight + 2);
				}
			}
		else if (GetRowCount() > count)
			{
			JSize rCount = GetRowCount();
			for (JSize i = rCount; i > count; i--)
				{
				RemoveRow(i);
				}
			}
		}
	else
		{
		JSize count = GetRowCount();
		for (JSize i = count; i > 1; i--)
			{
			RemoveRow(i);
			}
		}
	TableRefresh();
}

/******************************************************************************
 TableDrawArea

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

JBoolean
JXCursorMarkTable::TableDrawArea
	(
	JPagePrinter&	p,
	const JBoolean	putOnSamePage,
	const JRect&	partialPageRect
	)
{
	const JBoolean hasXMarks = JConvertToBoolean(itsPlot->GetXMarkCount() > 0);
	const JBoolean hasYMarks = JConvertToBoolean(itsPlot->GetYMarkCount() > 0);
	if (!hasXMarks && !hasYMarks)
		{
		return kTrue;
		}

	SetColBorderInfo(0, GetColormap()->GetGray80Color());
	SetRowBorderInfo(0, GetColormap()->GetGray80Color());

	JIndex currentRow = 1;
	JSize cols;
	JCoordinate width;
	if (hasXMarks)
		{
		width = GetColWidth(1);
		cols  = 1;
		}
	if (hasYMarks)
		{
		width += GetColWidth(1);
		cols  += 1;
		}
	// This fills the end of the first page
	if (putOnSamePage)
		{
		assert( !partialPageRect.IsEmpty() );
		if (!DrawRegions(p, partialPageRect, width, &currentRow))
			{
			return kTrue;
			}
		}
	// Now we start filling other pages
	while (1)
		{
		if (!p.NewPage())
			{
			SetColBorderInfo(1, GetColormap()->GetGray80Color());
			SetRowBorderInfo(1, GetColormap()->GetGray80Color());
			return kFalse;
			}
		if (!DrawRegions(p, p.GetPageRect(), width, &currentRow))
			{
			return kTrue;
			}
		}
	return kTrue;	
}

/******************************************************************************
 DrawRegions (private)

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

JBoolean
JXCursorMarkTable::DrawRegions
	(
	JPainter& 			p, 
	const JRect 		pageRect, 
	const JCoordinate 	regionWidth,
	JIndex* 			currentRow
	)
{
	const JCoordinate pageWidth = pageRect.width();
	const JSize regionsPerPage  = pageWidth/regionWidth;
	for (JSize i = 1; i <= regionsPerPage; i++)
		{
		JRect regionRect 	= pageRect;
		regionRect.left 	= regionRect.left + (i - 1) * regionWidth;
		regionRect.right	= regionRect.left + regionWidth;
		JSize rows			= regionRect.height()/GetRowHeight(1);
		
		JCoordinate bottomRow = *currentRow + rows - 1;
		JCoordinate top = (*currentRow - 1) * GetRowHeight(1);
		JRect cellRect(top, 0, 
						rows * GetRowHeight(1) + top, regionWidth);
		*currentRow = bottomRow + 1;
		TableDrawCells(p, cellRect, regionRect);
		if (*currentRow > GetRowCount())
			{
			SetColBorderInfo(1, GetColormap()->GetGray80Color());
			SetRowBorderInfo(1, GetColormap()->GetGray80Color());
			return kFalse;
			}
		}
	return kTrue;
}

/******************************************************************************
 TableDrawCells (public)

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

void
JXCursorMarkTable::TableDrawCells
	(
	JPainter& 	p, 
	const JRect cellRect, 
	const JRect regionRect
	)
{
	const JPoint start = cellRect.topLeft() - regionRect.topLeft();
	p.SetClipRect(regionRect);
	p.ShiftOrigin(-start);
	TableDraw(p, cellRect);
	p.ShiftOrigin(start);
	p.Reset();
}
