/*Color.c*/
/*Puts up a color requestor to get the screen colors for 'Liner*/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <exec/exec.h>
#include <graphics/displayinfo.h>
#include <utility/tagitem.h>
#include <libraries/gadtools.h>

extern struct TextAttr Topaz;

#include "ColorWdw.h"

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct Window *Wdw;

#define Rp Wdw->RPort
#define Vp Wdw->WScreen->ViewPort

#define RED 1
#define GREEN 2
#define BLUE 3

#define SLIDER_WIDTH_15KHZ 4096
#define SLIDER_WIDTH_31KHZ 16383

#define SLIDER_MULT_15KHZ 4369
#define SLIDER_MULT_31KHZ 21845

extern ColorReq();
void UpdateColorReg();
void RestoreColors();
void SetSliders();

struct TagItem bbTag[]=
{
   {GT_VisualInfo,NULL},
   {TAG_DONE,NULL}
};


ColorReq(Scrn,Type,VisInfo)
struct Screen *Scrn;
ULONG Type;
APTR VisInfo;
{
   struct Gadget *it;
   struct PropInfo *prop;

   ULONG Class;
   SHORT MouseX;
   USHORT color=0;
   struct IntuiMessage *mesg;
   USHORT CurrentGadget;
   USHORT Colors[4];
   ULONG OldColors[4];
   UWORD SliderMult;
   struct textFont *Topaz_tf;
   UWORD Y_Add;
   UBYTE DivBy;
   struct Gadget *IAGadget;
   BYTE c;

   ULONG rgb;

      /*Make room for the title bar*/
   NewWindowStructure1.Height+=(Y_Add=Scrn->Font->ta_YSize-Topaz.ta_YSize);

   NewWindowStructure1.Type=CUSTOMSCREEN;
   NewWindowStructure1.Screen=(struct Screen *)Scrn;

   Topaz_tf=(struct textFont *)OpenFont(&Topaz);

   if(Topaz_tf == NULL)    /*If topaz 8 couldn't be opened*/
      return(FALSE);       /*The machine deserves to crash :-) */

   MakeButtonGadgets(&ColorBar,&Reset,VisInfo,&Topaz,1,Y_Add);

   BlueSlider.TopEdge+=Y_Add;
   RedSlider.TopEdge+=Y_Add;
   GreenSlider.TopEdge+=Y_Add;

   if(Type & VGA_MONITOR_ID) /*If productivity mode*/
   {	    /*Give the users the more limited color choices*/
      DivBy=4;
      SliderMult=SLIDER_MULT_31KHZ;
      GreenSliderSInfo.HorizBody=RedSliderSInfo.HorizBody=
	    BlueSliderSInfo.HorizBody=SLIDER_WIDTH_31KHZ;
   }
   else
   {
      DivBy=1;
      SliderMult=SLIDER_MULT_15KHZ;
      GreenSliderSInfo.HorizBody=RedSliderSInfo.HorizBody=
	    BlueSliderSInfo.HorizBody=SLIDER_WIDTH_15KHZ;
   }

   Wdw=(struct Window *)OpenWindow(&NewWindowStructure1);
   if(Wdw==NULL)
      return(FALSE);

   NewWindowStructure1.Height-=Y_Add;

   SetFont(Wdw->RPort,Topaz_tf);
   bbTag[0].ti_Data=(Tag)VisInfo;

      /*Draw bevel boxes around various parts of the window*/
   DrawBevelBoxA(Wdw->RPort,35,38+Y_Add,192,11,bbTag);
   DrawBevelBoxA(Wdw->RPort,35,27+Y_Add,192,11,bbTag);
   DrawBevelBoxA(Wdw->RPort,35,16+Y_Add,192,11,bbTag);
   DrawBevelBoxA(Wdw->RPort,286,15+Y_Add,29,35,bbTag);
   DrawBevelBoxA(Wdw->RPort,7,51+Y_Add,262,16,bbTag);

      /*Draws the four screen colors (so the user can select which*/
      /*one he wants to change.  Rather useful...*/
   SetAPen(Rp,1);
   RectFill(Rp,9+64,53+Y_Add,9+127,64+Y_Add);
   SetAPen(Rp,2);
   RectFill(Rp,9+128,53+Y_Add,9+191,64+Y_Add);
   SetAPen(Rp,3);
   RectFill(Rp,9+192,53+Y_Add,9+255,64+Y_Add);
   PrintIText(Rp,&IntuiTextList1,0,Y_Add);

      /*Store the colors before we do anything*/
   for(c=0;c<4;c++)
      OldColors[c]=GetRGB4(Vp.ColorMap,c);

   rgb=GetRGB4(Vp.ColorMap,0);

   SetSliders(Colors,SliderMult,rgb,DivBy);

   UpdateNum(RED,Colors[RED],Y_Add,DivBy);
   UpdateNum(GREEN,Colors[GREEN],Y_Add,DivBy);
   UpdateNum(BLUE,Colors[BLUE],Y_Add,DivBy);

   RefreshGadgets(&RedSlider,Wdw,NULL);

   for(;;)
   {
      Wait(1<<Wdw->UserPort->mp_SigBit);
      while((mesg=(struct IntuiMessage *)GetMsg(Wdw->UserPort))!=NULL)
      {
	 it=(APTR)mesg->IAddress;
	 Class=mesg->Class;
	 MouseX=mesg->MouseX;
	 IAGadget=(APTR)mesg->IAddress;
	 ReplyMsg(mesg);

	 switch(Class)
	 {
	    case GADGETUP:
	       RestoreColors(OldColors,color,Colors,SliderMult,Y_Add,DivBy);
	       break;
	    case CLOSEWINDOW:
	       CloseWindow(Wdw);
	       CloseFont(Topaz_tf);
	       FreeGadgets(ColorBar.NextGadget);

	       BlueSlider.TopEdge-=Y_Add;
	       RedSlider.TopEdge-=Y_Add;
	       GreenSlider.TopEdge-=Y_Add;

	       return(TRUE);
	    case GADGETDOWN:
	       CurrentGadget=it->GadgetID;
	       if(CurrentGadget < 4)
	       {
		  prop=(APTR)it->SpecialInfo;
		  UpdateNum(CurrentGadget,(Colors[CurrentGadget]=
			(prop->HorizPot) >> 12 ),Y_Add,DivBy);
		  UpdateColorReg(color,Colors,&Vp);
	       }
	       else
	       {
		  color=(MouseX-9)/64;
		  rgb=GetRGB4(Vp.ColorMap,color);

		  SetSliders(Colors,SliderMult,rgb,DivBy);

		  UpdateNum(RED,Colors[RED],Y_Add,DivBy);
		  UpdateNum(GREEN,Colors[GREEN],Y_Add,DivBy);
		  UpdateNum(BLUE,Colors[BLUE],Y_Add,DivBy);

		  RefreshGadgets(&RedSlider,Wdw,NULL);
		  SetAPen(Rp,color);
		  RectFill(Rp,290,17+Y_Add,310,47+Y_Add);
	       }
	       break;
	    case MOUSEMOVE:
	       UpdateNum(CurrentGadget,
		     (Colors[CurrentGadget]=(prop->HorizPot >> 12)),Y_Add,DivBy);
	       UpdateColorReg(color,Colors,&Vp);
	 }
      }
   }
}

UpdateNum(Color,value,Y_Add,DivBy)
USHORT Color,value;
UWORD Y_Add;
UBYTE DivBy;
{
   char Num[4];
   UBYTE TrueValue = value/DivBy;

   if(value > 15)
      return(FALSE); /*Get rid of funny answers*/
   SetAPen(Rp,1);
   Move(Rp,15,15+(Color*10)+Y_Add);

   if(TrueValue > 9)
      stci_d(Num,value);
   else
   {
      stci_d(&Num[1],TrueValue);
      Num[0]=' ';
   }
   Text(Rp,Num,2);
   return(TRUE);
}

void UpdateColorReg(reg,colors,ViewPort)
USHORT reg,*colors;
struct ViewPort *ViewPort;
{
   SetRGB4(ViewPort,reg,colors[RED],colors[GREEN],colors[BLUE]);
}

void RestoreColors(OldColors,curreg,Colors,SliderMult,Y_Add,DivBy)
ULONG *OldColors;
BYTE curreg;
USHORT *Colors;
UWORD SliderMult;
UWORD Y_Add;
UBYTE DivBy;
{
   BYTE c;
   USHORT red,green,blue;

   for(c=0;c<4;c++)
   {
      red = (OldColors[c]>>8) & 0xF;
      green = (OldColors[c]>>4) & 0xF;
      blue = OldColors[c] & 0xF;
      SetRGB4(&Vp,c,red,green,blue);
      if(c==curreg)
      {
	 SetSliders(Colors,SliderMult,OldColors[c],DivBy);

	 UpdateNum(RED,Colors[RED],Y_Add,DivBy);
	 UpdateNum(GREEN,Colors[GREEN],Y_Add,DivBy);
	 UpdateNum(BLUE,Colors[BLUE],Y_Add,DivBy);

      }
   }
}

void SetSliders(Colors,SliderMult,rgb,DivBy)
USHORT *Colors;
UWORD SliderMult;
ULONG rgb;
UBYTE DivBy;
{
   UBYTE Color;

   Color=(rgb >> 8 & 0x0F) / DivBy;
   RedSliderSInfo.HorizPot=(Colors[RED]=Color*DivBy) * SliderMult;

   Color=(rgb & 0x0F) / DivBy;
   BlueSliderSInfo.HorizPot=(Colors[BLUE]=Color*DivBy) * SliderMult;

   Color=(rgb >> 4 & 0x0F) / DivBy;
   GreenSliderSInfo.HorizPot=(Colors[GREEN]=Color*DivBy) * SliderMult;

   RefreshGadgets(&RedSlider,Wdw,NULL);
}

/*~~~End of color.c*/
