// COPYRIGHT (C) 1990-1999.  All Rights Reserved. - REPORT.CPP
// Zinc Software Incorporated.  Pleasant Grove, Utah  USA
// May be freely copied, used and distributed.

#include <zaf.hpp>
#include "report.hpp"

// For DOS programs run under platforms such as Windows 95 or NT you
// should be sure that the printer port is captured, otherwise the app
// may appear to hang or function very slowly.

ReportWindow::ReportWindow(void) :
	ZafWindow(0, 0, 40, 10), printer()
{
	// Add the decorations to the window.
	AddGenericObjects(new ZafStringData(ZAF_ITEXT("Report Window")));

	// Center the window on the screen.
	zafWindowManager->Center(this);

	// Add the menu.
	ZafPullDownMenu *menuBar = new ZafPullDownMenu;
	ZafPullDownItem *fileMenu = new ZafPullDownItem(ZAF_ITEXT("File"));
	fileMenu->SetHotKey('F', 0);
	ZafPopUpItem *menuItem = new ZafPopUpItem(ZAF_ITEXT("Print"));
	menuItem->SetHotKey('P', 0);
	menuItem->SetSendMessageWhenSelected(true);
	menuItem->SetValue(PRINT_REPORT);
	fileMenu->Add(menuItem);
	menuItem = new ZafPopUpItem(ZAF_ITEXT(""), ZAF_SEPARATOR);
	fileMenu->Add(menuItem);
	menuItem = new ZafPopUpItem(ZAF_ITEXT(""), ZAF_EXIT_OPTION);
	fileMenu->Add(menuItem);
	menuBar->Add(fileMenu);
	Add(menuBar);

	vList = new ZafVtList(0, 0, 0, 0);
	vList->SetRegionType(ZAF_AVAILABLE_REGION);
	vList->Add(new ZafScrollBar(0, 0, 0, 0));

	// Fill the list with data.
	ZafIChar string[128];
	for (int i = 1; i <= 100; i++)
	{
		sprintf(string, ZAF_ITEXT("Line %d"), i);
		vList->Add(new ZafString(0, 0, 40, string, -1));
	}

	// Add the list to the window.
	Add(vList);
}

#if defined(ZAF_DEFAULT_DRAW)
// nextChild is 1-based.
int ReportWindow::DrawPage(int page, int nextChild)
{
	ZafCoordinate line = 0, lineHeight = 0;
	if (page == 1)
	{
		// Draw the report title.
		line = printer.TextLine(0, line, printer.PageWidth(),
			ZAF_ITEXT("Sample Report"), -1, ZAF_HZ_CENTER);
		lineHeight = line;

		// Include a blank line.
		line += lineHeight;
	}

	// Draw the page header.
	ZafIChar pHeader[64];
	sprintf(pHeader, ZAF_ITEXT("Page %d"), page);
	line = printer.TextLine(0, line, printer.PageWidth(), pHeader, -1,
		ZAF_HZ_CENTER);

	// Include a blank line.
	if (!lineHeight)
		lineHeight = line;
	line += lineHeight;

	// Draw the data lines that will fit on the page.
	for (ZafWindowObject *child = vList->First(); child; child = child->Next())
		if (child->ListIndex() + 1 == nextChild)
		{
			if (line + lineHeight <= printer.PageHeight())
			{
				line = printer.TextLine(0, line, printer.PageWidth(),
					child->Text());
				++nextChild;
			}
			else
			{
				// nextChild is the first child to draw on the next page.
				return (nextChild);
			}
		}

	// Return zero to signify no more children.
	return (0);
}
#endif

ZafEventType ReportWindow::Event(const ZafEventStruct &event)
{
	ZafEventType ccode = event.type;

	switch (ccode)
	{
	case PRINT_REPORT:
		{
		// Initialize a print job structure.
		ZafPrintJobStruct job;
		job.collate = false;
		job.copies = 1;
		job.startPage = job.endPage = currentPage = 1;
		job.minPage = 1;
		job.maxPage = 2;

		// Present the print dialog and fill the job structure.
		// This example is not set up to print from other than the first page,
		// so disable page range modification.
		ZafPrintDialog printDialog(0, 0, &printer, &job);
		printDialog.SetAllowModifyRange(false);
		if (printDialog.Control() == S_DLG_OK)
		{
			// Begin a print job.
			if (printer.BeginJob(ZAF_ITEXT("Sample Report")) != ZAF_ERROR_NONE)
			{
				zafErrorSystem->ReportError(ZAF_NULLP(ZafWindowObject),
					ZAF_ITEXT("Error"), ZAF_DIALOG_OK,
					ZAF_ITEXT("Uanble to initialize print job."));

				break;
			}

			// Collate is true only if collation must be done manually.
			if (job.collate)
			{
				// copies is greater than 1 only if multiple copies must
				// be done manually.
				for (int copy = 0; copy < job.copies; copy++)
				{
					int nextChild = 1;
					for (int page = job.startPage; page <= job.endPage; page++)
					{
						// Begin a new page.
						printer.BeginPage();

						// Draw the page.
						nextChild = DrawPage(page, nextChild);

						// End the page.
						printer.EndPage();
					}
				}
			}
			else
			{
				int nextChild = 1;
				for (int page = job.startPage; page <= job.endPage; page++)
				{
					int nextPageChild = 0;
					for (int copy = 0; copy < job.copies; copy++)
					{
						// Begin a new page.
						printer.BeginPage();

						// Draw the page.
						nextPageChild = DrawPage(page, nextChild);

						// End the page.
						printer.EndPage();
					}
					nextChild = nextPageChild;
				}
			}
			printer.EndJob();
		}
		}
		break;

	default:
		ccode = ZafWindow::Event(event);
	}

	return (ccode);
}

int ZafApplication::Main(void)
{
	// Ensure main() is linked properly.
	LinkMain();

	// Display the window.
	zafWindowManager->Add(new ReportWindow);

	// Get the user input.
	Control();

	// Return success.
	return (0);
}

