// $Header: /MEWIN/SRC/PRINT.S 33    3/08/96 12:31p Johnp $
Macro_File Print;

#include windows.sh
#include dialog.sh
#include commdlg.sh
#include mewhelp.sh
#include mewlib.sh
#include mew_btn.sh
#include metools.sh
#include print.sh
// #include msglog.sh

// Default Strings
#define Default_Header  "<LM><FILE>.<EXT><RM><CDATE> <CTIME>"
#define Default_Footer  "<CM>Page: <PAGE>"

// Setup Dialog Control IDs
#define _P_HELP           1038
#define _P_DEFBTN         1058
#define _P_SELPRINTER     1136
#define _P_PRNPRINTER     1088

#define _PS_LMARGIN       2001
#define _PS_RMARGIN       2002
#define _PS_TMARGIN       2003
#define _PS_BMARGIN       2004
#define _PS_HEADER        2010
#define _PS_FOOTER        2011
#define _PS_HEADERON      2012
#define _PS_FOOTERON      2013
#define _PS_HEADEROFFSET  2014
#define _PS_FOOTEROFFSET  2015
#define _PS_LINENUMBERING 2016

#define _PS_FONTS         2020
#define _PS_PAGESETUP     2021

#define _PO_FF            2050
#define _PO_WRAP          2051
#define _PO_SYNTAX        2052
#define _PO_COLOR         2053

#define _PN_OPTIONS       3010
#define _PN_PRNCOLLAPSE   3011
#define _PN_HEX           3012


// db files and pages
#define DBFILE      "MECONFIG"
#define PRINTPAGE   "PRINT.CFG"

#define PRINT_HELPLINK        "Print"
#define PRINTSETUP_HELPLINK   "Print Setup"
#define PAGESETUP_HELPLINK    "Page Setup"
#define PRINTOPT_HELPLINK     "Print Options"
#define PRINTFONT_HELPLINK    "Printer Fonts"

struct TPrintWork
{
  WORD    dc;
  INT     window;

  INT     line;
  INT     page;

  ASCIIZ  Lheader  [128];
  ASCIIZ  Cheader  [128];
  ASCIIZ  Rheader  [128];
  ASCIIZ  Lfooter  [128];
  ASCIIZ  Cfooter  [128];
  ASCIIZ  Rfooter  [128];
}

// Temporary place holder for template names for Commdlg Hook
struct TPrintRec
{
	ASCIIZ  PrintTemplate [32];
	ASCIIZ  SetupTemplate [32];
}
global
{
  int g_PrintWindow   "!PRINTWINDOW";
}


void TransHF (struct TPrintDlg pds, struct TPrintOptions Popt, struct TPrintWork PWork)
{
  int jx;
  int center_start, right_start;
  str left_str, center_str, right_str, tstr;
  str tline[1024];

  int tRefresh = Refresh;
  Refresh = False;

  int tWin = cur_window;
  Switch_Window (PWork.Window);
  if ( ((POpt.Flags & POPTF_HEADERON) != 0) && ( POpt.Header != "" ) )
  {
    tline = TranslateCmdLine (Popt.Header, file_name);
    Call XlatePrint;

    PWork.LHeader = left_str;
    PWork.CHeader = center_str;
    PWork.RHeader = right_str;
  }

  if ( ((POpt.Flags & POPTF_FOOTERON) != 0) && (POpt.Footer != "") )
  {
    tline = TranslateCmdLine (pOpt.Footer, file_name);
    Call XlatePrint;
    PWork.LFooter = left_str;
    PWork.CFooter = center_str;
    PWork.RFooter = right_str;
  }


  Switch_Window (tWin);
  Refresh = tRefresh;
  Return ();

XlatePrint:
	// Put page number
  left_str    = "";
  center_str  = "";
  right_str   = "";
  while ( jx = xpos('<PAGE>', Caps (tline), 1) )
  {
    tline = Str_Del(tline, jx, 6);
    tline = Str_Ins(str (PWork.page), tline, jx);
  }

  // These need to come after all other translations.
  center_start  = 0;
  right_start   = 0;
  while ( jx = xpos('<LM>', Caps (tline), 1) )
  {
    tline = Str_Del(tline, jx, 4);

  }
  while ( jx = xpos('<CM>', Caps (tline), 1) )
  {
    tline = Str_Del(tline, jx, 4);
    center_start  = jx;
  }
  while ( jx = xpos('<RM>', Caps (tline), 1) )
  {

    tline = Str_Del(tline, jx, 4);
    right_start   = jx;
  }


  if ( right_start && (center_start >= right_start)  )
    center_start = 0;

  if ( center_start > 0)
  {
    left_str = Copy (tline, 1, center_start - 1);
    if ( right_start > 0)
    {
      center_str = Copy (tline, center_start, right_start - center_start);
      right_str  = Copy (tline, right_start,  (Length (tline) + 1) - right_start);
    }
    else
    {
      center_str = Copy (tline, center_start, (Length (tline) + 1) - center_start);
    }
  }
  else if ( right_start > 0)
  {
    left_str    = Copy (tline, 1, right_start - 1);
    right_str   = Copy (tline, right_start, (Length (tline) + 1) - right_start);
  }
  else
  {
    left_str = Copy (tline, 1, Length (tline));
  }
  ret;
}

void SavePrintCfg ()
{

	int tinsert = insert_mode;
	insert_mode = TRUE;

	int twin = cur_window;

	struct TPrintOptions pOpt;
	str tstr [1024] = POPtionsStruct;
	str_to_struct (pOpt, tstr);

	if( LocateDbPage( DBFILE, PRINTPAGE, TRUE ) )
	{
		down;
		goto_col (1);
    while ( !at_eof && !XPos ("\f", get_line, 1))
		{
			del_line;
		}
		cr;
		up;
		Text ("FLAGS="
							+ "/USEFF="     + str ((POpt.flags & POPTF_USEFF) != 0)
							+ "/WRAP="      + str ((POpt.flags & POPTF_WRAP) != 0)
							+ "/HEADERON="  + str ((POpt.flags & POPTF_HEADERON) != 0)
							+ "/FOOTERON="  + str ((POpt.flags & POPTF_FOOTERON) != 0)
              + "/SCOLOR="    + str ((POpt.flags & POPTF_COLOR) != 0)
              + "/SYNTAX="    + str ((POpt.flags & POPTF_SYNTAX) != 0)
							+ "/NUM="       + str (POpt.LineNumbering));
		cr;
		Text ("MARGINS="
							+ "/RM=" + str (POpt.RMargin)
							+ "/LM=" + str (POpt.LMargin)
							+ "/TM=" + str (POpt.TMargin)
							+ "/BM=" + str (POpt.BMargin));
		cr;
		Text ("HEADER=" + POpt.Header);
		cr;
		Text ("FOOTER=" + POpt.Footer);
		cr;
		Text ("OFFSETS="
								+ "/HO=" + str (POpt.HeaderOffset)
								+ "/FO=" + str (POpt.FooterOffset));
		cr;
		Text ("FONT="
								+ "/NAME=" + Popt.FontName
								+ "/SIZE=" + str (Popt.FontHeight)
								+ "/POINT=" + str (POpt.FontPointSize)
                + "/SET="  + str (POpt.CharSet)
                + "/WT=" + str(Popt.FontWeight)
                + "/IT=" + str(Popt.FontItalic));
	}
	Switch_window (twin);
	insert_mode = tInsert;
}

void SetPrintCfg ()
{

	str dbline [2048];
	str tstr   [2048];
	struct TPrintOptions POpt;

	int twin = cur_window;
	if( LocateDbPage( DBFILE, PRINTPAGE, FALSE) )
	{
		down;
		goto_col (1);
    while ( !at_eof && (cur_char != "\f") )
		{
			dbline = get_line;

			tstr = parse_str ("FLAGS=", dbline);
			if ( tstr != "" )
			{
				Popt.Flags = 0;
				if ( Parse_int ("/USEFF=", tstr) )
					POpt.flags |= POPTF_USEFF;
				if ( Parse_int ("/WRAP=", tstr) )
					POpt.flags |= POPTF_WRAP;
				if ( Parse_int ("/HEADERON=", tstr) )
					POpt.flags |= POPTF_HEADERON;
				if ( Parse_int ("/FOOTERON=", tstr) )
					POpt.flags |= POPTF_FOOTERON;
        if ( Parse_int ("/SCOLOR=", tstr) )
          POpt.flags |= POPTF_COLOR;
        if ( Parse_int ("/SYNTAX=", tstr) )
          POpt.flags |= POPTF_SYNTAX;

				Popt.LineNumbering = Parse_Int ("/NUM=", tstr);
				goto loopit;
			}
			tstr = parse_str ("MARGINS=", dbline);
			if ( tstr != "" )
			{
				POpt.RMargin = Parse_Int ("/RM=" , tstr);
				POpt.LMargin = Parse_Int ("/LM=" , tstr);
				POpt.TMargin = Parse_Int ("/TM=" , tstr);
				POpt.BMargin = Parse_Int ("/BM=" , tstr);
				goto loopit;
			}
			tstr = Parse_Str ("HEADER=", dbline);
			if ( tstr != "" )
			{
				POpt.Header = tstr;
				goto loopit;
			}
			tstr = Parse_Str ("FOOTER=", dbline);
			if ( tstr != "" )
			{
				POpt.Footer = tstr;
				goto loopit;
			}
			tstr = Parse_Str ("OFFSETS=", dbline);
			if ( tstr != "" )
			{
				POpt.HeaderOffset = Parse_Int ("/HO=", tstr);
				POpt.FooterOffset = Parse_Int ("/FO=", tstr);
				goto loopit;
			}
			tstr = Parse_Str ("FONT=", dbline);
			if ( tstr != "" )
			{
				POpt.FontName       = Parse_Str ("/NAME=", tstr);
				POpt.FontHeight     = Parse_Int ("/SIZE=", tstr);
				Popt.FontPointSize  = Parse_Int ("/POINT=", tstr);
				POpt.CharSet        = Parse_Int ("/SET=", tstr);
        POpt.FontWeight     = parse_int ("/WT=", tstr);
        POpt.FontItalic     = parse_int ("/IT=", tstr);
				goto loopit;
			}
loopit:
			down;
		}
		struct_to_str (tstr, POpt);
		POptionsStruct = tstr;
	}

	Switch_window (twin);
}

int GetPrinterDC (str szInDevice)
{
	int jx;
	str szPrinter[80], szDevice[80], szDriver[20], szOutput[30];


	if ( szInDevice == "")
	{
		GetProfileString ("windows", "device", "", szPrinter, 80);
		jx = XPos (',', szPrinter, 1);
		if ( jx )
		{
			szDevice = Copy (szPrinter, 1, jx-1);
			jx++;
		}
		else
		{
			return (0);
		}
	}
	else
	{
		GetProfileString ("devices", szInDevice, "", szPrinter, 128);
		szDevice = szInDevice;
		jx = 1;
	}

	int jy = XPos (',', szPrinter, jx);
	if (jy )
	{
		str szDriver = Copy (szPrinter, jx, jy-jx);
		jy++;
    str szOutput = Copy (szPrinter, jy, svl(szPrinter) - jy + 1);

		return (CreateDC (szDriver, szDevice, szOutput, 0));
	}
	return (0);
}


// The following Dll Import is a mod of GetProfileString to allow get a Null terminater buffer
IMPORT _int16   GetProfileSection(ASCIIZ AppName, Pointer KeyName,
																	ASCIIZ Default, Pointer ReturnedString,
																	_int16 Size)  KERNEL 58;
struct section_s
{

	Char buf [8192];
}

str find_null (struct section_s st, int &start)
{
	int jx, jy;

	for ( jx = start; (st.buf[start] != "\x00") && (start < 8192); start++ );

	if ( start == 8192)
	{
		return ( "");
	}

	str t  = "";
	for ( jy = 1; jx < start; jx++)
	{
		t = str_ins(st.buf[jx], t, jy);
		jy++;
	}
	return ( t);
}

str FindPrinterName (str p_str = Parse_Str( "/P=", mparm_str ))
{
	int 	jx, jy, jz;
	str 	c_str;

	struct section_s tt;


	GetProfileSection ("devices", 0, "", &tt.buf, 8192);

	jx = 0;
	while ( 1)
	{

		c_str = find_null (tt, jx);
		if ( c_str == "")
		{
			break;
		}

		jx++;
		if (xpos (c_str, p_str, 1))
		{
			return ( c_str);
		}
	}
	return ( "");
}

struct TS
{
	ASCIIZ style [100];
}
int PrintFontProc ( int dlg, int message, int wparam, int lparam, struct TChooseFont frec ) No_Break
{

	int result = 0;
	switch ( message )
	{
		case WM_ACTIVATE :
		{
			if ( wparam )
			{
				HelpLink_String = PRINTFONT_HELPLINK;
			}
			else
			{
				HelpLink_String = "";
			}
			break;
		}

		case WM_COMMAND :
		{
			switch ( wparam )
			{
				case _P_HELP :
					MewHelp_Context();
					result = 1;
					break;
			}
		}
	}
	return (result);
}


int SelectPFont (int dlg, int dc)
{
	struct TLogFont     PrintFont;
	struct TChooseFont  ChooseRec;
	struct TS           t;

	struct TPrintOptions pOpt;
	str tstr [1024] = POPtionsStruct;
	str_to_struct (pOpt, tstr);


	PrintFont.lfHeight          = POpt.FontHeight;
	PrintFont.lfWidth           = 0;
	PrintFont.lfEscapement      = 0;
  PrintFont.lfWeight          = POpt.FontWeight;
  PrintFont.lfItalic          = POpt.FontItalic;
	PrintFont.lfUnderline       = 0;
	PrintFont.lfStrikeOut       = 0;
	PrintFont.lfOrientation     = 0;
	PrintFont.lfCharSet         = POpt.CharSet;
	PrintFont.lfCLipPrecision   = CLIP_DEFAULT_PRECIS;
	PrintFont.lfQuality         = DEFAULT_QUALITY;
  PrintFont.lfPitchAndFamily  = FF_DONTCARE;
	PrintFont.lfFaceName        = POpt.FontName;

	ChooseRec.lStructSize     = 46;
	ChooseRec.hWndOwner       = dlg;                // caller's window handle
	ChooseRec.hDC             = dc;                 // printer DC/IC or nil
	ChooseRec.lpLogFont       = &PrintFont;         // ptr. to a LOGFONT struct
	ChooseRec.iPointSize      = 0;                  // 10 * size in points of selected font
  ChooseRec.Flags           = CF_PRINTERFONTS |
                              CF_INITTOLOGFONTSTR |
//                              CF_FIXEDPITCHONLY |
                              CF_SHOWHELP;        // enum. type flags
	ChooseRec.rgbColors       = 0x00ffffff;         // returned text color
	ChooseRec.lCustData       = 0;                  // data passed to hook fn.
	ChooseRec.lpfnHook        = 0;                  // ptr. to hook function
	ChooseRec.lpTemplateName  = 0;                  // custom template name
	ChooseRec.hInstance       = app_handle;
	ChooseRec.lpszStyle       = &t.style;           /* return the style field here
																										must be lf_FaceSize or bigger */
	ChooseRec.nFontType       = PRINTER_FONTTYPE;                  /* same value reported to the EnumFonts
																											call back with the extra fonttype_
																											bits added */
	ChooseRec.nSizeMin        = 0;                  // minimum pt size allowed &
	ChooseRec.nSizeMax        = 0;                  /* max pt size allowed if
																									cf_LimitSize is used      */

	if( HookFontPromptWithMacro( &ChooseRec, "PrintFontProc" ) )
	{

		POpt.FontName       = PrintFont.lfFaceName;
		POpt.FontHeight     = PrintFont.lfHeight;
		POpt.FontPointSize  = ChooseRec.iPointSize;
		Popt.CharSet        = PrintFont.lfCharset;
    POpt.FontWeight     = PrintFont.lfWeight;
    Popt.FontItalic     = PrintFont.lfItalic;

		struct_to_str (tstr, POpt);
		POptionsStruct = tstr;

		return(TRUE);
	}
	return (FALSE);
}

void PrintPageDialog (int dlg, struct TPrintDlg Pds)
{
	int jx;
	struct TPrintOptions pOpt;
	str tstr [1024] = POptionsStruct;
	str_to_struct (pOpt, tstr);

	int dlg;
	DlgCreate(dlg);

	DlgAddCtrl( dlg, DLG_GroupBox, "Margins", 1, 1, 18, 6, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Static,  "&Left:",   2, Dlg_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",         DLG_PosOffset + 8, Dlg_PosOffset, 5, 0, _PS_LMARGIN, 0, "/MAX=100/MIN=0");
	DlgAddCtrl( dlg, DLG_Static,  "&Right:",  2, Dlg_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",         DLG_PosOffset + 8, Dlg_PosOffset, 5, 0, _PS_RMARGIN, 0, "/MAX=100/MIN=0");
	DlgAddCtrl( dlg, DLG_Static,  "&Top:",    2, Dlg_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",         DLG_PosOffset + 8, Dlg_PosOffset, 5, 0, _PS_TMARGIN, 0, "/MAX=100/MIN=0");
	DlgAddCtrl( dlg, DLG_Static,  "&Bottom:", 2, Dlg_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",         DLG_PosOffset + 8, Dlg_PosOffset, 5, 0, _PS_BMARGIN, 0, "/MAX=100/MIN=0");

	DlgSetInt ( dlg, _PS_LMARGIN, POpt.LMargin);
	DlgSetInt ( dlg, _PS_RMARGIN, POpt.RMargin);
	DlgSetInt ( dlg, _PS_TMARGIN, POpt.TMargin);
	DlgSetInt ( dlg, _PS_BMARGIN, POpt.BMargin);

	DlgAddCtrl( dlg, DLG_GroupBox, "Header/Footer", 21, 1, 50, 6, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Static,   "H&eader:",  22, DLG_PosOffset + 1, 10, 0, -1,   0, "");
	DlgAddCtrl( dlg, DLG_CheckBox, "",          22, Dlg_PosOffset + 1, DLG_Units | 10,  0, _PS_HEADERON, 0, "");
	DlgAddCtrl( dlg, DLG_Text,     "",          DLG_PosOffset + 3, DLG_PosOffset, 45, 0, _PS_HEADER,   0, "/ML=128/HISTORY=HEADER_HISTORY");
	DlgAddCtrl( dlg, DLG_Static,   "F&ooter:",  22, DLG_PosOffset + 1, 10, 0, -1,   0, "");
	DlgAddCtrl( dlg, DLG_CheckBox, "",          22, DLG_PosOffset + 1, DLG_Units | 10,  0, _PS_FOOTERON, 0, "");
	DlgAddCtrl( dlg, DLG_Text,     "",          DLG_PosOffset + 3, DLG_PosOffset, 45, 0, _PS_FOOTER,   0, "/ML=128/HISTORY=FOOTER_HISTORY");

	DlgSetInt ( dlg, _PS_HEADERON, (POpt.Flags & POPTF_HEADERON) != 0);
	DlgSetInt ( dlg, _PS_FOOTERON, (POpt.Flags & POPTF_FOOTERON) != 0);
	jx = Parse_Int ("/#=", Global_Str ("HEADER_HISTORY") );
	if (jx) {
		DlgSetStr (dlg, _PS_HEADER, Global_Str ("HEADER_HISTORY" + Str (jx)));
	} else {
		DlgSetStr (dlg, _PS_HEADER, POpt.Header);
	}
	jx = Parse_Int ("/#=", Global_Str ("FOOTER_HISTORY") );
	if (jx) {
		DlgSetStr (dlg, _PS_FOOTER, Global_Str ("FOOTER_HISTORY" + Str (jx)));
	} else {
		DlgSetStr (dlg, _PS_FOOTER, POpt.Footer);
	}

	DlgAddCtrl( dlg, DLG_GroupBox, "From Edge", 73, 1, 20, 3, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Static,  "Hea&der:",  74, DLG_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",          DLG_PosOffset + 9, DLG_PosOffset, 5, 0, _PS_HEADEROFFSET, 0, "/MAX=100/MIN=0");
	DlgAddCtrl( dlg, DLG_Static,  "Foo&ter:",  74, DLG_PosOffset + 1, 8, 0, -1, 0, "");
	DlgAddCtrl( dlg, DLG_Integer, "",          DLG_PosOffset + 9, DLG_PosOffset, 5, 0, _PS_FOOTEROFFSET, 0, "/MAX=100/MIN=0");

	DlgSetInt ( dlg, _PS_HEADEROFFSET, POpt.HeaderOffset);
	DlgSetInt ( dlg, _PS_FOOTEROFFSET, POpt.FooterOffset);

	DlgAddCtrl(dlg, DLG_Static, "Line &Numbering:", 73, 5, 20, 0, -1, 0, "");
	DlgAddCtrl(dlg, DLG_Choice, "None()Number from Top()Number from Block()", DLG_PosOffset, DLG_PosOffset + 1, 20, 0, _PS_LINENUMBERING, 0, "");
	DlgSetInt (dlg, _PS_LINENUMBERING, POpt.LineNumbering + 1);

	DlgAddCtrl( dlg, DLG_PushButton, "OK", 1,   Dlg_PosOffset + 2,  Dlg_StanBtnWidth,                 0, 101, DLGF_DefButton, "/R=1");
	DlgAddCtrl( dlg, DLG_PushButton, "Cancel",  Dlg_PosOffset + 12, Dlg_PosOffset, Dlg_StanBtnWidth,  0, 102, 0, "/R=0");
  DlgAddCtrl( dlg, DLG_PushButton, "&Help",   Dlg_PosOffset + 70, Dlg_PosOffset, Dlg_StanBtnWidth,  0, 103, 0, "/R=2");

	int tint = DlgExecute(dlg, 101, "Page Setup", PAGESETUP_HELPLINK, '', 0);

	if ( tint == 1 )
	{
		POpt.LMargin = DlgGetInt ( dlg, _PS_LMARGIN);
		POpt.RMargin = DlgGetInt ( dlg, _PS_RMARGIN);
		POpt.TMargin = DlgGetInt ( dlg, _PS_TMARGIN);
		POpt.BMargin = DlgGetInt ( dlg, _PS_BMARGIN);
		POpt.HeaderOffset = DlgGetInt ( dlg, _PS_HEADEROFFSET);
		POpt.FooterOffset = DlgGetInt ( dlg, _PS_FOOTEROFFSET);

		POpt.Header = DlgGetStr (dlg, _PS_HEADER);
		POpt.Footer = DlgGetStr (dlg, _PS_FOOTER);

		POpt.LineNumbering = DlgGetInt (dlg, _PS_LINENUMBERING) - 1;

		if (DlgGetInt (dlg, _PS_HEADERON))
			POpt.flags |= POPTF_HEADERON;
		else
			POpt.flags &= (POPTF_HEADERON ^ 0xffff);

		if (DlgGetInt (dlg, _PS_FOOTERON))
			POpt.flags |= POPTF_FOOTERON;
		else
			POpt.flags &= (POPTF_FOOTERON ^ 0xffff);

		DlgKill (dlg);
		struct_to_str (tstr, POpt);
		POptionsStruct = tstr;
	}
}


int PrintSetupHook( int dlg, int message, int wparam, int lparam, struct TPrintDlg pds ) No_Break
{
	int result = 0;
 // msglog (1, "Setup", dlg, message, wparam, lparam);
	switch ( message )
	{
		case WM_INITDIALOG :
			// InitSetupDialog (dlg, pds);
			HelpLink_String = PRINTSETUP_HELPLINK;
			break;

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

		case WM_COMMAND :
			switch ( wparam  )
			{
				case _PS_PAGESETUP :
				{
					PrintPageDialog (dlg, pds);
					result = 1;
					break;
				}

				case _PS_FONTS :
				{
					int jx, dc;
					str szPrinter;

					if (SendDlgItemMessage (dlg, _P_DEFBTN, BM_GETSTATE, 0, 0) & 0x03) {
						dc = GetPrinterDC("");
					} else {
						jx = SendDlgItemMessage (dlg, _P_SELPRINTER, CB_GETCURSEL, 0, 0);
						SendDlgItemMessageStr (dlg, _P_SELPRINTER, CB_GETLBTEXT, jx, szPrinter);

						dc = GetPrinterDC (FindPrinterName (szPrinter));
					}
					if ( dc )
          {
            SelectPFont (dlg, dc);
						DeleteDC (dc);
          }
					result = 1;
					break;
				}

				case ID_OK :
					break;

				case _P_HELP :
					MewHelp_Context ();
					result = 1;
					break;
			}
			break;
	}
	return (result);
}

void PrintOptsDialog (int dlg, struct TPrintDlg Pds)
{
	struct TPrintOptions pOpt;
	str tstr [1024] = POptionsStruct;
	str_to_struct (pOpt, tstr);

	int dlg;
	DlgCreate(dlg);
  DlgAddCtrl( dlg, DLG_CheckBox, "&Page Breaks from embedded formfeeds",
    3, 1, 0, 0, _PO_FF, 0, "");
	DlgSetInt ( dlg, _PO_FF, (POpt.Flags & POPTF_USEFF) != 0);
  DlgAddCtrl( dlg, DLG_CheckBox, "&Wrap text at right margin",
    Dlg_PosOffset, Dlg_PosOffset + 1, 0, 0, _PO_WRAP, 0, "");
  DlgSetInt ( dlg, _PO_WRAP, (POpt.Flags & POPTF_WRAP) != 0);

  DlgAddCtrl( dlg, DLG_CheckBox, "&Syntax highlight",
    Dlg_PosOffset, Dlg_PosOffset + 1, 0, 0, _PO_SYNTAX, 0, "");
  DlgSetInt ( dlg, _PO_SYNTAX, (POpt.Flags & POPTF_SYNTAX) != 0);

//  DlgAddCtrl( dlg, DLG_CheckBox, "&Use color for syntax", 3, 2, 0, 0, _PO_COLOR, 0, "");
//  DlgSetInt ( dlg, _PO_WRAP, (POpt.Flags & POPTF_COLOR) != 0);

	DlgAddCtrl( dlg, DLG_PushButton, "OK", 1, Dlg_PosOffset + 2, Dlg_StanBtnWidth, 0, 101, DLGF_DefButton, "/R=1");
	DlgAddCtrl( dlg, DLG_PushButton, "Cancel", Dlg_PosOffset + 12, Dlg_PosOffset, Dlg_StanBtnWidth, 0, 102, 0, "/R=0");
	DlgAddCtrl( dlg, DLG_PushButton, "&Help", Dlg_PosOffset + 40, Dlg_PosOffset, Dlg_StanBtnWidth, 0, 103, 0, "/R=2");

	return_int = DlgExecute(dlg, _PO_FF, "Print Options", PRINTOPT_HELPLINK, '', 0);

	if ( return_int == 1 )
	{
		if (DlgGetInt (dlg, _PO_FF))
			POpt.flags |= POPTF_USEFF;
		else
			POpt.flags &= (POPTF_USEFF ^ 0xffff);

		if (DlgGetInt (dlg, _PO_WRAP))
			POpt.flags |= POPTF_WRAP;
		else
      POpt.flags &= (POPTF_WRAP ^ 0xffff);

    if (DlgGetInt (dlg, _PO_SYNTAX))
      POpt.flags |= POPTF_SYNTAX;
		else
      POpt.flags &= (POPTF_SYNTAX ^ 0xffff);

//    if (DlgGetInt (dlg, _PO_COLOR))
//      POpt.flags |= POPTF_COLOR;
//    else
//      POpt.flags &= (POPTF_COLOR ^ 0xffff);

		DlgKill (dlg);
		struct_to_str (tstr, POpt);
		POptionsStruct = tstr;
	}
}

int PrintHook( int dlg, int message, int wparam, int lparam, struct TPrintDlg pds ) No_Break
{
	int result = 0;
	// msglog (1, "Print", dlg, message, wparam, lparam);
	switch ( message )
	{
		case WM_INITDIALOG :
			HelpLink_String  = PRINT_HELPLINK;
      int jx;
      int t_win = cur_window;
      int t_refresh = refresh;
      refresh = false;

      if (g_printwindow == 0 )
      {
        for ( jx = 1; jx <= window_count; jx++ )
        {
          switch_window ( jx);
          if ( collapse_mode != 0 )
          {
            break;
          }
        }
        if ( jx == (window_count+1) )
        {
          EnableWindow (GetDlgItem (dlg, _PN_PRNCOLLAPSE), False)
        }
      }
      else
      {
        switch_window (g_printwindow);
        if ( collapse_mode == 0 )
        {
          EnableWindow (GetDlgItem (dlg, _PN_PRNCOLLAPSE), False)
        }
        if ( (window_attr & 0x20) != 0)
        {
          SendDlgItemMessage (dlg, _PN_HEX, BM_SETCHECK, 1, 0);
        }
      }
      switch_window (t_win);
      refresh = t_refresh;
			break;

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

			break;

		case WM_COMMAND :
			switch ( wparam  )
			{
				case _PN_OPTIONS :
					PrintOptsDialog (dlg, pds);
					result = 1;
					break;

				case _PS_PAGESETUP :
					PrintPageDialog (dlg, pds);
					result = 1;
					break;

				case _PS_FONTS :
				{
					int jx, dc = 0;
					str szPrinter[128];

					GetWindowText (GetDlgItem (dlg, _P_PRNPRINTER), szPrinter, 127);
					str prn_string = FindPrinterName (szPrinter);

					dc = GetPrinterDC (prn_string);

					if ( dc )
          {
            SelectPFont (dlg, dc);
						DeleteDC (dc);
          }
					result = 1;
					break;
				}
				case ID_OK :
          struct TPrintOptions pOpt;
          str tstr [1024] = POptionsStruct;
          str_to_struct (pOpt, tstr);

          if (SendDlgItemMessage (dlg, _PN_PRNCOLLAPSE, BM_GETCHECK, 0, 0))
          {
            POpt.flags |= POPTF_COLLAPSE;
          }
          else
          {
            POpt.flags &= POPTF_COLLAPSE ^ 0XFFFFFFFF;
          }
          if (SendDlgItemMessage (dlg, _PN_HEX, BM_GETCHECK, 0, 0))
          {
            POpt.flags |= POPTF_HEX;
          }
          else
          {
            POpt.flags &= POPTF_HEX ^ 0XFFFFFFFF;
          }
          struct_to_str (tstr, POpt);
          POptionsStruct = tstr;
					break;

				case _P_HELP :
					MewHelp_Context();
					result = 1;
					break;
			}

	}
	return (result);
}

void InitOptions ()
{
	struct TPrintOptions pOpt;
	str tstr [1024] = POPtionsStruct;
	if ( tstr == "")
	{
    POpt.Header = Default_Header;
    POpt.Footer = Default_Footer;

		POpt.LMargin = 3;
		POpt.RMargin = 3;
		POpt.TMargin = 3;
		POpt.BMargin = 3;

		POpt.LineNumbering = 0;

		POpt.HeaderOffset = 1;
		POpt.FooterOffset = 1;

		POpt.Flags = POPTF_HEADERON | POPTF_FOOTERON;

		POpt.FontName       = "Courier New";
		POpt.FontHeight     = -13;
		Popt.FontPointSize  = 90;
		POpt.CharSet        = 0;
    POpt.FontWeight     = FW_NORMAL;
    POpt.FontItalic     = 0;
	}
	else
	{
		str_to_struct (pOpt, tstr);
		if ( POpt.Fontname == '' )
		{
			POpt.FontName       = "Courier New";
			POpt.FontHeight     = -13;
			Popt.FontPointSize  = 90;
			POpt.CharSet        = 0;
      POpt.FontWeight     = FW_NORMAL;
      POpt.FontItalic     = 0;
		}
	}
	if ( parse_int ("/#=", Global_Str("HEADER_HISTORY")) == 0 )
	{
		return_str = POpt.Header;
		RM ("HISTORY_LIST /M=1/HISTORY=HEADER_HISTORY");
	}
	if ( parse_int ("/#=", Global_Str("FOOTER_HISTORY")) == 0 )
	{
		return_str = POpt.Footer;
		RM ("HISTORY_LIST /M=1/HISTORY=FOOTER_HISTORY");
	}

	struct_to_str (tstr, pOpt);
	POptionsStruct = tstr;
}

int PrintWindowRaw ( int parent, int win, struct TPrintDlg pds)
{

  int result = 0;
  if ( pds.hdc != 0)
  {
    struct TPrintOptions PrnOpt;
    str tstr [1024] = POptionsStruct;
    str_to_struct (PrnOpt, tstr);

    PrintFromWindow (parent, win, &pds, &PrnOpt);
    result = 1;
  }
  return (result);
}


/*******************************************************************************
  PrintDialog - 9/13/95 3:22PM

 parent = The windows window handle of the parent to the dialog. Usually frame_handle
 win    = the mulit-edit buffer number to use for the dialog.  if  0 then no check
 pds    = The print dialog structure to return info in.

 Note: That if  return is ok it will be neces sary to do a DeleteDC on the hdc in the
        print dialog structure after using it.

 Returns:
 0        = if canceled
 non zero = if  Ok

 by John K. Perona, Copyright 1995 by American Cybernetics, Inc.

********************************************************************************/
int PrintDialog( int parent, int win, struct TPrintDlg pds )
{

  int tRefresh = Refresh;

	struct TPrintRec prec;

  refresh = False;

	InitOptions ();

	if ( !parent )
		parent = frame_handle;

  g_printwindow = win;
	int twin = cur_window;
	if ( win )
		switch_window (win);

	HelpLink_String = PRINT_HELPLINK;


  if ( GetDevNamesHandle() && GetDevModeHandle() )
  {
    struct TDevNames  devn;

    GetGlobalStructure (GetDevNamesHandle(), &devn, 0);
    if ( devn.wDefault & DN_DEFAULTPRN)
    {

      pds.lStructSize           = 52;
      pds.hDevMode              = 0;
      pds.hDevNames             = 0;
      pds.flags                 = PD_RETURNDEFAULT;

      PrintDlg (&pds);

      struct TDevMode   devm;

      GetGlobalStructure (GetDevModeHandle(),  &devm, 0);
      str oldname = devm.dmDeviceName;

      GetGlobalStructure (pds.hDevMode, &devm, 0);
      str newname = devm.dmDeviceName;

      if ( newname != oldname )
      {
        GlobalFree (GetDevModeHandle ());
        GlobalFree (GetDevNamesHandle());
        SetDevModeHandle (0);
        SetDevNamesHandle (0);
      }
      GlobalFree (pds.hDevMode);
      GlobalFree (pds.hDevNames);
    }
  } else {
    SetDevNamesHandle (0);
    SetDevModeHandle (0);
  }



  prec.PrintTemplate        = "PRINTPROMPT";
  prec.SetupTemplate        = "PRINTSETUPPROMPT";
	pds.hWndOwner             = parent;
	pds.HInstance             = app_handle;
  pds.hDevMode              = GetDevModeHandle();
  pds.hDevNames             = GetDevNamesHandle();
	pds.nCopies               = 1;
	pds.nFromPage             = 0xffff;
	pds.nToPage               = 0xffff;
	pds.nMinPage              = 0;
	pds.nMaxPage              = 0;
	pds.flags                 = PD_ENABLEPRINTTEMP | PD_ENABLESETUPTEMP | PD_SHOWHELP | PD_RETURNDC;
	pds.lCustData             = 0;
	pds.lpfnPrintHook         = 0;
	pds.lpfnSetupHook         = 0;
	pds.lpPrintTemplateName   = &prec.PrintTemplate;
	pds.lpSetupTemplateName   = &prec.SetupTemplate;

	pds.flags |= PD_COLLATE;

	if (doc_mode) {
		pds.nMinPage = 1;
		pds.nMaxPage = 0xffff;
	} else {
		pds.flags |= PD_NOPAGENUMS;
	}


  if ( win )
  {
    if ( block_stat) {
      pds.flags |= PD_SELECTION;
    } else {
      pds.flags |= PD_NOSELECTION | PD_ALLPAGES;
    }
  } else {
    pds.flags |= PD_NOSELECTION | PD_ALLPAGES;
  }

  int result = HookPrintPromptWithMacro ( &pds, "PrintHook", "PrintSetupHook");

	if ( result  )
	{
    SetDevModeHandle (pds.hDevMode);
    SetDevNamesHandle (pds.hDevNames);

		SavePrintCfg ();
  } else {
		int error = CommDlgExtendedError ();
		if ( error )
		{
			Make_Message ("Error= " + str (CommDlgExtendedError()));
		}
	}
	HelpLink_String = "";

	switch_window (twin);
	refresh = tRefresh;
  g_printwindow = 0;
  return (result);
} // PrintDialog

void PrintWindow ( int parent = parse_int("/DLGHANDLE=", mparm_str),
                   int win    = parse_int("/WINHANDLE=", mparm_str))
{
  struct TPrintDlg PrnDialogStruct;
  if ( !win )
  {
    win = cur_window;
  }

  if ( PrintDialog (parent, win, PrnDialogStruct) )
  {
    if ( PrnDialogStruct.hdc != 0)
    {
      struct TPrintOptions PrnOpt;
      str tstr [1024] = POptionsStruct;
      str_to_struct (PrnOpt, tstr);

      PrintFromWindow (parent, win, &PrnDialogStruct, &PrnOpt);
      DeleteDC (PrnDialogStruct.hdc);
    }
	}
	return ();
}

void PrintSetup ( int parent = parse_int("/DLGHANDLE=", mparm_str) )
{
	int result;
	int tRefresh = refresh;

	InitOptions ();
	if (!parent )
	{
		parent = frame_handle;
	}
	struct TPrintDlg pds;
	struct TPrintRec prec;

	refresh = FALSE;

	prec.SetupTemplate        = "PRINTSETUPPROMPT";

	pds.hWndOwner             = parent;
	pds.HInstance             = app_handle;
  pds.hDevMode              = GetDevModeHandle ();
  pds.hDevNames             = GetDevNamesHandle ();
	pds.nCopies               = 1;
	pds.nFromPage             = 0xffff;
	pds.nToPage               = 0xffff;
	pds.nMinPage              = 0;
	pds.nMaxPage              = 0;
	pds.flags                 = PD_ENABLESETUPTEMP | PD_PRINTSETUP | PD_SHOWHELP;
	pds.lCustData             = 0;
	pds.lpfnPrintHook         = 0;
	pds.lpfnSetupHook         = 0;
	pds.lpPrintTemplateName   = 0;
	pds.lpSetupTemplateName   = &prec.SetupTemplate;

	result = HookPrintPromptWithMacro ( &pds, "", "PrintSetupHook");

	if ( result )
	{
    SetDevModeHandle (pds.hDevMode);
    SetDevNamesHandle (pds.hDevNames);

		SavePrintCfg ();
	}

	refresh = tRefresh;
	return();
}

void Prn_Filter (str &t_str) TRANS2 {
	int filter_char = global_int("@PRN_FILTER_CHAR"),
			t_int,
			t_str_addr = ((seg(t_str) << 16) | ofs(t_str)) + 3;

	if (filter_char == 0) {
		filter_char = 32; // default is a space
	} else if (filter_char == -1) {
		filter_char = 0; // null if global is -1
	}

	for (t_int = 1; t_int <= svl(t_str); ++t_int) {
		if (xpos(str_char(t_str,t_int),"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F",1)) {
			memb(t_str_addr + t_int, filter_char);
		}
	}
}
