/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information.       */
/* Contact email: mac@aarongiles.com                     */
/*********************************************************/

#if THINK_C
#include "THINK.Header"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif

/*
 * Local variables:
 *   lColorsWindow = pointer to the colors window
 *
 */

static WindowPtr gColorsWindow = nil;

/*
 * OpenColors()
 *
 *     Purpose: Creates and initializes the colors window
 *      Inputs: none
 *     Returns: nothing
 *
 */
 
OSErr OpenColors(void) 
{
	Rect theRect, mainRect;
	OSErr theErr = noErr;
	Point where;
	
	if (gColorsWindow) {
		if (!WindowVisible(gColorsWindow)) FWShowWindow(gColorsWindow);
		return noErr;
	}
	if (!(gColorsWindow = AllocateWindow())) return memFullErr;
	PushPort();
	MySetPort(nil);
	if (gColorsWindow = FWGetNewFloatingWindow(rColorsWindow, (Ptr)gColorsWindow, 
			(WindowPtr)-1)) {
		MySetPort((CGrafPtr)gColorsWindow);
		theRect = gColorsWindow->portRect;
		OffsetRect(&theRect, -theRect.left, -theRect.top);
		if (gThePrefs.colorsBounds.top != gThePrefs.colorsBounds.bottom) {
			gThePrefs.colorsBounds.right = gThePrefs.colorsBounds.left + Width(&theRect);
			gThePrefs.colorsBounds.bottom = gThePrefs.colorsBounds.top + Height(&theRect);
		}
		GetActiveRect(gMainMonitor, &mainRect);
		where.h = mainRect.right - kWindowBorderWidth - Width(&theRect);
		where.v = mainRect.top + kWindowBorderHeight + GetMBarHeight() + gTitleBarHeight;
		PlaceWindow(gColorsWindow, &gThePrefs.colorsBounds, where);
		gThePrefs.colorsOpen = true;
		PopPort();
		return noErr;
	} else theErr = memFullErr;
	CloseColors();
	PopPort();
	return theErr;
}

/*
 * CloseColors()
 *
 *     Purpose: Closes the colors window
 *      Inputs: none
 *     Returns: nothing
 *
 */

void CloseColors(void)
{
	PushPort();
	MySetPort(nil);
	if (gColorsWindow) {
		gThePrefs.colorsOpen = false;
		SaveWindowPosition(gColorsWindow, &gThePrefs.colorsBounds);
		FWCloseWindow(gColorsWindow);
		DeallocateWindow(gColorsWindow);
	}
	gColorsWindow = nil;
	PopPort();
}

/*
 * GetColorsWindow()
 *
 *     Purpose: Returns a pointer to the statistics window
 *      Inputs: none
 *     Returns: nothing
 *
 */
 
WindowPtr GetColorsWindow(void)
{
	return gColorsWindow;
}

/*
 * DrawColorsWindow()
 *
 *     Purpose: Draws the statistics window
 *      Inputs: none
 *     Returns: nothing
 *
 */
 
void DrawColorsWindow(void) 
{
	short rows, cols, rowSize, colSize, theDepth, r, c;
	CTabHandle theColors;
	GDHandle theDevice;
	RGBColor theColor;
	Rect theRect;

	if (!gColorsWindow) return;
	PushPort();
	MySetPort((CGrafPtr)gColorsWindow);
	theRect = gColorsWindow->portRect;
	GlobalRect(&theRect, gColorsWindow);
	theDevice = GetMaxDevice(&theRect);
	CalcVis((WindowPeek)gColorsWindow);
	if (theDevice) {
		theDepth = (*(*theDevice)->gdPMap)->pixelSize;
		theColors = (*(*theDevice)->gdPMap)->pmTable;
		if (theDepth <= 8) {
			switch (theDepth) {
				case 1: rows = 1, cols = 2; break;
				case 2: rows = 1, cols = 4; break;
				case 4: rows = 2, cols = 8; break;
				case 8: rows = 8, cols = 32; break;
			}
			rowSize = Height(&gColorsWindow->portRect) / rows - ((rows == 1) ? 1 : 0);
			colSize = Width(&gColorsWindow->portRect) / cols;
			for (r = 0; r < rows; r++)
				for (c = 0; c < cols; c++) {
					RGBForeColor(&(*theColors)->ctTable[r * cols + c].rgb);
					theRect.left = colSize * c + 1;
					theRect.right = theRect.left + colSize - 1;
					theRect.top = rowSize * r + 1;
					theRect.bottom = theRect.top + rowSize - 1;
					PaintRect(&theRect);
				}
			RGBForeColor(&gWhite);
			for (c = 0; c <= cols; c++) {
				MoveTo(c * colSize, gColorsWindow->portRect.top);
				LineTo(c * colSize, gColorsWindow->portRect.bottom);
			}
			for (r = 0; r <= rows; r++) {
				MoveTo(gColorsWindow->portRect.left, r * rowSize);
				LineTo(gColorsWindow->portRect.right, r * rowSize);
			}
		} else {
			colSize = Width(&gColorsWindow->portRect) / 256;
			rowSize = Height(&gColorsWindow->portRect) / 4;
			theRect.left = 1;
			theRect.right = 1 + colSize;
			for (c = 255; c > 0; c--) {
				theRect.top = 1;
				theRect.bottom = rowSize;
				theColor.red = theColor.green = theColor.blue = c << 8;
				RGBForeColor(&theColor);
				PaintRect(&theRect);
				theRect.top += rowSize;
				theRect.bottom += rowSize;
				theColor.green = theColor.blue = 0;
				RGBForeColor(&theColor);
				PaintRect(&theRect);
				theRect.top += rowSize;
				theRect.bottom += rowSize;
				theColor.green = theColor.red;
				theColor.red = 0;
				RGBForeColor(&theColor);
				PaintRect(&theRect);
				theRect.top += rowSize;
				theRect.bottom += rowSize;
				theColor.blue = theColor.green;
				theColor.green = 0;
				RGBForeColor(&theColor);
				PaintRect(&theRect);
				theRect.left += colSize;
				theRect.right += colSize;
			}
		}
	}
	PopPort();
}	

/*
 * DoColorsHelp(globalPt)
 *
 *     Purpose: Pops up help for the colors windoid; needed because it should be displayed even
 *					if it's not "active"
 *      Inputs: globalPt = point, in global coordinates, where the mouse is
 *     Returns: nothing
 *
 */
 
void DoColorsHelp(Point globalPt)
{
	HMMessageRecord theRecord;
	Point tip = { 0, 0 };
	Rect aRect;
	
	if (HMIsBalloon() || gInBackground) return;
	PushPort();
	SetPort(gColorsWindow);
	if (HMExtractHelpMsg(kHMRectListResType, rColorsWindow, 1, kHMEnabledItem, &theRecord) == noErr) {
		tip = globalPt;
		aRect = gColorsWindow->portRect;
		GlobalRect(&aRect, gColorsWindow);
		HMShowBalloon(&theRecord, tip, &aRect, nil, 0, 0, kHMRegularWindow);
	}
	PopPort();
}
