/* main.c */

#include <OSIncludes.h>

#pragma header

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LVO_ObtainBestPenA -840

extern "ASM" void OBPEntry(void);
extern "ASM" LONG GoOld_OBP(register __a0 struct ColorMap *cm,register __d1 ULONG r, register __d2 ULONG g,register __d3 ULONG b,register __a1 struct TagItem *tags);

struct Library *GfxBase;
struct Task *WBTask;
APTR oldfunc,p;


LONG New_ObtainBestPenA(struct ColorMap *cm, ULONG r, ULONG g,ULONG b,struct TagItem *tags)
{
	struct PaletteExtra *pe;
	struct Task *t;
	LONG ret;
	WORD  r2,g2,b2;
	UWORD *rgbtable;
	UWORD oldrgb0;
	BOOL IsWorkbench;

	ret=GoOld_OBP(cm,r,g,b,tags);	// call old ObtainBestPen
	
	if (ret==0)
	{
		IsWorkbench=FALSE;
		
		t=FindTask(NULL);
		if (WBTask)
		{
			// fast check, once we know the WBTask
			if (t==WBTask) IsWorkbench=TRUE;
	
		} else {
			// slow check until we know the WBTask
	
			if (strcmp(t->tc_Node.ln_Name,"Workbench")==0)
			{
				IsWorkbench=TRUE;
				WBTask=t;
			}
		}
	
		if (IsWorkbench)
		{
			// Workbench is calling ...
	
			ReleasePen(cm,ret);	// we don't like pen 0 >:(

			// I don't know if it's enough calling ObtainSemaphore
			// here... mayebe Forbid would be better :-?

			pe=cm->PalExtra;
			ObtainSemaphore(&pe->pe_Semaphore);
			rgbtable=cm->ColorTable;
			// rgbtable contains the higher 4 bits (like copper):
			// % 0 0 0 0 R7 R6 R5 R4 G7 G6 G5 G4 B7 B6 B5 B4

			oldrgb0=rgbtable[0];							// save rgb of col 0

			// change rgb of col 0,
			// so that the probablity that we
			// get returned 0 when we call OBP again is
			// reduced to a minimum
			
			r2=r>>24;if (r2>128) r2=0; else r2=15;
			g2=g>>24;if (g2>128) g2=0; else g2=15;
			b2=b>>24;if (b2>128) b2=0; else b2=15;

			rgbtable[0]=(r2<<8)+(g2<<4)+b2;

			ret=GoOld_OBP(cm,r,g,b,tags);				// call OBP again

			rgbtable[0]=oldrgb0;							// restore rgb of col 0
			
			ReleaseSemaphore(&pe->pe_Semaphore);
	
		} // if (IsWorkbench)

	} // if (ret==0)

	return ret;
}

void main(void)
{
	BOOL quitme=FALSE;

	GfxBase=(struct Library *)OpenLibrary("graphics.library",36);
	
	Forbid();
	oldfunc=SetFunction(GfxBase,LVO_ObtainBestPenA,(APTR) OBPEntry);
	Permit();
	
	do {
		Wait(SIGBREAKF_CTRL_C);

		Forbid();
		p=SetFunction((struct Library *)GfxBase,LVO_ObtainBestPenA,oldfunc);
		if (p==OBPEntry)
		{
			quitme=TRUE;
		} else {
			SetFunction((struct Library *)GfxBase,LVO_ObtainBestPenA,p);
		}
		Permit();
		
	} while (!quitme);
	
	
	CloseLibrary(GfxBase);
}
