/* REXX exec containing support routines for the EHIxxxx execs        */
/*** trace ?r ***************************************************** \| *
*               (C) Copyright Robert AH Prins, 2007-2017               *
************************************************************************
*  ------------------------------------------------------------------  *
* | Date       | By   | Remarks                                      | *
* |------------+------+----------------------------------------------| *
* |            |      |                                              | *
* |------------+------+----------------------------------------------| *
* | 2017-05-15 | RAHP | Remove long form ISPF colours                | *
* |------------+------+----------------------------------------------| *
* | 2016-11-24 | RAHP | Add "ehixmit" interface                      | *
* |------------+------+----------------------------------------------| *
* | 2016-11-18 | RAHP | Multiple updates/simplifications             | *
* |------------+------+----------------------------------------------| *
* | 2016-02-22 | RAHP | Remove action bars from display              | *
* |------------+------+----------------------------------------------| *
* | 2012-11-26 | RAHP | Remove '$', '#' & '@' in names (ooREXX)      | *
* |------------+------+----------------------------------------------| *
* | 2012-06-25 | RAHP | wscon changes                                | *
* |------------+------+----------------------------------------------| *
* | 2009-07-27 | RAHP | Add monitor function                         | *
* |------------+------+----------------------------------------------| *
* | 2009-07-02 | RAHP | - add selection for short CSS 'em' colors    | *
* |            |      | - allow progress interval up to 5000         | *
* |------------+------+----------------------------------------------| *
* | 2009-06-18 | RAHP | Add short form ISPF colors                   | *
* |------------+------+----------------------------------------------| *
* | 2009-05-04 | RAHP | Add 'whitespace:pre' for 'Edit' and 'None'   | *
* |------------+------+----------------------------------------------| *
* | 2009-04-30 | RAHP | Remove header and footer for 'None'          | *
* |------------+------+----------------------------------------------| *
* | 2009-04-23 | RAHP | Make 'Edit' and 'None' HTML also 'XHTML 1.0  | *
* |            |      | Strict' compliant                            | *
* |------------+------+----------------------------------------------| *
* | 2009-04-22 | RAHP | Update comment                               | *
* |------------+------+----------------------------------------------| *
* | 2009-04-01 | RAHP | Add font selection for generated HTML        | *
* |------------+------+----------------------------------------------| *
* | 2009-03-16 | RAHP | Replace LISTDSI by BXPWDYN                   | *
* |------------+------+----------------------------------------------| *
* | 2009-03-02 | RAHP | Make HTML 'XHTML 1.0 Strict' compliant       | *
* |------------+------+----------------------------------------------| *
* | 2009-02-09 | RAHP | - Update for Firefox 3.x                     | *
* |            |      | - RACF problem with 'html' extension @ NVSM  | *
* |------------+------+----------------------------------------------| *
* | 2007-09-27 | RAHP | Free panel dataset                           | *
* |------------+------+----------------------------------------------| *
* | 2007-09-24 | RAHP | Add panel to modify options                  | *
* |------------+------+----------------------------------------------| *
* | 2007-09-18 | RAHP | - add GPL V3 License                         | *
* |            |      | - add GET_OPTIONS routine                    | *
* |------------+------+----------------------------------------------| *
* | 2007-09-17 | RAHP | Correct tag mismatch                         | *
* |------------+------+----------------------------------------------| *
* | 2007-09-11 | RAHP | Add ISPF generating code                     | *
* |------------+------+----------------------------------------------| *
* | 2007-09-06 | RAHP | Cater for PC environment                     | *
* |------------+------+----------------------------------------------| *
* | 2007-08-30 | RAHP | Add generate CSS to make HTML 4.01 compliant | *
* |------------+------+----------------------------------------------| *
* | 2007-08-23 | RAHP | Initial version                              | *
* |------------+------+----------------------------------------------| *
************************************************************************
* EHISUPP is a REXX exec containing a number of support routines for   *
* the various other EHIxxxx execs. To use this exec, it needs to be    *
* passed the required routine and its arguments.                       *
*                                                                      *
* The routines currently implemented are:                              *
*                                                                      *
* - generate_output                                                    *
*                                                                      *
*   This routine expects six parameters, containing                    *
*                                                                      *
*   o 1 - the separator for the next five parameters                   *
*   o 2 - the generated HTML string, with records separated by         *
*         "br" tags                                                    *
*   o 3 - the name of the output file where the HTLM will be saved     *
*   o 4 - a title for the window                                       *
*   o 5 - a header to append to the top of the generated HTML          *
*   o 6 - a footer to append to the bottom of the generated HTML       *
*                                                                      *
*   The routine will cut the generated HTML on the "br" tags, append   *
*   the title, header and footer and save the HTML in the output file. *
*                                                                      *
* - xfer_and_show_html                                                 *
*                                                                      *
*   This routine expects five parameters, containing                   *
*                                                                      *
*   o 1 - the separator for the next four parameters                   *
*   o 2 - the name of the directory on the PC to receive the file      *
*   o 3 - the name of the file on the PC                               *
*   o 4 - the name of the file on the host                             *
*   o 5 - a flag to indicate to start the application associated with  *
*         an extension of '.html' on the PC (YES/NO)                   *
*                                                                      *
* - get_options                                                        *
*                                                                      *
*   This routine expects two parameters, containing                    *
*                                                                      *
*   o 1 - the separator that will be used to concatenate the returned  *
*         values                                                       *
*   o 2 - the name of the invoking macro                               *
*                                                                      *
* t_rex will contain the environment. It can be:                       *
*                                                                      *
* - TSO     - TSO/ISPF                                                 *
* - MVS     - z/OS (PGM=IRXJCL)                                        *
* - SYSTEM  - Regina                                                   *
* - COMMAND - PC DOS 7/2000                                            *
* - CMD     - Object REXX (OS/2, Windoze)                              *
************************************************************************
* Send questions, suggestions and/or bug reports to:                   *
*                                                                      *
* robert@prino.org / robert.ah.prins@gmail.com                         *
*                                                                      *
* Robert AH Prins                                                      *
* Taboralaan 46                                                        *
* 8400 Oostende                                                        *
* Belgium                                                              *
************************************************************************
* This program is free software: you can redistribute it and/or        *
* modify it under the terms of the GNU General Public License as       *
* published by the Free Software Foundation, either version 3 of       *
* the License, or (at your option) any later version.                  *
*                                                                      *
* This program is distributed in the hope that it will be useful,      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
* GNU General Public License for more details.                         *
*                                                                      *
* You should have received a copy of the GNU General Public License    *
* along with this program. If not, see <http://www.gnu.org/licenses/>  *
***********************************************************************/
parse source source
parse value source with . . moi . . . cmdenv aspace .

t_rex = address()
!br   = '<b' || 'r>'

/***********************************************************************
* Set to 0 if no default modification pop-up panel is required         *
***********************************************************************/
popup = 1

parse arg function ',' data

interpret 'signal' function

/***********************************************************************
* GENERATE_OUTPUT:                                                     *
*                                                                      *
* This procedure writes the output to a temporary dataset              *
***********************************************************************/
generate_output:
  parse value data with sep ',' htmlout (sep),
                                odsn (sep),
                                title (sep),
                                header (sep),
                                footer (sep),
                                htmlfont

  lrecl = 0

  if left(htmlout, 6) = x2c(ff)'ISPF'x2c(ff) then
    call generate_ispf
  else
    call generate_std

  call split_writer

  /*********************************************************************
  * Clean up                                                           *
  *********************************************************************/
  "ispexec qlibdef ispplib id(id)"
  if rc = 0 then
    do
      "ispexec libdef ispplib"
      "free f("id")"
    end

return 0

/***********************************************************************
* GENERATE_STD:                                                        *
*                                                                      *
* Generate standard (fast) HTML                                        *
***********************************************************************/
generate_std:
  /*********************************************************************
  * Put the header lines on the stack                                  *
  *********************************************************************/
  queue '<!DOCTYPE html>'
  queue '<html lang="en">'
  queue '<!--' footer '-->'
  queue '<head>'
  queue '  <meta charset="UTF-8" />'
  queue '  <title>' || title || '</title>'
  queue ' '
  queue '  <style type="text/css" media="screen">'
/*queue '  a         { text-decoration:none; }'
  queue '  a:link    { color:lime; }'
  queue '  a:active  { color:lime; }'
  queue '  a:visited { color:lime; }'
  queue '  a:hover   { color:#7890f0; font-style:italic; }'
*/queue ' '
  queue '  em             { font-style:normal; }'
  queue '  em.b           { color:#7890f0; }'
  queue '  em.f           { color:pink;    }'
  queue '  em.l           { color:lime;    }'
  queue '  em.r           { color:red;     }'
  queue '  em.t           { color:aqua;    }'
  queue '  em.w           { color:white;   }'
  queue '  em.y           { color:yellow;  }'
  queue ' '
  queue '  body {'
  queue '    background-color: #000000;'
  queue '    color: #00FF00;'
  queue '    font-size: 1vw;'
  queue '    padding: 0 0 0 1em;'
  queue '  }'
  queue ' '
  queue '  pre {'
  queue '    font-family: "Liberation Mono",Inconsolata,' ||,
                         '"Courier New",monospace;'
  queue '  }'
  queue '  </style>'
  queue ' '
  queue '</head>'
  queue '<body><pre>'

  lrecl = max(109, length(footer) + 9, length(title) + 15)

  /*********************************************************************
  * Split the code on "br" tags and put them on the stack              *
  *********************************************************************/
  do while htmlout \= ''
    parse value htmlout with dataline (!br) htmlout

    dataline = strip(dataline, 'T')
      queue dataline

    lrecl = max(lrecl, length(dataline))
  end

  queue '</pre></body>'
  queue '</html>'

  html = ''
return 0

/***********************************************************************
* GENERATE_ISPF:                                                       *
*                                                                      *
* Generate a fancy ISPF-like scrolling HTML page                       *
***********************************************************************/
generate_ispf:
  parse value title with . ':' idsn

  idsn    = left(strip(idsn), 47)
  seq     = strip(substr(htmlout, 7, 6), 'L', '0')
  htmlout = substr(htmlout, 14)

  css     = generate_ispf_css()

  !footer = '*|*' || 'FOOTER' || '*|*'
  !title  = '*|*' || 'TITLE'  || '*|*'
  !dsn    = '*|*' || 'DSN'    || '*|*'
  !seq    = '*|*' || 'SEQ'    || '*|*'
  !data   = '*|*' || 'DATA'   || '*|*'!br

  parse value css with p1 (!footer),
                       p2 (!title),
                       p3 (!dsn),
                       p4 (!seq),
                       p5 (!data) p6

  html = p1 || footer  ||,
         p2 || title   ||,
         p3 || idsn    ||,
         p4 || seq     ||,
         p5 || htmlout || p6
return

/***********************************************************************
* SPLIT_WRITER:                                                        *
*                                                                      *
* Split to generated output on "br" tags, put the parts on the stack   *
* and write them to a file.                                            *
***********************************************************************/
split_writer:
  /*********************************************************************
  * Split the output on "br" tags and put them on the stack            *
  *********************************************************************/
  do while html \= ''
    parse value html with dataline (!br) html
    queue strip(dataline, 'T')

    lrecl = max(lrecl, length(dataline))
  end

  /*********************************************************************
  * Create the output dataset                                          *
  *********************************************************************/
  if t_rex = 'TSO' then
    do
      if aspace = 'ISPF' then
        "ispexec lmerase dataset("odsn")"
      else
        "del" odsn

      dynlib = 'dyn'random(99999)

      "alloc f("dynlib") da("odsn") new reu " ||,
                        "unit(sysda)" || ,
                        "space(60 60) tracks release " ||,
                        "recfm(v b) lrecl("lrecl + 4") blksize(0)"
      if rc > 0 then
        do
          say 'Error when allocating' odsn
          return 8
        end

      /*****************************************************************
      * Write out the stack                                            *
      *****************************************************************/
      "execio" queued() "diskw" dynlib "(finis)"
      if rc > 0 then
        do
          queue 'Error when writing to' odsn
          return 8
        end

      "free f("dynlib")"
    end
  else
    if t_rex = 'SYSTEM'  |,                            /* Regina      */
       t_rex = 'COMMAND' |,                            /* PC DOS 7    */
       t_rex = 'CMD' then                              /* Object REXX */
      do
        htmlfile = space(idsn'.t'translate(time(), ' ', ':')'.html', 0)

        do queued()
          parse pull line
          call lineout htmlfile, line
        end
      end
return 0

/***********************************************************************
* XFER_AND_SHOW_HTML:                                                  *
*                                                                      *
* Transfer the html file to the PC via ISPF Workstation Agent and      *
* start the application associated with extension .html                *
***********************************************************************/
xfer_and_show_html:
  parse value data with sep ',' dir_pc (sep),
                                htmlfile (sep),
                                odsn (sep),
                                ipaddr (sep),
                                start_browser

  /*********************************************************************
  * Format the name of the html file for PC                            *
  *********************************************************************/
  if right(dir_pc, 2) \= ':\' then
    dir_pc = strip(dir_pc, 'T', '/') || '/'

  w = dir_pc || htmlfile

  connected     = 0
  was_connected = 0

  /*********************************************************************
  * Is user already connected to workstation?                          *
  *********************************************************************/
  "ispexec vget zwscon shared"
  if rc     = 8 |,
     zwscon = '' then
    do
      was_connected = 0

      /*****************************************************************
      * Start connection and check that we're really connected         *
      *****************************************************************/
      title  = strip(left(htmlfile, 64))

      /*****************************************************************
      * WSCON always returns rc 8 when a member has been opened in     *
      * edit mode immediately before the WSCON service. So this        *
      * sequence of commands is only there to be on the safe side ;-)  *
      * Code from Stefan Brech via ISPF-L list                         *
      *****************************************************************/
      zedlmsg = ''
      zedsmsg = ''
      "ispexec control display lock"
      "ispexec display msg(isrz000)"

      "ispexec wscon ip(ipaddr) "     ||,
                    "title(title) "   ||,
                    "codepage(1140) " ||,
                    "charset(0695) "  ||,
                    "noguidsp "       ||,
                    "panel(onerror)"

      if rc = 0 then
        connected = 1
    end
  else
    do
      connected     = 1
      was_connected = 1
    end

  /*********************************************************************
  * Issue message if still no connection exists                        *
  *********************************************************************/
  if connected = 0 then
    "ispexec setmsg msg(ispp605)"
  else
    do
      h = odsn

      /*****************************************************************
      * Put filenames in the ISPF pool & transfer file to PC           *
      *****************************************************************/
      "ispexec filexfer host(h) ws(w) to(ws) text"

      /*****************************************************************
      * and optionally start the corresponding browser                 *
      *****************************************************************/
      if translate(left(start_browser, 1)) = 'Y' then
        "ispexec select wscmd("w") modeless min invis"

      /*****************************************************************
      * Only close connection to the workstation if it hadn't been     *
      * estabished before this exec                                    *
      *****************************************************************/
      if was_connected = 0 then
        "ispexec wsdiscon"
    end
return 0

/***********************************************************************
* GENERATE_ISPF_CSS:                                                   *
*                                                                      *
* Generate the embedded CSS for the output file                        *
***********************************************************************/
generate_ispf_css:
  signal get_ispf_css

/*
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<!-- *|*FOOTER+
*|* -->
<head>
<title>*|*TITLE+
*|*</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
body
  {
   margin:0px;
   overflow:hidden;
   background-color:black;
   color:lime;
   font:normal 48px/52px "FonT";
  }

.floatleft
  {
   float:left;
  }

.rightheader
  {
   float:right;
   text-align:right;
  }

.ul
  {
   text-decoration: underline;
  }

#headers
  {
   position:absolute;
   top:0px;
   left:0px;
   width:500px;
  }

#extra
  {
   width:100%;
   overflow:hidden;
  }

#fixed
  {
   width:100%;
   overflow:hidden;
  }

#leftarea
  {
   float:left;
   overflow:hidden;
   height:200px;
  }

#mainarea
  {
   position:relative;
   overflow:scroll;
   height:2000px;
   white-space:pre;
   color:lime;
  }

#colto, #colfrom
  {
   color:aqua;
  }

#topofdata
  {
   position:absolute;
   white-space:pre;
   color:#7890f0;
  }

#bottomofdata
  {
   position:relative;
   white-space:pre;
   color:#7890f0;
  }

#measure
  {
   position:absolute;
   top:1px;
   visibility:hidden;
  }

#scrolltest
  {
   position:absolute;
   overflow:hidden;
   visibility:hidden;
  }

em             { font-style:normal; }
em.b           { color:#7890f0; }
em.f           { color:fuchsia; }
em.l           { color:lime;    }
em.r           { color:red;     }
em.t           { color:aqua;    }
em.w           { color:white;   }
em.y           { color:yellow;  }

</style>
</head>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
- - -->
<!-- Copyright (C) 2007-2009 Small Office Solutions Ltd.               +
    -->
<!--               http://www.smallofficesolutions.co.uk               +
    -->
<!--                                                                   +
    -->
<!-- This program is free software; you can redistribute it and/or modi+
fy  -->
<!-- it under the terms of the GNU General Public License as published +
by  -->
<!-- the Free Software Foundation; either version 3 of the License, or +
    -->
<!-- (at your option) any later version.                               +
    -->
<!--                                                                   +
    -->
<!-- This program is distributed in the hope that it will be useful,   +
    -->
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of    +
    -->
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     +
    -->
<!-- GNU General Public License for more details.                      +
    -->
<!--                                                                   +
    -->
<!-- You should have received a copy of the GNU General Public License +
    -->
<!-- along with this program. If not, see <http://www.gnu.org/licenses/+
>.  -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
- - -->

<body onload="setwidth();">
 <div id="scrolltest">aaaaaaaaaaaaaaaaaaaaaa</div>
 <div id="measure">1234567890&nbsp;This&nbsp;is&nbsp;a&nbsp;fixed&nbsp;+
80&nbsp;characters&nbsp;width:&nbsp;do&nbsp;not&nbsp;change&nbsp;this+
&nbsp;text!&nbsp;4567890</div>
 <div id="extra">
  <em class="w">&nbsp;&nbsp;&nbsp;<span class="ul">F</span>ile+
&nbsp;&nbsp;<span class="ul">E</span>dit&nbsp;&nbsp;E<span class="ul">d+
</span>it_Settings&nbsp;&nbsp;<span class="ul">M</span>enu&nbsp;&nbsp;+
<span class="ul">U</span>tilities&nbsp;&nbsp;<span class="ul">C</span>+
ompilers&nbsp;&nbsp;<span class="ul">T</span>est&nbsp;&nbsp;+
<span class="ul">H</span>elp</em><br />
  <em class="b">&nbsp;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;+
&mdash;&mdash;&mdash;</em><br />
 </div>
 <div id="fixed">
  <span class="floatleft"><em class="t">&nbsp;VIEW&nbsp;&nbsp;+
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*|*DSN+
*|*</em></span>
  <br /><span style="white-space:nowrap;"><em class="l">+
&nbsp;Command ===></em> <em class="t">+
_________________________________________________</em></span>
  <span id="headers" class="rightheader"><em class="l"><br />+
<br />Columns</em> <span id="colfrom">00001</span>&nbsp;<span id=+
"colto">00072</span><br /><em class="l"> Scroll ===></em>&nbsp;+
<em class="t"><span class="ul">CSR&nbsp;</span></em></span>
 </div>
 <div id="leftarea">
  <em class="r">&nbsp;******<br /> </em>
  <em class="b">
  <script type="text/javascript">
//<![CDATA[
    seq = *|*SEQ+
*|*
    var a = [];

    if (seq <= 9999)
    {
      z = '00<br />&nbsp;'
      for (var i = 0; i < seq; i++)
        a[i] = (i+10001).toString().substr(1);
      document.write('&nbsp;'+a.join(z)+'00<br />');
    }
    else
    {
      z = '0<br />&nbsp;'
      for (var i = 0; i < seq; i++)
        a[i] = (i+100001).toString().substr(1);
      document.write('&nbsp;'+a.join(z)+'0<br />');
    }
//]]>
  </script>
  </em>
  <em class="r">&nbsp;******</em>
 </div>
<div class="floatleft">&nbsp;</div>
<div id="mainarea"><span id="topofdata">+
***************************** Top of Data +
******************************</span><!-- Formatted data follows; do +
NOT break this line apart or insert additional line breaks..   -->
*|*DATA+
*|*
<span id="bottomofdata">**************************** Bottom of Data +
****************************</span>
</div>
<script type="text/javascript" defer="defer">
//<![CDATA[
  var fs2=0;  // the actual fs2 of the fixed-width text.
  var fs=0;   // the actual number of pixels width of each character.
  var ss=0;   // dimensions of a browser scrollbar (note: ss will be +
NEGATIVE)

  function ge(x) {return document.getElementById(x);}
  function gs(x) {return document.getElementById(x).style;}
  function setwidth() { // do initial sizing calculations and layout

  var thisContainer = document.getElementById('mainarea');
  if (thisContainer)
    {
     var onClickAction = 'scrollmain();';
     thisContainer.onscroll = new Function(onClickAction);
    }

  ss=ge('scrolltest').offsetHeight;                    // get the +
height of a single line div without scrollbars
  gs('scrolltest').overflow='scroll';                  // allow the +
scrollbars to show
  ss-=ge('scrolltest').offsetHeight;                   // find the +
difference (i.e. the height of a scrollbar - assume height of +
horizontal bar = width of vertical bar!

  var wh=window.innerHeight?window.innerHeight:document.documentElement+
.clientHeight?document.documentElement.clientHeight:document.body.+
clientHeight;
  var ww=window.innerWidth?window.innerWidth:document.documentElement.+
clientWidth?document.documentElement.clientWidth:document.body.+
clientWidth;
      // determine the actual window inner height+width
  fs2=Math.floor(ww/40);                               // "FonT" +
is twice as high as it is wide; we need 80 columns; this is an +
approximation only
  while ((Math.floor(ge('measure').scrollWidth) > Math.floor(ww+ss)) +
&& fs2>1) // iteratively reduce fs2 until 80 columns fits on-screen
    {
    fs2-=1;document.body.style.font='normal '+fs2+'px/'+(fs2+4)++
'px "FonT"';
    gs('measure').font='normal '+fs2+'px/'+(fs2+4)+'px "FonT"';
    }
  gs('fixed').width=ge('measure').scrollWidth+'px';    // set the +
width of the header area
  fs=ge('measure').scrollWidth / 80;                   // get the +
width of a character
  gs('headers').height=(4+fs2)+'px';                   // limit the +
height of the headers
  gs('fixed').height=(8+(2*fs2))+'px';                 // fix the +
height of the header at just two rows
  gs('fixed').width=ge('measure').scrollWidth+'px';
  gs('headers').width=gs('fixed').width;
  gs('mainarea').width=(ge('measure').scrollWidth-(fs*8)-ss)+'px'; +
// set the width of the main area
  gs('mainarea').height=(8+(wh+ss)-(6*fs2))+'px';      // set the main +
area height
  gs('leftarea').height=(8+(wh+ss)-(6*fs2)+ss)+'px';   // set the left +
area height
  gs('measure').display='none';                        // don't +
display our 80-character measure
  gs('scrolltest').display='none';                     // don't +
display the scrollbar measuring div
  scrollmain();                                        // set up the +
initial column numbers
  ge('mainarea').scrollLeft=0;
  }

  function scrollmain() { // update the column indicators
  var main=ge('mainarea');
  var col='0000'+Math.floor((fs+(fs/2)+main.scrollLeft)/fs);   // get +
the leftmost column number
  ge('colfrom').innerHTML=col.substr(col.length-5,5);          // trim +
it and display
  col='0000'+Math.floor((Math.floor(((fs/2)+main.scrollLeft)/fs)+Math.+
floor((Math.ceil(main.style.width.replace('px',''))+ss)/fs)));
  ge('colto').innerHTML=col.substr(col.length-5,5);            // trim +
and display the rightmost column number
  ge('leftarea').scrollTop=main.scrollTop;                     // +
scroll the left area in sync with the main area
  gs('topofdata').left=main.scrollLeft+'px';                   // +
reposition the top of data bar
  gs('bottomofdata').left=main.scrollLeft+'px';                // +
reposition the bottom of data bar
  }
//]]>
</script>
</body>
</html>
*/

get_ispf_css:
  out = ''

  do i = sigl + 3 while pos('*' || '/', sourceline(i)) = 0
    l = strip(left(sourceline(i), 72), 'T')

    if pos('"FonT"', l) \= 0 then
      do
        parse value l with pre '"FonT"' post
        l = pre'"'htmlfont'"'post
      end

    if right(l, 1) = '+' then
      out = out || substr(l, 1, length(l) - 1)
    else
      out = out || l || !br
  end
return out

/***********************************************************************
* MONITOR:                                                             *
*                                                                      *
* Display progress/status messages                                     *
***********************************************************************/
monitor:
  parse value data with zwinttl ',' text

  if sysvar('SYSENV') = 'BACK' then
    do
      say text
      return 0
    end

  content = ' 'text
  shadow  = copies('W', 77)

  "ispexec control display lock"
  "ispexec addpop  row(14) column(1)"
  "ispexec display panel(monpanel)"
  "ispexec control display restore"

  zwinttl = ''
return 0

/***********************************************************************
* GET_OPTIONS:                                                         *
*                                                                      *
* This procedure gets the output options for the various EHIxxx macros *
***********************************************************************/
get_options:
  parse value data with sep ',' macro

  /*********************************************************************
  * Set up defaults                                                    *
  *********************************************************************/
  viewhtml = 'YES'        /* View html output after generating?       */
  xferwsa  = 'NO'         /* Transfer html to PC via ISPF WSA?        */
  startff  = 'NO'         /* Start browser associated with .html?     */
  htmltype = 'ISPF'       /* Reproduce very fancy ISPF Edit format    */
  htmltype = 'STD'        /* Plain HTML                               */
  htmlfont = 'Courier New'/* Default font                             */
  progress = 100          /* Number of lines between 'Say' statements */

  pcdir    = 'c:\temp'    /* PC directory where html should be stored */

  /*********************************************************************
  * Override defaults for specific macros
  *********************************************************************/
  select
    when macro = 'EHIASM' then
      do
        progress = 100
      end

    when macro = 'EHICOBOL' then
      do
        progress = 500
      end

    when macro = 'EHIJCL' then
      do
        progress = 25
      end

    when macro = 'EHINONE' then
      do
        progress = 500
      end

    when macro = 'EHIPLI' then
      do
        progress = 500
      end

    when macro = 'EHIREXX' then
      do
        progress = 100
      end

    when macro = 'EHISUPC' then
      do
        progress = 1000
      end

    otherwise nop
  end

  "ispexec vget (ehixmit) shared"
/*!*/
  if rc = 0 then
    do
      popup    = 0
      progress = 0
      viewhtml = 'NO'
    end
/*!*/

  if popup          &,
     t_rex  = 'TSO' &,
     aspace = 'ISPF' then
    do
      call load_dynlib

      "ispexec libdef ispplib library id("dynlib") stack"
      "ispexec addpop row(10) column(-1)"
      "ispexec vget (ipaddr) profile"

      do until rc \= 0
        "ispexec display panel("moi")"
      end

      "ispexec vput (ipaddr) profile"
      "ispexec rempop"
    end

return viewhtml || sep ||,
       xferwsa  || sep ||,
       startff  || sep ||,
       htmltype || sep ||,
       progress || sep ||,
       pcdir    || sep ||,
       htmlfont || sep ||,
       ipaddr   || sep

/***********************************************************************
* LOAD_DYNLIB:                                                         *
*                                                                      *
* This procedure loads the via EPANQ generated panel, message and      *
* skeleton code into a library. Note that there is no reason to use    *
* different libraries for any of these objects, as long as they are    *
* named differently|                                                   *
***********************************************************************/
load_dynlib:
dynlib = 'dyn'random(99999)
alloc  = "alloc fi("dynlib") rtdsn(sysdsname) "   ||,
                   "lrecl(80) blksize(0) dir(5) " ||,
                   "new delete reuse "            ||,
                   "space(1,1)"
rc = bpxwdyn(alloc)

if rc = 0 then
  ispdyn = sysdsname
else
  ispdyn = 'NOT FOUND'

"newstack"

member = moi

queue ')attr default(' ||,
      x2c(010203) ||,
      ')'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '/' || '*              (C) Copyright Robert AH Prins, 2007-' ||,
      '2016              *' || '/'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '/' || '*  ------------------------------------------------' ||,
      '----------------  *' || '/'
queue '/' || '* | Date       | By   | Remarks                    ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* |            |      |                            ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/* | 2016-11-18 | RAHP | - remove ''EDIT'' html option    ' ||,
      '            | */'
queue '/* |            |      | - always use ''html'' as extensio' ||,
      'n           | */'
queue '/' || '* |            |      | - only "Courier New" font  ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* | 2012-06-25 | RAHP | Add IP address             ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/* | 2009-07-02 | RAHP | - make short CSS ''em'' colors th' ||,
      'e default   | */'
queue '/' || '* |            |      | - allow progress interval u' ||,
      'p to 5000       | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* | 2009-04-01 | RAHP | Allow selection of font    ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* | 2009-02-09 | RAHP | Allow other extension      ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* | 2007-09-24 | RAHP | Initial version            ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '/' || '* Panel - EHISUPP                                  ' ||,
      '                  *' || '/'
queue '/' || '*                                                  ' ||,
      '                  *' || '/'
queue '/' || '* This panel is used by the EHIxxxx edit macros to ' ||,
      'display a number  *' || '/'
queue '/' || '* of user modifyable settings, such as the option t' ||,
      'o transfer the    *' || '/'
queue '/' || '* generated HTML to the PC using the WSA, to displa' ||,
      'y it, to select   *' || '/'
queue '/' || '* the format of the output, to set the progress ind' ||,
      'icator and to     *' || '/'
queue '/' || '* set the PC directory.                            ' ||,
      '                  *' || '/'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue ' 04 type(absl) ge(on)'
queue ' 05 type(pt)'
queue ' 08 type(ch)'
queue ' 09 type(fp)'
queue ' 0a type(nt)'
queue ' 0c type(nt) skip(on)'
queue ' 0b type(ab)'
queue ' 11 type(sac)'
queue ' 13 type(nef) padc(user)'
queue ' 19 type(dt)'
queue ' 22 type(wasl) skip(on) ge(on)'
queue ' 26 type(nef) caps(on) padc(user)'
queue ' 27 area(scrl) extend(on)'
queue ' 28 type(grpbox)'
queue ' 29 type(cef) padc(user) ckbox(on)'
queue ' 2a type(nef) caps(off) padc(user)'
queue ' '
queue ')body window(77,14) expand(||)'
queue x2c(05) ||,
      ' | |' moi '- Processing defaults for' macro '| |'
queue x2c(09) ||,
      'Command ===>' ||,
      x2c(26) ||,
      'zcmd                                                      ' ||,
      '    ' ||,
      x2c(0A) ||,
      ''
queue ' '
queue x2c(09) ||,
      'View HTML  . . . .' ||,
      x2c(26) ||,
      'z  ' ||,
      x2c(0A11) ||,
      '     (Yes/No)'
queue x2c(09) ||,
      'HTML type  . . . .' ||,
      x2c(26) ||,
      'z   ' ||,
      x2c(0A11) ||,
      '    (STD/ISPF)'
queue ' '
queue x2c(09) ||,
      'Progress . . . . .' ||,
      x2c(26) ||,
      'z   ' ||,
      x2c(0A11) ||,
      '    (Progress indicator)'
queue ' '
queue x2c(09) ||,
      'xfer WSA . . . . .' ||,
      x2c(26) ||,
      'z  ' ||,
      x2c(0A11) ||,
      '     (Yes/No)'
queue x2c(09) ||,
      'IP address . . . .' ||,
      x2c(26) ||,
      'z              ' ||,
      x2c(0A) ||,
      ''
queue x2c(09) ||,
      'PC directory . . .' ||,
      x2c(2A) ||,
      'z                                                       ' ||,
      x2c(0A) ||,
      ''
queue x2c(09) ||,
      'Start browser  . .' ||,
      x2c(26) ||,
      'z  ' ||,
      x2c(0A11) ||,
      '     (Yes/No)'
queue ' '
queue x2c(09) ||,
      'Press' ||,
      x2c(05) ||,
      'ENTER' ||,
      x2c(09) ||,
      'to proceed or' ||,
      x2c(05) ||,
      'END' ||,
      x2c(09) ||,
      'to accept defaults'
queue ')init'
queue '  .zvars = ''(viewhtml +'
queue '             htmltype +'
queue '             progress +'
queue '             xferwsa +'
queue '             ipaddr +'
queue '             pcdir +'
queue '             startff)'''
queue ' '
queue '  &rtn = PFK(RETURN)'
queue ' '
queue '  if (&viewhtml = &z)'
queue '    &viewhtml = ''Yes'''
queue '  if (&htmltype = &z)'
queue '    &htmltype = ''STD'''
queue ' '
queue '  if (&progress = &z)'
queue '    &progress = 100'
queue ' '
queue '  if (&xferwsa = &z)'
queue '    &xferwsa  = ''No'''
queue '  if (&pcdir = &z)'
queue '    &pcdir    = ''c:\temp'''
queue '  if (&startff = &z)'
queue '    &startff  = ''No'''
queue ' '
queue '  &htmlfont = ''Courier New'''
queue ')proc'
queue '  &pfkey = .pfkey'
queue ' '
queue '  if (&rtn ^= &z)'
queue '    if (&pfkey = &rtn)'
queue '      .resp = END'
queue '      &resp = end'
queue ' '
queue '  if (.resp = END)'
queue '    &resp = END'
queue ' '
queue '  if (.resp ^= END)'
queue '    &viewhtml = trans(trunc(&viewhtml, 1)'
queue '                      N,NO'
queue '                      *,YES)'
queue '    ver(&viewhtml nb list ''YES'' ''NO'')'
queue ' '
queue '    &htmltype = trans(trunc(&htmltype, 1)'
queue '                      I,ISPF'
queue '                      *,STD)'
queue '    ver(&htmltype nb list STD,ISPF)'
queue ' '
queue '    ver(&progress nb num)'
queue ' '
queue '    if (&progress = 0)'
queue '      &progress = 100'
queue ' '
queue '    if (&progress > 5000)'
queue '      &progress = 5000'
queue ' '
queue '    &xferwsa = trans(trunc(&xferwsa, 1)'
queue '                     Y,YES'
queue '                     *,NO)'
queue '    ver(&xferwsa  nb list ''YES'' ''NO'')'
queue ' '
queue '    if (&xferwsa = ''YES'')'
queue '      ver(&ipaddr nb ipaddr4)'
queue ' '
queue '    if (&pcdir = &z)'
queue '      &pcdir = ''c:\temp'''
queue ' '
queue '    &startff = trans(trunc(&startff, 1)'
queue '                     Y,YES'
queue '                     *,NO)'
queue '    ver(&startff  nb list ''YES'' ''NO'')'
queue ' '
queue '    refresh(*)'
queue ' '
queue '    if (.msg ^= '' '')'
queue '      .resp = ENTER'
queue ' '
queue '    if (.msg = '' '')'
queue '      .resp = END'
queue '      &resp = OK'
queue ')end'

call put_object

"newstack"

member = 'MONPANEL'

queue ')attr'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '/' || '*  ------------------------------------------------' ||,
      '----------------  *' || '/'
queue '/' || '* | Date       | By   | Remarks                    ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* |            |      |                            ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '* | 2009-07-27 | RAHP | Initial version            ' ||,
      '                | *' || '/'
queue '/' || '* |------------+------+----------------------------' ||,
      '----------------| *' || '/'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '/' || '* Panel - MONPANEL                                 ' ||,
      '                  *' || '/'
queue '/' || '*                                                  ' ||,
      '                  *' || '/'
queue '/' || '* This is a one-line panel that can be used to send' ||,
      ' status messages  *' || '/'
queue '/' || '* to the user and receive limited input.           ' ||,
      '                  *' || '/'
queue '/' || '***************************************************' ||,
      '*******************' || '/'
queue '  | area(dynamic) scroll(on) extend(on)'
queue '  W type(char) color(white)'
queue ')body window(77,1)'
queue '|content,shadow                                           ' ||,
      '                  |'
queue ')init'
queue ')reinit'
queue '  refresh(*)'
queue ')proc'
queue '  &cur = .cursor'
queue '  &pos = .csrpos'
queue '  &pfp = .pfkey'
queue ')end'

put_object:
  tfil = 'tfil'random(9999)

  "alloc f("tfil") da('"ispdyn"("member")') shr reu"
  "execio" queued() "diskw "tfil" (finis"
  "free f("tfil")"

  "delstack"
return