Macro_file Colors;

#include windows.sh
#include mew_dlgs.sh
#include dialog.sh
#include mewlist2.sh
#include commdlg.sh
#include colordlg.sh
#include colors.sh
#include metools.sh
#include mewhelp.sh
#include mewlib.sh


#define MAXTEMPLATELEN  32
#define MAXCOLORS       64
#define NUMBASICCOLORS  48
#define NUMCUSTOMCOLORS 16
#define NUMCOLORSROW    8

#define _CO_BASIC       720
#define _CO_CUSTOM      721
#define _CO_TNAME       751
#define _CO_SAVETNAME   752
#define _CO_DELTNAME    753
#define _CO_BOLD        760
#define _CO_ITALIC      761
#define _CO_NODISPLAY   765
#define _CO_USEFONT     766
#define _CO_USECOLOR    767
#define _CO_LISTSTATIC  755
#define _CO_SYNTAX      780
#define _CO_SYNTAXLINE  781
#define _CO_COLORLIST   790
#define _CO_DEFINENEW   791
#define _CO_HELP        792


#define CO_ID_HELP     1038

// Color Control Messages
#define WM_CO_SETFG     0x601
#define WM_CO_SETBG     0x602
#define WM_CO_ADDCUSTOM 0x603
#define WM_CO_END       0x604

// Color Control Notification Messages
#define CON_NOTIFY      1

// Record Constant Strings for DB
#define NAME_REC      "NAME="
#define FG_REC        "/FC="
#define BG_REC        "/BC="
#define ATTR_REC      "/AT="
#define FONT_REC      "/FT="
#define TEXT_REC      "/TX="
#define IDX_REC       "INDEX="
#define FLAGS_REC     "FLAGS="
#define REALFG_REC    "RFG="
#define REALBG_REC    "RBG="
#define REALATTR_REC  "RAT="

#define CO_HELPLINK "Colors, Configuring"
#define CA_HELPLINK "Custom Colors"

#define DBFILE      "MECONFIG"
#define COLORPAGE   "COLORS.DB"
#define CUSTOMPAGE  "CUSTOMRGB.DB"

#define COL_OFF     0x0001
#define COL_USE     0x0002
#define COL_FONTS   0x0004


Global
{
	int ColorsChanged   "~ColorsChanged";
	str GColorInfo      "@GColorInfo";
	int ColorBuf        "@ColorBuf";
	int ColorFGindex    "@ColorFGIndex";
	int ColorBGIndex    "@ColorBGIndex";
	str ColorTemplate   "@ColorTemplate";
  str ColorNormal     "@ColorNormal";
	int FBIndex         "~CustomIndex";
}

struct ColorInfo
{
	int RGBValues [MAXCOLORS];
}

struct TColorRec
{
	ASCIIZ  template [ 32];
	Int     customcolors  [16];

}

void ShowStruct (int window, struct ColorInfo cinfo)
{
	str tstr [1024];
	for ( int jx = 0; jx < MAXCOLORS; jx += 4)
	{
		tstr = tstr + hex_str (cinfo.RGBValues[jx]) + "  ";
		tstr = tstr + hex_str (cinfo.RGBValues[jx+ 1]) + "  ";
		tstr = tstr + hex_str (cinfo.RGBValues[jx+ 2]) + "  ";
		tstr = tstr + hex_str (cinfo.RGBValues[jx+ 3]) + "\n";
	}
	MessageBox (window, tstr, "COLORVALUES", MB_OK);
}

int ColorCustomHook( int dlg, int message, int wparam, int lparam, struct tChooseColor chrec ) No_Break
{

	int result = 0;
	switch ( message )
	{
		case WM_INITDIALOG :
		{
			struct TRect r1;
			struct TRect r2;

			GetWindowRect  (GetDlgItem (GetParent (dlg), _CO_CUSTOM), &r1);
			GetWindowRect  (dlg, &r2);

			int x = r1.left - (r2.right - r2.left) - GetSystemMetrics (SM_CXFRAME);

			GetClientRect  (GetParent (dlg), &r1);
			ClientToScreen (GetParent (dlg), &r1);
			int y = r1.top;
			MoveWindow (dlg, x, y, r2.right - r2.left, r2.bottom - r2.top, TRUE);
			break;
		}

		case WM_ACTIVATE :
		{
			if ( wparam )
			{
				HelpLink_String = CA_HELPLINK;
			}
			else
			{
				HelpLink_String = "";
			}
			break;
		}

		case WM_COMMAND :
		{
			switch ( wparam )
			{
				case CO_ID_HELP :
					MewHelp_Context();
					result = 1;
					break;

				case COLOR_ADD :
				{
					int rgb;
					int error;

					rgb  = GetDlgItemInt(dlg, COLOR_RED, error, FALSE);
					rgb |= GetDlgItemInt(dlg, COLOR_GREEN, error, FALSE) << 8;
					rgb |= GetDlgItemInt(dlg, COLOR_BLUE, error, FALSE)  << 16;

					SendMessage (GetParent (dlg), WM_CO_ADDCUSTOM, 0, rgb);
					result = 1;
				}
			}
		}
	}

	return (result);
}


void AddCustomColor (int parent = parse_int ("/DLGHANDLE=", mparm_str),
                     str gstr   = parse_str ("/GL=", mparm_str))
{
	int twin_id;
	int result;
	int tRefresh = refresh;

	struct TChooseColor chrec;
	struct TColorRec    cprec;
  struct ColorInfo cinfo;

  str tstr [1024] = Global_Str (gstr);
  str_to_struct (cinfo, tstr);
	refresh = FALSE;

	cprec.template  = "COLORCUSTOM";
	for ( int jx = 0; jx < NUMCUSTOMCOLORS; jx++ )
	{
		cprec.customcolors[jx] = cinfo.RGBValues[NUMBASICCOLORS + jx];
	}

	chrec.hWndOwner       = parent;
	chrec.HInstance       = app_handle;
	chrec.RGBResult       = cprec.customcolors[0];
	chrec.Flags           = CC_ENABLETEMPLATE | CC_SHOWHELP | CC_FULLOPEN | CC_RGBINIT;
	chrec.lpCustColors    = &cprec.customcolors;
	chrec.lCustData       = 0;
	chrec.lpfnHook        = 0;
	chrec.lpTemplateName  = &cprec.template;

	result = HookColorPromptWithMacro ( &chrec, "ColorCustomHook");

	refresh = tRefresh;
	return ();
}

int GetAttrLineFont (int attr, str & exstr)
{
  int font, nfont, bfont, ifont, ibfont;

  Get_Window_Font_Handle (0, nfont, bfont, ifont, ibfont);

  exstr = "";
  font = nfont;
  switch ( attr & MEWSTYLE )
  {
  case MEWBOLD :
    if ( !bfont)
    {
      exstr = "/SB=1";
    } else {
      font = bfont;
    }
    break;
  case MEWITALIC :
    font = ifont;
    break;

  case MEWSTYLE :
    font = ibfont;
  }
  return (font);
}

//
//
// mebuf = me window num, if 0 then set default table
void SetListAttrs (int dlg, int mebuf)
{
	int index, fg, bg, attr;
	str tstr;
	int bFlag = 0;

	int lbuf = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0 ,0);
	int obuf = cur_window;
	switch_window (lbuf);
	tof;

	while ( !at_eof)
	{
		tstr  = get_line;
		index = parse_int (IDX_REC, tstr);
		if ( index >= 0)
		{
      fg    = parse_int (REALFG_REC, tstr);
      bg    = parse_int (REALBG_REC, tstr);
      attr  = parse_int (REALATTR_REC, tstr);
			Set_Mew_Attr (mebuf, index, fg, bg, attr);
		}
		down;
	}
	tof;

	struct TRect r;
	GetClientRect (frame_handle, &r);
	RedrawWindow (frame_handle, &r, 0, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
	switch_window (obuf);
}

//
//
// mebuf = me window num, if 0 then set default table
// tname = name of color/attr template
int SetTemplateAttrs (int mebuf, str template)
{
	int oid = window_id;

	int result = 0;
	str dbstr [2048];
	str tstr, recstr;
	int jx;
	int fg, bg, attr;

	template = caps (template);
	if( LocateDbPage( DBFILE, COLORPAGE, FALSE) )
	{
		down;
		while( !at_eof && (cur_char != '|12'))
		{
			dbstr = get_line;
			if (caps(parse_str (NAME_REC, dbstr)) == template)
			{
				call SetColorline;
				result = 1;
			}
			down;
		}
	}
	switch_win_id (oid);
	RedrawWindow (frame_handle, 0, 0, RDW_INVALIDATE);
	return (result);


SetColorLine:
	// Parse out each Color Record
	jx      = Text_Attr;
	recstr  = "NT=";
	call docolor;
	jx      = Highlight_Attr;
	recstr  = "HT=";
	call docolor;
	jx      = Search_Attr;
	recstr  = "ST=";
	call docolor;
	jx      = Page_Attr;
	recstr  = "PT=";
	call docolor;
	jx      = Changed_Attr;
	recstr  = "CT=";
	call docolor;
	jx      = EOF_Attr;
	recstr  = "ET=";
	call docolor;
	jx      = LineNormal_Attr;
	recstr  = "LT=";
	call docolor;
	jx      = LineBlock_Attr;
	recstr  = "LBT=";
	call docolor;
	jx      = LineChanged_Attr;
	recstr  = "LCT=";
	call docolor;
	jx      = Margin_Attr;
	recstr  = "MT=";
	call docolor;

	jx      = Reserved_Attr;
	recstr  = "REST=";
	call docolor;
	jx      = Symbol_Attr;
	recstr  = "SYMT=";
	call docolor;
	jx      = EolComment1_Attr;
	recstr  = "EOL1T=";
	call docolor;
	jx      = EolComment2_Attr;
	recstr  = "EOL2T=";
	call docolor;
	jx      = OpComment1_Attr;
	recstr  = "CMT1T=";
	call docolor;
	jx      = OpComment2_Attr;
	recstr  = "CMT2T=";
	call docolor;
	jx      = Numeric_Attr;
	recstr  = "NUMT=";
	call docolor;
	jx      = String_Attr;
	recstr  = "STRT=";
	call docolor;

	jx      = FC_Different_Attr;
	recstr  = "FCD=";
	call docolor;
	jx      = FC_Inserted_Attr;
	recstr  = "FCI=";
	call docolor;
	ret;

docolor:
	tstr  = parse_str (recstr, dbstr);
	fg    = parse_int (FG_REC, tstr);
	bg    = parse_int (BG_REC, tstr);
	attr  = parse_int (ATTR_REC, tstr);
	Set_Mew_Attr (mebuf, jx, fg, bg, attr);
	ret;
}

void InitColorList (str tname, int buf)
{
	str dbstr [2048];
	tname = caps(tname);

  Set_Global_Str ("TEMPLATE_HISTORY", "/#=0/HL=256");
  if( LocateDbPage( DBFILE, COLORPAGE, TRUE) )
	{
		down;
		while( !at_eof && (cur_char != '|12'))
		{
			dbstr = get_line;
      return_str = parse_str (NAME_REC, dbstr);
      if ( caps(return_str) == tname )
      {
        Set_Global_Str ("TEMPLATE_HISTORY0", return_str);
      }
      else
      {
        RM("HISTORY_LIST /M=1/HISTORY=TEMPLATE_HISTORY");
      }
			down;
		}
	}
  if ( buf < 0 )
  {
    return_str = "NONE";
    RM("HISTORY_LIST /M=1/HISTORY=TEMPLATE_HISTORY");
  }
}
void KillColorList ()
{
  int jy = parse_int ("/#=", Global_str ("TEMPLATE_HISTORY"));
  for ( int jx = 0; jx <= jy; jx++ )
  {
    Set_Global_Str ("TEMPLATE_HISTORY" + str(jx), "");
  }
  Set_Global_Str ("TEMPLATE_HISTORY", "");
}

void Setup1ColorList (int dlg, str tname)
{
	int oid = window_id;
	str dbstr [2048];
	str name;
	int bfound = 0;
	int jx, flags;
  str tstr, txstr, recstr;
	int fg, bg, font;
	int attr;

	tname = caps(tname);

  if( LocateDbPage( DBFILE, COLORPAGE, FALSE) )
	{
		down;
		while( !at_eof && (cur_char != '|12'))
		{
			dbstr = get_line;
			name = parse_str (NAME_REC, dbstr);
			if (caps(name) == tname)
			{
				jx = SendDlgItemMessageStr (dlg, _CO_TNAME, CB_FINDSTRINGEXACT, -1, name);
				SendDlgItemMessage (dlg, _CO_TNAME, CB_SETCURSEL, jx, 0);
				call Setlist;
				bfound = True;
			}
			down;
		}
	}
	if ( !bFound )
	{
		dbstr = "";
		call setlist;
	}

	switch_win_id (oid);
	return ();


SetList:
	// Get Default fonts and switch to list buffer for setup
  // Fonts_Get (0, nfont, bfont, ifont);


	int lbuf = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0 ,0);
	int obuf = cur_window;
	switch_window (lbuf);
	tof;

	// Parse out each Color Record
	put_line("@þ=Editing" + IDX_REC + str(-1));
	down;
	flags   = COL_FONTS;
	jx      = Text_Attr;
	recstr  = "NT=";
	txstr   = "Normal Text";
	call DoListLine;
	jx      = Highlight_Attr;
	recstr  = "HT=";
	txstr   = "Highlight Text";
	call DoListLine;
	jx      = Search_Attr;
	recstr  = "ST=";
	txstr   = "Search Highlight Text";
	call DoListLine;
	flags   = COL_FONTS | COL_OFF;
	jx      = Page_Attr;
	recstr  = "PT=";
	txstr   = "Page Break Text";
	call DoListLine;
	jx      = Changed_Attr;
	recstr  = "CT=";
	txstr   = "Changed Text";
	call DoListLine;
	jx      = EOF_Attr;
	recstr  = "ET=";
	txstr   = "End of File";
	call DoListLine;
	jx      = LineNormal_Attr;
	recstr  = "LT=";
	txstr   = "Current Line Text";
	call DoListLine;
	jx      = LineBlock_Attr;
	recstr  = "LBT=";
	txstr   = "Current Line in Block Text";
	call DoListLine;

	flags   = COL_OFF;
	jx      = LineChanged_Attr;
	recstr  = "LCT=";
	txstr   = "Line Changed Marker";
	call DoListLine;

	flags   = COL_OFF;
	jx      = Margin_Attr;
	recstr  = "MT=";
	txstr   = "Right Margin Marker";
	call DoListLine;

	put_line("@þ=Syntax Highlighting" + IDX_REC + str(-1));
	down;

	flags   = COL_FONTS | COL_USE;
	jx      = Reserved_Attr;
	recstr  = "REST=";
	txstr   = "Reserved Words";
	call DoListLine;
	jx      = Symbol_Attr;
	recstr  = "SYMT=";
	txstr   = "Symbol Text";
	call DoListLine;
	jx      = EolComment1_Attr;
	recstr  = "EOL1T=";
	txstr   = "EOL Comment 1";
	call DoListLine;
	jx      = EolComment2_Attr;
	recstr  = "EOL2T=";
	txstr   = "EOL Comment 2";
	call DoListLine;
	jx      = OpComment1_Attr;
	recstr  = "CMT1T=";
	txstr   = "Open\\Close Comment 1";
	call DoListLine;
	jx      = OpComment2_Attr;
	recstr  = "CMT2T=";
	txstr   = "Open\\Close Comment 2";
	call DoListLine;
	jx      = Numeric_Attr;
	recstr  = "NUMT=";
	txstr   = "Numeric Text";
	call DoListLine;
	jx      = String_Attr;
	recstr  = "STRT=";
	txstr   = "String Text";
	call DoListLine;

	put_line("@þ=File Compare" + IDX_REC + str(-1));
	down;
	flags   = COL_FONTS;
	jx      = FC_Different_Attr;
	recstr  = "FCD=";
	txstr   = "FC Difference";
	call DoListLine;
	jx      = FC_Inserted_Attr;
	recstr  = "FCI=";
	txstr   = "FC Inserted";
	call DoListLine;

	ListSetCount (GetDlgItem (dlg, _CO_COLORLIST), c_line-1);
	RedrawWindow (GetDlgItem (dlg, _CO_COLORLIST), 0, 0, RDW_INVALIDATE);
	SendDlgItemMessage  (dlg, _CO_COLORLIST, LB_SETCURSEL, 1, 0);
	switch_window (obuf);
	ret;

DoListLine:
	tstr  = parse_str (recstr, dbstr);

	fg    = parse_int (FG_REC, tstr);
	bg    = parse_int (BG_REC, tstr);
	attr  = parse_int (ATTR_REC, tstr);

	if ( (fg == 0) && (bg == 0) && (attr == 0) )
	{
		Get_Mew_Attr (0, jx, fg, bg, attr);
	}

  put_line( IDX_REC     + str (jx) +
            FLAGS_REC   + str (flags) +
            REALFG_REC  + str (fg) +
            REALBG_REC  + str (bg) +
            REALATTR_REC + str (attr) +
            "C="       +
            TEXT_REC    + txstr);

  if ( jx == Text_Attr )
  {
    ColorNormal = Get_Line;
  }
	down;
	ret;
}
void Setup2ColorList (int dlg)
{
  str tstr [2048];
  int rattr, attr, flags, fg, bg;

	int lbuf = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0 ,0);
	int obuf = cur_window;
	switch_window (lbuf);
  tof;

  while ( !at_eof )
  {
    tstr = get_line;

    fg    = parse_int (REALFG_REC, tstr);
    bg    = parse_int (REALBG_REC, tstr);
    rattr = parse_int (REALATTR_REC, tstr);
    flags = parse_int (FLAGS_REC, tstr);

    attr = rattr;
    if ( ((rattr & MewUseFont)  == 0 ) && ((flags & COL_USE) != 0))
    {
      attr = parse_int (REALATTR_REC, ColorNormal);
    }
    if ( ((rattr & MewUseColor) == 0 ) && ((flags & COL_USE)  != 0))
    {
      fg  = parse_int (REALFG_REC, ColorNormal);
      bg  = parse_int (REALBG_REC, ColorNormal);
    }

    str exstr;
    int font = GetAttrLineFont (attr, exstr);

    tstr += exstr +
            ATTR_REC  + str (attr) +
            FONT_REC  + str (font) +
            FG_REC  + str(fg) +
            BG_REC  + str(bg);

    put_line (tstr);
    down;
  }
  switch_window (obuf);
}
void SetupColorList (int dlg, str tname)
{
  Setup1ColorList (dlg, tname);
  Setup2ColorList (dlg);
}

void SaveColorList (int dlg, str templatename)
{
	str dbstr[2048];
	str tstr, txstr;
	int fg, bg, attr;
	int jx;

	int lbuf = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0 ,0);
	int obuf = cur_window;
	switch_window (lbuf);

	// Parse out each Color Record
	dbstr   = NAME_REC + templatename;

	jx      = Text_Attr;
	txstr  = "NT=";
	call DoDBRec;
	jx      = Highlight_Attr;
	txstr  = "HT=";
	call DoDBRec;
	jx      = Search_Attr;
	txstr  = "ST=";
	call DoDBRec;
	jx      = Page_Attr;
	txstr  = "PT=";
	call DoDBRec;
	jx      = Changed_Attr;
	txstr  = "CT=";
	call DoDBRec;
	jx      = EOF_Attr;
	txstr  = "ET=";
	call DoDBRec;
	jx      = LineNormal_Attr;
	txstr  = "LT=";
	call DoDBRec;
	jx      = LineBlock_Attr;
	txstr  = "LBT=";
	call DoDBRec;
	jx      = LineChanged_Attr;
	txstr  = "LCT=";
	call DoDBRec;
	jx      = Margin_Attr;
	txstr  = "MT=";
	call DoDBRec;

	jx      = Reserved_Attr;
	txstr  = "REST=";
	call DoDBRec;
	jx      = Symbol_Attr;
	txstr  = "SYMT=";
	call DoDBRec;
	jx      = EolComment1_Attr;
	txstr  = "EOL1T=";
	call DoDBRec;
	jx      = EolComment2_Attr;
	txstr  = "EOL2T=";
	call DoDBRec;
	jx      = OpComment1_Attr;
	txstr  = "CMT1T=";
	call DoDBRec;
	jx      = OpComment2_Attr;
	txstr  = "CMT2T=";
	call DoDBRec;
	jx      = Numeric_Attr;
	txstr  = "NUMT=";
	call DoDBRec;
	jx      = String_Attr;
	txstr  = "STRT=";
	call DoDBRec;

	jx      = FC_Different_Attr;
	txstr  = "FCD=";
	call DoDBRec;
	jx      = FC_Inserted_Attr;
	txstr  = "FCI=";
	call DoDBRec;

	templatename = caps(templatename);
	// Search for existing value
	if( LocateDbPage( DBFILE, COLORPAGE, TRUE ) )
	{
		down;
		while( !at_eof && (cur_char != '|12'))
		{
			if (caps (parse_str(NAME_REC, get_line)) == templatename)
			{
				goto putColorRec;
			}
			down;
		}
	}

	int tInsert = insert_mode;
	insert_mode = TRUE;
	goto_col (1);
	cr;
	up;
	insert_mode = tInsert;

PutColorRec:
	put_line (dbstr);
	switch_window (obuf);
	return ();


DoDBRec:
	tof;
	while (!at_eof || (cur_char == '|12'))
	{
		tstr  = get_line;
		down;
		if (parse_int (IDX_REC, tstr) == jx)
		{
      fg    = parse_int (REALFG_REC, tstr);
      bg    = parse_int (REALBG_REC, tstr);
      attr  = parse_int (REALATTR_REC, tstr);

			dbstr = dbstr + txstr + FG_REC + str(fg) + BG_REC + str(bg) + ATTR_REC  + str(attr);
			break;
		}
	}
	ret;

}

void RemoveColorList (int dlg, str templatename)
{
	int owin = cur_window;

	templatename = caps (templatename);
	if( LocateDbPage( DBFILE, COLORPAGE, FALSE ) )
	{
		down;
		while( !at_eof && (cur_char != '|12'))
		{
			if (caps(parse_str(NAME_REC, get_line)) == templatename)
			{
				del_line;
				break;
			}
			down;
		}
	}
	switch_window (owin);
}

void LoadCustomColors (struct ColorInfo cinfo)
{
	int bDefault = True;
	int jx, jy;
	str tstr[2048];

	int owin = cur_window;

	if( LocateDbPage( DBFILE, CUSTOMPAGE, FALSE ) )
	{
		down;
		if ( !at_eof && (cur_char != '|12'))
		{
			tstr = get_line;
			for ( jx = 0; jx < NUMCUSTOMCOLORS; jx++ )
			{
				jy = Parse_Int ("" + str (jx) + "=", tstr);
				if (!jy)
				{
					jy = 0xffffff;
				}
				cinfo.RGBValues[NUMBASICCOLORS + jx] = jy;
			}
			bDefault = False;
		}
	}
	if (bDefault)
	{
		for ( jx = 0; jx < NUMCUSTOMCOLORS; jx++ )
		{
			cinfo.RGBValues[NUMBASICCOLORS + jx] = 0xffffff;
		}
	}
	switch_window (owin);
}

void SaveCustomColors (struct ColorInfo cinfo)
{
	int jx;
	str tstr[2048];

	int owin = cur_window;

	if( LocateDbPage( DBFILE, CUSTOMPAGE, TRUE ) )
	{
		down;
		tstr = "";
		for ( jx = 0; jx < NUMCUSTOMCOLORS; jx++ )
		{
			tstr = tstr + "" + str (jx) + "=" + str (cinfo.RGBValues[NUMBASICCOLORS + jx]);
		}
		goto_col (1);
		if (cur_char == '|12'  )
		{
			int tInsert = insert_mode;
			insert_mode = TRUE;
			cr;
			up;
			insert_mode = tInsert;
		}
		put_line(tstr);
	}
	switch_window (owin);
}


void ShowCurrentAttr (int dlg)
{
	str tstr;
	int rgb, attr;
	int bFG;
	int flags;

	int lbuf  = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0, 0);
	int index = SendDlgItemMessage (dlg, _CO_COLORLIST, LB_GETCURSEL, 0, 0);

	int obuf = cur_window;
	switch_window (lbuf);
	goto_line (index + 1);
	tstr  = get_line;
	index = parse_int (IDX_REC, tstr);

	if ( index >= 0 )
	{
    SendMessage (dlg, WM_CO_SETFG, 0, parse_int (REALFG_REC, tstr));
    SendMessage (dlg, WM_CO_SETBG, 0, parse_int (REALBG_REC, tstr));

		int bold    = 0;
		int italic  = 0;
		int normal  = 1;

    attr  = parse_int  (REALATTR_REC, tstr);
    flags = parse_int  (FLAGS_REC, tstr);
		if ( (flags & COL_FONTS) == 0 )
		{
			EnableWindow (GetDlgItem (dlg, _CO_BOLD), FALSE);
			EnableWindow (GetDlgItem (dlg, _CO_ITALIC), FALSE);
		} else {
			if ( attr & MEWBOLD )
			{
				bold    = 1;
			}
			if ( attr & MEWITALIC )
			{
				italic  = 1;
			}
			EnableWindow (GetDlgItem (dlg, _CO_BOLD), TRUE);
			EnableWindow (GetDlgItem (dlg, _CO_ITALIC), TRUE);
		}
		SendDlgItemMessage (dlg, _CO_BOLD,   BM_SETCHECK, bold, 0);
		SendDlgItemMessage (dlg, _CO_ITALIC, BM_SETCHECK, italic, 0);

		normal = 0;
		if ( (flags & COL_OFF) == 0 )
		{
			EnableWindow (GetDlgItem (dlg, _CO_NODISPLAY), FALSE);
		} else {
			EnableWindow (GetDlgItem (dlg, _CO_NODISPLAY), TRUE);
			if ( attr & MEWBLANK )
				normal = 1;
		}
		SendDlgItemMessage (dlg, _CO_NODISPLAY, BM_SETCHECK, normal, 0);

		normal = 0;
		bold   = 0;
		if ((flags & COL_USE) == 0 )
		{
			EnableWindow (GetDlgItem (dlg, _CO_USECOLOR), FALSE);
			EnableWindow (GetDlgItem (dlg, _CO_USEFONT), FALSE);
		}
		else
		{
			EnableWindow (GetDlgItem (dlg, _CO_USECOLOR), TRUE);
			EnableWindow (GetDlgItem (dlg, _CO_USEFONT),  TRUE);
			if ( attr & MEWUSECOLOR )
				normal = 1;
			if ( attr & MEWUSEFONT )
				bold   = 1;
		}
		SendDlgItemMessage (dlg, _CO_USECOLOR, BM_SETCHECK, normal, 0);
		SendDlgItemMessage (dlg, _CO_USEFONT,  BM_SETCHECK, bold, 0);
	}
	switch_window (obuf);
}

void SetCurrentAttr (int dlg, struct ColorInfo cinfo)
{
  str tstr[2048], cstr, exstr;
  int rattr, attr, flags, fg, bg;
  int font;

	int lbuf  = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0, 0);
	int index = SendDlgItemMessage (dlg, _CO_COLORLIST, LB_GETCURSEL, 0, 0) + 1;


	int obuf = cur_window;
	switch_window (lbuf);
	goto_line (index);
	cstr = get_line;

	index = parse_int (IDX_REC, cstr);

	if ( index >= 0 )
	{

		tstr  = IDX_REC + str (parse_int (IDX_REC, cstr))
              + FLAGS_REC + str (parse_int (FLAGS_REC, cstr));

		if ( ColorFGIndex >= 0 )
		{
      tstr += REALFG_REC + str (cinfo.RGBValues[ColorFGIndex]);
		}
		if ( ColorBGIndex >= 0 )
		{
      tstr += REALBG_REC + str (cinfo.RGBValues[ColorBGIndex]);
		}

    rattr = 0;
		if ( isDlgButtonChecked (dlg, _CO_BOLD) )
		{
      rattr |= MEWBOLD;
		}
		if ( isDlgButtonChecked (dlg, _CO_ITALIC) )
		{
      rattr |= MEWITALIC;
		}
		if ( isDlgButtonChecked (dlg, _CO_NODISPLAY) )
		{
      rattr |= MEWBLANK;
		}
		if ( isDlgButtonChecked (dlg, _CO_USECOLOR) )
		{
      rattr |= MEWUSECOLOR;
		}
		if ( isDlgButtonChecked (dlg, _CO_USEFONT) )
		{
      rattr |= MEWUSEFONT;
		}
    tstr += REALATTR_REC + str (rattr);

    fg    = parse_int (REALFG_REC, tstr);
    bg    = parse_int (REALBG_REC, tstr);
    flags = parse_int (FLAGS_REC, tstr);

    attr = rattr;
    if ( ((rattr & MewUseFont)  == 0 ) && ((flags & COL_USE) != 0))
    {
      attr = parse_int (REALATTR_REC, ColorNormal);
    }
    if ( ((rattr & MewUseColor) == 0 ) && ((flags & COL_USE)   != 0))
    {
      fg  = parse_int (REALFG_REC, ColorNormal);
      bg  = parse_int (REALBG_REC, ColorNormal);
    }

    str exstr;
    int font = GetAttrLineFont (attr, exstr);

    tstr += "C=" + exstr +
            ATTR_REC  + str (attr) +
            TEXT_REC  + parse_str(TEXT_REC, cstr) +
            FONT_REC  + str(font) +
            FG_REC  + str(fg) +
            BG_REC  + str(bg);

		put_line (tstr);
    if ( parse_int (IDX_REC, tstr) == Text_Attr )
    {
      ColorNormal = tstr;
    }
		ColorsChanged = TRUE;
	}
	switch_window (obuf);
	str nstr;
	GetWindowText (GetDlgItem (dlg, _CO_TNAME), nstr, MAXTEMPLATELEN);

  if ((nstr != "") && (nstr != "NONE"))
	{
		EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), TRUE);
	}

	RedrawWindow (GetDlgItem (dlg, _CO_COLORLIST), 0, 0, RDW_INVALIDATE);

}

int FindColorPos (int ctrl, int point)
{
	struct TRect r;

	int ncolors;
	if ( GetDlgCtrlId(ctrl) == _CO_BASIC )
	{
		ncolors = NumBasicColors;
	}
	else
	{
		ncolors = NumCustomColors;
	}

	GetClientRect (ctrl, &r);

	int xx = (point & $ffff);
	int yy = (point >>16);

	int xSize = (r.right - r.left) / NumColorsRow;
	int ySize = (r.bottom - r.top) / (ncolors / NumColorsRow);

	int xSpace = GetSystemMetrics (SM_CXFRAME);
	int ySpace = GetSystemMetrics (SM_CYFRAME);

	int xExtra = (((r.right - r.left) % NumColorsRow) + xSpace) / 2;
	int yExtra = (((r.bottom - r.top) % (ncolors / NumColorsRow)) + ySpace) / 2;

	int x = (xx - xExtra) / xSize;
	int y = (yy - yExtra) / ySize;
	if ( ((xx-xExtra) < 0) || ((yy-yExtra) < 0) )
		return (-1);

	if (( xx < ((((x + 1) * xSize) - xSpace) + xExtra)) && (yy < ((((y+1) * ySize) - ySpace) + yExtra)))
	{
		if ( GetDlgCtrlID (ctrl) == _CO_BASIC )
		{
			return (x + (y * NumColorsRow));
		}
		else
		{
			return (x + (y * NumColorsRow) + NumBasicColors);
		}
	}
	else
	{
		return (-1);
	}
}
void PaintColorPos (int ctrl, int dc, int index, struct ColorInfo cinfo)
{
	struct  TRect r;

	if ( index >= 0 )
	{
		int ncolors;
		if ( GetDlgCtrlId(ctrl) == _CO_BASIC )
		{
			ncolors = NumBasicColors;
		}
		else
		{
			ncolors = NumCustomColors;
		}

		int madedc = False;
		if ( dc == 0 )
		{
			dc      = GetDC (ctrl);
			madedc  = True;
		}
		GetClientRect (ctrl, &r);

    int xSize = (r.right - r.left) / NumColorsRow;
    int ySize = (r.bottom - r.top) / (ncolors / NumColorsRow);


		SelectObject (dc, GetStockObject (BLACK_PEN));

		int brush     = CreateSolidBrush (cinfo.RGBValues [index]);
		int oldBrush  = SelectObject (dc, brush);

		int jindex = index;
		if ( index >= NumBasicColors )
		{
			jindex = index - NumBasicColors;
		}
		int xSpace = GetSystemMetrics (SM_CXFRAME);
		int ySpace = GetSystemMetrics (SM_CYFRAME);

    int xExtra = (((r.right - r.left) % NumColorsRow) + xSpace) / 2;
    int yExtra = (((r.bottom - r.top) % (ncolors / NumColorsRow)) + ySpace) / 2;

		int x = ((jindex % NumColorsRow) * xSize) + xExtra;
		int y = ((jindex / NumColorsRow) * ySize) + yExtra;


		Rectangle (dc, x, y, x + xSize - xSpace, y + ySize - ySpace);

		str stxt[3] = "";

		if ( (index == ColorFGIndex) && (index == ColorBGIndex))
		{
			stxt = "BF";
		} else if (index == ColorFGIndex)
		{
			stxt = "FG";
		} else if (index == ColorBGIndex)
		{
			stxt = "BG";
		}

		if ( stxt != "")
		{
			SetBkMode (dc, TRANSPARENT);

			SetTextColor (dc, cinfo.RGBValues[index] ^ $c0c0c0);
			// Center the Indicator text
      r.left    = x;
      r.top     = y;
      r.right   = x + xSize - xSpace;
      r.bottom  = y + ySize - ySpace;

      int temp = 0;
			jindex = GetTextExtent (dc, stxt, 2);
      x = r.left + (((xSize - xSpace) - (jindex & $ffff))  / 2);
      y = r.top  + (((ySize - ySpace) - (jindex >> 16))  / 2);

      ExtTextOut (dc, x, y, ETO_CLIPPED, &r, stxt, 2, 0);
		}

		SelectObject (dc, oldBrush);
		DeleteObject (brush);
		if ( madedc )
		{
			ReleaseDC (ctrl, dc);
		}
	}
}

int ColorCtrlProc ( int &retval, int ctrl, int message, int wparam, int lparam, str parms ) No_Break

{
	int     result = 0;
	struct  TPaintStruct ps;
	struct  ColorInfo    cinfo;

	switch ( message )
	{
		case WM_LBUTTONDOWN :
		case WM_RBUTTONDOWN :
		{
			int index = FindColorPos (ctrl, lParam);
			if ( index >= 0 )
			{
        str tstr[1024] = Global_Str (parse_str ("/GL=", parms));
				str_to_struct (cinfo, tstr);

				if ( message == WM_LBUTTONDOWN )
				{
					SendMessage (GetParent(ctrl), WM_CO_SETFG, 0, cinfo.RGBValues[index]);
				}
				else
				{
					SendMessage (GetParent(ctrl), WM_CO_SETBG, 0, cinfo.RGBValues[index]);
				}
				SendMessage (GetParent (ctrl), WM_COMMAND, GetDlgCtrlID (ctrl), (CON_NOTIFY << 16) | ctrl);
			}
			result = 1;
			break;
		}
		case WM_ERASEBKGND :
		{
			retval = 1;
			result = 1;
			break;
		}
		case WM_PAINT :
		{
      str tstr[1024] = Global_Str (parse_str ("/GL=", parms));
			str_to_struct (cinfo, tstr);

			int jx;
			int ji;
			if ( GetDlgCtrlID (ctrl) == _CO_BASIC )
			{
				ji = 0;
				jx = NumBasicColors;
			}
			else
			{
				ji = NumBasicColors;
				jx = MaxColors;
			}

			int dc = BeginPaint (ctrl, &ps);
			for (ji = ji; ji < jx; ji++ )
			{
				PaintColorPos (ctrl, dc, ji, cinfo);
			}
			EndPaint (ctrl, &ps);

			result = 1;
			break;
		}
	}
	return (result);
}

void SaveTemplate (int dlg = parse_int ("/DLGHANDLE=", mparm_str));
{
	str nstr;
	GetWindowText (GetDlgItem(dlg, _CO_TNAME), nstr, MAXTEMPLATELEN);
  if (( nstr != "") && (nstr != "NONE") )
	{
		int sel = SendDlgItemMessageStr (dlg, _CO_TNAME, CB_FINDSTRINGEXACT, -1, nstr);
		if ( sel == CB_ERR)
		{
			sel = SendDlgItemMessageStr( dlg, _CO_TNAME, CB_ADDSTRING, 0, nstr);
		}
		SendDlgItemMessage (dlg, _CO_TNAME, CB_SETCURSEL, sel, 0);

		SaveColorList (dlg, nstr);
		ColorTemplate = nstr;
		ColorsChanged = FALSE;
	}
  EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), FALSE);
}

void DeleteTemplate (int dlg = parse_int ("/DLGHANDLE=", mparm_str))
{
	str nstr;
	GetWindowText (GetDlgItem(dlg, _CO_TNAME), nstr, MAXTEMPLATELEN);
  if ( nstr != "NONE" )
  {
    int sel = SendDlgItemMessageStr (dlg, _CO_TNAME, CB_FINDSTRINGEXACT, -1, nstr);
    if ( sel != CB_ERR)
    {
      SendDlgItemMessage ( dlg, _CO_TNAME, CB_DELETESTRING, sel, 0);
      SendDlgItemMessage ( dlg, _CO_TNAME, CB_SETCURSEL, -1, 0);
      SetWindowText (GetDlgItem (dlg, _CO_TNAME), "");
    }
    RemoveColorList (dlg, nstr);
    ColorTemplate = "";
  }

  EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), FALSE);
}


int CheckSaved (int dlg)
{
	int flag = 1;
	if ( ColorsChanged )
	{

		int mdlg;
		DlgCreate (mdlg);
		DlgAddCtrl( mdlg, DLG_Icon, "IC_EXCLAMATION", 1, 1, 0, 0, 1101, 0, "");
		DlgAddCtrl (mdlg, DLG_Static,
			"You have not saved changes to a template"
			+ "\r\nchanges are valid for this session only.",
			8, 1, 45, 2, 1100,  0, "");
		DlgAddCtrl (mdlg, DLG_PushButton,
			"OK",
			2, 4, DLG_StanBtnWidth, 0, 1, DLGF_DefButton, "/R=1");
		DlgAddCtrl (mdlg, DLG_PushButton,
			"Cancel",
			DLG_StanBtnWidth + 4, DLG_PosOffset, DLG_StanBtnWidth, 0, 2, 0, "/R=0");

		flag = DlgExecute (mdlg, 1, "Warning", CO_HELPLINK, "", 0);
		DlgKill (mdlg);
	}
	return (flag);
}

int ColorPromptProc ( int &retval, int dlg, int message, int wparam, int lparam, str parms ) No_Break
{
	int result = 0;
	struct ColorInfo cinfo;
	//if ( global_int ("@TEST") )
	//{
	//  msglog (5, "Color", dlg, message, wparam, lparam);
	//}

	switch ( message )
	{
		case WM_CO_ADDCUSTOM :
		{
			int jx;
      str tstr [1024] = Global_Str (parse_str ("/GL=", parms));
			str_to_struct (cinfo, tstr);

			for ( jx = NUMBASICCOLORS; jx < MAXCOLORS; jx++ )
			{
				if ( cinfo.RGBValues[jx] == 0xffffff )
				{
					cinfo.RGBValues[jx] = lParam;
					PaintColorPos (GetDlgItem (dlg, _CO_CUSTOM), 0, jx, cinfo);
					break;
				}
			}
			if ( jx == MAXCOLORS )
			{
				if ( FBIndex == 1 )
					jx = ColorFGIndex;
				else if ( FBIndex == 2 )
					jx = ColorBGIndex;
				cinfo.RGBValues[jx] = lParam;
				PaintColorPos (GetDlgItem (dlg, _CO_CUSTOM), 0, jx, cinfo);
			}
			struct_to_str (tstr, cinfo);
      Set_Global_Str (parse_str ("/GL=", parms), tstr);
      result = 1;
			break;
		}

		case WM_CO_SETFG :
		case WM_CO_SETBG :
		{
      str tstr [1024] = Global_Str (parse_str ("/GL=", parms));
			str_to_struct (cinfo, tstr);

			int newindex;
			int newctrl;
			int oldctrl;
			int oldindex;

			for ( newindex = 0; newindex < MaxColors; newindex++ )
			{
				if (lparam == cinfo.RGBValues[newindex]  )
					break;
			}
			if ( newindex == MaxColors ) newindex = -1;

			if ( message == WM_CO_SETFG )
			{
				oldindex = ColorFGIndex;
				ColorFGIndex = newindex;
				if ( ColorFGIndex > 47 ) FBIndex = 1;
			}
			else
			{
				oldindex = ColorBGIndex;
				ColorBGIndex = newindex;
				if ( ColorBGIndex > 47 ) FBIndex = 2;
			}

			if ( oldindex < NumBasicColors )
			{
				oldctrl = GetDlgItem (dlg, _CO_BASIC);
			}
			else
			{
				oldctrl = GetDlgItem (dlg, _CO_CUSTOM);
			}

			if ( newindex < NumBasicColors )
			{
				newctrl = GetDlgItem (dlg, _CO_BASIC);
			}
			else
			{
				newctrl = GetDlgItem (dlg, _CO_CUSTOM);
			}
			PaintColorPos (oldctrl, 0, oldindex, cinfo);
			PaintColorPos (newctrl, 0, newindex, cinfo);

      result = 1;
			break;
		}

		case WM_COMMAND :
		{
      str tstr [1024] = Global_Str (parse_str ("/GL=", parms));
			str_to_struct (cinfo, tstr);
			switch ( wparam )
			{
        case DLG_WCMD_INIT :
        {
          SendDlgItemMessage ( dlg, _CO_TNAME, CB_LIMITTEXT, MAXTEMPLATELEN, 0);

          if ( ColorBuf )
          {
            EnableWindow (GetDlgItem (dlg, _CO_SYNTAX), FALSE);
            EnableWindow (GetDlgItem (dlg, _CO_SYNTAXLINE), FALSE);
          }
          else
          {
            SendDlgItemMessage (dlg, _CO_SYNTAX,      BM_SETCHECK, keyword_highlighting, 0);
            SendDlgItemMessage (dlg, _CO_SYNTAXLINE,  BM_SETCHECK, !keyword_cline_override, 0);
          }
          EnableWindow (GetDlgItem (dlg, COLOR_MIX), TRUE);
          EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), FALSE);

          if (( ColorTemplate == "") || (ColorTemplate == "NONE"))
          {
            EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), FALSE);
          }

          SetupColorList  (dlg, ColorTemplate);
          ShowCurrentAttr (dlg);
          break;
        }

				case _CO_CUSTOM :
				case _CO_BASIC :
				{
					switch ( lparam >> 16 )
					{
						case CON_NOTIFY :
							SetCurrentAttr (dlg, cinfo);
					}
					break;
				}
				case _CO_COLORLIST :
					switch (lParam >> 16)
					{
						case LBN_SELCHANGE :
						{
							ShowCurrentAttr (dlg);
							break;
						}
					}
					break;

				case _CO_BOLD :
				case _CO_ITALIC :
				case _CO_NODISPLAY :
				case _CO_USEFONT :
				case _CO_USECOLOR :
				{
					SetCurrentAttr (dlg, cinfo);
					break;
				}
				case _CO_TNAME :
				{
					str nstr;
					int sel;
					switch ( lparam >> 16 )
					{
						case CBN_SELCHANGE :
						{
							sel = SendDlgItemMessage (dlg, _CO_TNAME, CB_GETCURSEL, 0, 0);
							if ( sel != CB_ERR )
							{
								SendDlgItemMessageStr  (dlg, _CO_TNAME, CB_GETLBTEXT, sel, nstr);
							}
              SetupColorList (dlg, nstr);
							ColorTemplate = nstr;
              if ( ColorTemplate != "NONE" )
              {
                EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), TRUE);
              }
              else
              {
                EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), FALSE);
              }
							EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), FALSE);
              break;
						}
						case CBN_EDITCHANGE :
						{
							GetWindowText (GetDlgItem (dlg, _CO_TNAME), nstr, MAXTEMPLATELEN);
              if (( nstr != "") && (nstr != "NONE") )
							{
								sel = SendDlgItemMessageStr  (dlg, _CO_TNAME, CB_FINDSTRINGEXACT, -1, nstr);
								if ( sel == CB_ERR )
								{
									EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), FALSE);
								} else {
									EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), TRUE);
								}
								EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), TRUE);
							}
							else
							{
								EnableWindow (GetDlgItem (dlg, _CO_DELTNAME), FALSE);
								EnableWindow (GetDlgItem (dlg, _CO_SAVETNAME), FALSE);

							}
						}
					}
					break;
				}
				case ID_OK :
				case ID_CANCEL :
				{
					if (wparam == ID_OK)
					{
            int trefresh = refresh;
            refresh = False;
						if (CheckSaved (dlg) != 0)
						{
							SaveCustomColors (cinfo);
							if ( !ColorBuf )
							{
								keyword_highlighting    =  SendDlgItemMessage (dlg, _CO_SYNTAX, BM_GETCHECK, 0, 0);
								keyword_cline_override  = !SendDlgItemMessage (dlg, _CO_SYNTAXLINE, BM_GETCHECK, 0, 0);
								SetListAttrs (dlg, ColorBuf);
							}
							New_Screen;
						}
            else
            {
              result = 1;
            }
            refresh = True;
					}
					else
					{
							SetFocus (GetDlgItem (dlg, ID_CANCEL));
					}
					break;
				}
			}
			break;
		}
		break;
	}
  if ( !result )
  {
    result = DlgMessageProc(retval, dlg, message, wparam, lparam, parms );
  }
	return( result );
}

void InitColorValues (int dlg, struct ColorInfo cinfo)
{
	// Setup color tables
	cinfo.RGBValues[0] = 0x8080ff;
	cinfo.RGBValues[1] = 0x80ffff;
	cinfo.RGBValues[2] = 0x80ff80;
	cinfo.RGBValues[3] = 0x80ff00;
	cinfo.RGBValues[4] = 0xffff80;
	cinfo.RGBValues[5] = 0xff8000;
	cinfo.RGBValues[6] = 0xc080ff;
	cinfo.RGBValues[7] = 0xff80ff;

	cinfo.RGBValues[8]  = 0x0000ff;
	cinfo.RGBValues[9]  = 0x00ffff;
	cinfo.RGBValues[10] = 0x00ff80;
	cinfo.RGBValues[11] = 0x40ff00;
	cinfo.RGBValues[12] = 0xffff00;
	cinfo.RGBValues[13] = 0xc08000;
	cinfo.RGBValues[14] = 0xc08080;
	cinfo.RGBValues[15] = 0xff00ff;

	cinfo.RGBValues[16] = 0x404080;
	cinfo.RGBValues[17] = 0x4080ff;
	cinfo.RGBValues[18] = 0x00ff00;
	cinfo.RGBValues[19] = 0x808000;
	cinfo.RGBValues[20] = 0x804000;
	cinfo.RGBValues[21] = 0xff8080;
	cinfo.RGBValues[22] = 0x400080;
	cinfo.RGBValues[23] = 0x8000ff;

	cinfo.RGBValues[24] = 0x000080;
	cinfo.RGBValues[25] = 0x0080ff;
	cinfo.RGBValues[26] = 0x008000;
	cinfo.RGBValues[27] = 0x408000;
	cinfo.RGBValues[28] = 0xff0000;
	cinfo.RGBValues[29] = 0xa00000;
	cinfo.RGBValues[30] = 0x800080;
	cinfo.RGBValues[31] = 0xff0080;

	cinfo.RGBValues[32] = 0x000040;
	cinfo.RGBValues[33] = 0x00407f;
	cinfo.RGBValues[34] = 0x004000;
	cinfo.RGBValues[35] = 0x404000;
	cinfo.RGBValues[36] = 0x800000;
	cinfo.RGBValues[37] = 0x400000;
	cinfo.RGBValues[38] = 0x400060;
	cinfo.RGBValues[39] = 0x800040;

	cinfo.RGBValues[40] = 0x000000;
	cinfo.RGBValues[41] = 0x008080;
	cinfo.RGBValues[42] = 0x408080;
	cinfo.RGBValues[43] = 0x808080;
	cinfo.RGBValues[44] = 0x808040;
	cinfo.RGBValues[45] = 0xc0c0c0;
	cinfo.RGBValues[46] = 0x400040;
	cinfo.RGBValues[47] = 0xffffff;

	LoadCustomColors (cinfo);

	ColorFGIndex = -1;
	ColorBGIndex = -1;

}

int CreateColorDialog (str tname, int buf)
{
  int t;
  int nfont;
  int dlg;
	struct  TTEXTMETRIC tm;

  DlgCreate (dlg);

	// Get Text sizes
  Get_Window_Font_handle (0, nfont, t, t, t);
  int dc    = GetDC (frame_handle);
  int sobj  = SelectObject (dc, nfont);
	GetTextMetrics (dc, &tm);
  SelectObject (dc, sobj);
  ReleaseDC (frame_handle, dc);

  int owin = cur_window;
  create_window;

	// Create the list box
  DlgAddCtrl (dlg, DLG_ListBox, "C=/T=5/W=100/H=" + str (tm.tmheight),
      1, 5, 40, DLG_UNITS | 175,
      _CO_COLORLIST,
      DLGF_LBPTR | DLGF_LB_SCROLLBAR | DLGF_LBINCSEARCH | DLGF_LB_NODBLCLICK,
      "/WIN=" + str(cur_window));

  DlgAddCtrl (dlg, DLG_Static,    "Basic Colors:",
      42,  5, 35,  1, 35, 0, "");
  DlgAddCtrl (dlg, DLG_WhiteFrame, "",
      DLG_PosOffset, Dlg_PosOffset + 1, 35,  6,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_OwnerButton, "",
      DLG_Units | DLG_PosOffset, DLG_Units | DLG_PosOffset, DLG_Units + 140, DLG_Units + 72,
      _CO_BASIC, 0, "");
  DlgAddCtrl (dlg, DLG_Static,    "Custom Colors:",
      Dlg_PosOffset, DLg_Units | Dlg_PosOffset + 75, 35,  1,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_WhiteFrame, "",
      Dlg_PosOffset, DLG_PosOffset + 1, 35,  2,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_OwnerButton, "",
      DLG_Units | DLG_PosOffset, DLG_Units | DLG_PosOffset, DLG_Units + 140, DLG_Units + 24,
      _CO_CUSTOM, 0, "");
  DlgAddCtrl (dlg, DLG_GroupBox,  "Control",
      Dlg_PosOffset, DLG_Units + DLG_PosOffset + 30, 15,  4,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "&Off",
      Dlg_PosOffset + 1, Dlg_PosOffset + 1, 13,  1,
      _CO_NODISPLAY, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "Use &Color",
      Dlg_PosOffset, Dlg_PosOffset + 1, 13,  1,
      _CO_USECOLOR, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "Use &Font",
      Dlg_PosOffset, Dlg_PosOffset + 1, 13,  1,
      _CO_USEFONT, 0, "");
  DlgAddCtrl (dlg, DLG_GroupBox,  "Font Style",
      Dlg_PosOffset + 15 + 1, DLG_NegOffset + 3, 15,  4,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "&Bold",
      Dlg_PosOffset + 1, Dlg_PosOffset + 1, 10,  1,
      _CO_BOLD, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "&Italic",
      Dlg_PosOffset    , Dlg_PosOffset + 1, 10,  1,
      _CO_ITALIC, 0, "");
  DlgAddCtrl (dlg, DLG_GroupBox,  "Syntax Highlighting",
      42,  1, 35,  DLG_Units | 40,
      -1, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "O&n",
      Dlg_PosOffset + 1,  DLG_PosOffset + 1, 33,  1,
      _CO_SYNTAX, 0, "");
  DlgAddCtrl (dlg, DLG_CheckBox,  "Override Current &Line",
      DLG_PosOffset,  DLG_PosOffset + 1, 33,  1,
      _CO_SYNTAXLINE, 0, "");
  DlgAddCtrl (dlg, DLG_PushButton, "OK",
       1, 20, DLG_StanBtnWidth, 0,
       ID_OK, DLGF_DEFBUTTON, "/R=1");
  DlgAddCtrl (dlg, DLG_PushButton, "Cancel",
       DLG_PosOffset + DLG_StanBtnWidth + 1, Dlg_PosOffset, DLG_StanBtnWidth, 0,
       ID_CANCEL, 0, "/R=0");
  DlgAddCtrl (dlg, DLG_PushButton, "&Help",
       65, DLG_PosOffset, DLG_StanBtnWidth, 0,
       _CO_HELP, 0, "/R=2");
  DlgAddCtrl (dlg, DLG_PushButton, "&Define Custom Colors...",
       DLG_NegOffset + 35, Dlg_PosOffset, 25, 0,
       _CO_DEFINENEW, 0, "/M=AddCustomColor /GL=@GColorInfo");
  DlgAddCtrl (dlg, DLG_GroupBox, "Color Templates",
       1, 1, 40, DLG_Units | 40,
       -1, 0, "");

  DlgAddCtrl (dlg, DLG_Text, "",
       DLG_PosOffset + 1, Dlg_PosOffset + 1, 38, 1,
       _CO_TNAME, 0, "/HISTORY=TEMPLATE_HISTORY/ML=80");
  DlgAddCtrl (dlg, DLG_PushButton, "&Save",
       Dlg_PosOffset + 6, DLG_Units + Dlg_PosOffset + 15, DLG_StanBtnWidth, 1,
       _CO_SAVETNAME, 0, "/M=SaveTemplate");
  DlgAddCtrl (dlg, DLG_PushButton, "&Remove",
      Dlg_PosOffset + DLG_StanBtnWidth + 4, Dlg_PosOffset, DLG_StanBtnWidth, 1,
      _CO_DELTNAME, 0, "/M=DeleteTemplate");

  InitColorList (tname, buf);

  switch_window (owin);

  return (dlg);

}

int SelectColors (int parent, str &templatename, int buf)
{
	int result = 0;
	struct ColorInfo cinfo;
	struct TMsg msg;

	int tRefresh = refresh;
	refresh = FALSE;
	//Set_global_int ("@TEST", 0);

	int twin_id = window_id;

  int dlgdata = CreateColorDialog (templatename, buf);
  int dlg = DlgBuild (dlgdata, "Color Setup", CO_HELPLINK, "", 0);
	if ( dlg )
	{
		ColorTemplate  = templatename;
		ColorBuf       = buf;
		InitColorValues (dlg, cinfo);

		str tstr [1024];
		struct_to_str (tstr, cinfo);
		GColorInfo = tstr;

    Subclass_With_Macro (GetDlgItem (dlg, _CO_BASIC),  "ColorCtrlProc", "/GL=@GColorInfo");
    Subclass_With_Macro (GetDlgItem (dlg, _CO_CUSTOM), "ColorCtrlProc", "/GL=@GColorInfo");

    result = DlgExecute (dlgdata, _CO_COLORLIST, "Color Setup", CO_HELPLINK,
      "/HOOK=ColorPromptProc //GL=@GColorInfo", 0);

		tstr = GColorInfo;
		str_to_struct (cinfo, tstr);
		templatename = ColorTemplate;

		int jx = SendDlgItemMessage (dlg, _CO_COLORLIST, WM_ML2_GETLISTBUF, 0, 0);
    KillColorList();
    DlgKill (dlgdata);
		switch_window (jx);
    delete_window;
	}
	HelpLink_String = "";

  ColorNormal   = "";
  ColorBuf      = 0;
  ColorFGindex  = 0;
  ColorBGIndex  = 0;
  ColorTemplate = "";

	refresh = tRefresh;
	switch_win_id (twin_id);
	return (result);
}

void SetupDefColors ( int parent = parse_int("/DLGHANDLE=", mparm_str) )
{
	if (!parent )
	{
		parent = frame_handle;
	}

	str tname;

	if (ColorsChanged )
	{
		tname = "";
	} else {
		tname = DefaultColor;
	}

	if (SelectColors (parent, tname, 0))
	{
		Set_Global_Int('SETUP_CHANGED',Global_Int('SETUP_CHANGED') | $01);
		if ( tname != DefaultColor)
		{
			DefaultColor = tname;
		}
	}
	return_int = 0;
}
void SetupCustColors ( int parent = parse_int("/DLGHANDLE=", mparm_str) )
{
	if (!parent )
	{
		parent = frame_handle;
	}
	str tname = return_str;
	if (SelectColors (parent, tname, -1))
	{
    return_int = 1;
		return_str = tname;
	}
  else
  {
    return_int = 0;
  }
}
