/* instemacs.cmd -- create program icons for emacs and emacsclient
                    Copyright (c) 1993 by Harald B”geholz

This file is part of GNU Emacs.

GNU Emacs 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 2, or (at your option)
any later version.

GNU Emacs 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 GNU Emacs; see the file COPYING.  If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.     */

parse arg args

call RxFuncAdd "SysLoadFuncs", "RexxUtil", "SysLoadFuncs"
call SysLoadFuncs

say "instemacs.cmd 1.0 (c) 1993 by Harald B”geholz"

OptionStartup=0
OptionInstall=0
OptionAssociate=0
OptionKeepvio=0
OptionMakedefault=0

do while args \== ""
  parse upper var args arg args

  select
    when arg="INSTALL" then
      OptionInstall=1
    when arg="STARTUP" then
      OptionStartup=1
    when arg="KEEPVIO" then
      OptionKeepvio=1
    when arg="ASSOCIATE" then
      OptionAssociate=1
    when arg="MAKEDEFAULT" then
      OptionMakedefault=1
    otherwise
      do
        say "*** Unknown option:" arg
        call Usage
      end
  end

end

if \OptionInstall then 
do
  say "*** Nothing to do!"
  call Usage
end

if OptionMakedefault then OptionAssociate=1

if OptionKeepVio then
  MinimizeEmacs=";PROGTYPE=WINDOWABLEVIO;MINIMIZED=YES"
else
  MinimizeEmacs=";PROGTYPE=PM"

if OptionAssociate then
do
  call FindAssoc
  Associate=MakeAssocString()
end
else
  Associate=""


emacsfspec=LocateEmacs("emacs.exe",1)
pmemacsfspec=LocateEmacs("pmemacs.exe",1)
emacsclientfspec=LocateEmacs("emacsclient.exe",0)

/* create a folder for the new objects */
call SysCreateObject "WPFolder", "New Things", "<WP_DESKTOP>", ,
     "OBJECTID=<HWB_NEWTHINGS>", "fail"

/* create the program Object for Emacs */
EmacsOk=SysCreateObject("WPProgram", "Emacs", "<HWB_NEWTHINGS>", ,
     "EXENAME="emacsfspec";PARAMETERS=-d %*"MinimizeEmacs";"||,
     "ICONRESOURCE=1,"pmemacsfspec";OBJECTID=<HWB_GNUEMACS>", "update")
if EmacsOk then
  say "Program object for Emacs created successfully."
else
  say "*** Could not create program object for Emacs."

/* create the program Object for Emacsclient */
if emacsclientfspec \== "" then
  EmacsclientOk=SysCreateObject("WPProgram", "Emacsclient", "<HWB_NEWTHINGS>",,
       "EXENAME="emacsclientfspec";PARAMETERS=-w %*;MINIMIZED=YES;"||,
       "ICONRESOURCE=1,"pmemacsfspec||Associate|| ,
       ";OBJECTID=<HWB_GNUEMACSCLIENT>", "update")
else
  EmacsclientOk=0

if EmacsclientOk then
  say "Program object for Emacsclient created successfully."
else
  say "*** Could not create program object for Emacsclient."

if OptionStartup then
do
  ShadowOk=SysCreateObject("WPShadow", "Emacs", "<WP_START>", ,
       "SHADOWID=<HWB_GNUEMACS>", "update")
  if ShadowOk then
    say "Shadow object for Emacs created successfully."
  else
    say "*** Could not create shadow object for Emacs."
end

if OptionMakedefault then
do
  if EmacsclientOk then
    call Makedefault
  else
    say "*** Sorry, can't make Emacsclient the default editor"
end

signal on syntax /* the following call will fail under OS/2 2.0, so trap it */

call SysSetObjectData "<HWB_NEWTHINGS>", "OPEN=DEFAULT"

exit

SYNTAX:
say "You can find the new objects in the folder 'New Things' on your desktop."
exit

/* ---------------------------------------------------------------------- */
LocateEmacs: procedure

parse arg fname required

fspec=SysSearchPath("EMACSPATH", fname)
if fspec=="" then fspec=SysSearchPath("PATH", fname)
if fspec=="" then
do
  say "*** Can't locate "fname". Be sure to have set your PATH or EMACSPATH"
  say "    variables correctly!"
  if required then
    exit
end
else say "Found "fspec"."

return fspec

/* ---------------------------------------------------------------------- */
FindAssoc: procedure expose key. assoc.

key.1="PMWP_ASSOC_TYPE"
assoc.1="Plain Text"
key.2="PMWP_ASSOC_TYPE"
assoc.2="OS/2 Command File"
key.3="PMWP_ASSOC_TYPE"
assoc.3="DOS Command File"
key.4="PMWP_ASSOC_FILTER"
assoc.4="*.DOC"
key.5="PMWP_ASSOC_FILTER"
assoc.5="*.TXT"
key.0=5

/* Find the object handle of the System Editor */
SEHandleBin=SysIni(, "PM_Workplace:Location", "<WP_SYSED>")
if SEHandleBin="ERROR:" then
  return                            /* fail silently if this doesn't work */

/* convert to 0-terminated decimal string */
SEHandle=c2d(reverse(SEHandleBin)) || "00"x

IniApp.1="PMWP_ASSOC_TYPE"
IniApp.2="PMWP_ASSOC_FILTER"

do i=1 to 2
  call SysIni , IniApp.i, "All:", "IniKeys"
  if Result \= "ERROR:" then
  do
    do j=1 to IniKeys.0
      Handles=SysIni(, IniApp.i, IniKeys.j)
      if Handles \= "ERROR:" then
      do
        if pos(SEHandle, Handles) > 0 then
        do
          Found=0
          do k=1 to key.0
            if (key.k == IniApp.i) & (assoc.k == IniKeys.j) then
            do
              Found=1
              leave k
            end
          end
          if \Found then
          do
            key.0=key.0+1
            new=key.0
            key.new=IniApp.i
            assoc.new=IniKeys.j
          end
        end
      end
    end
  end
end

return

/* ---------------------------------------------------------------------- */
MakeAssocString: procedure expose key. assoc.

AssocTypes=""
do i=1 to key.0
  if key.i=="PMWP_ASSOC_TYPE" then
    AssocTypes=AssocTypes","assoc.i
end
AssocTypes=substr(AssocTypes,2)

AssocFilters=""
do i=1 to key.0
  if key.i=="PMWP_ASSOC_FILTER" then
    AssocFilters=AssocFilters","assoc.i
end
AssocFilters=substr(AssocFilters,2)

return ";ASSOCTYPE="AssocTypes";ASSOCFILTER="AssocFilters


/* ---------------------------------------------------------------------- */
Makedefault: procedure expose key. assoc.
/* WARNING: This procedure changes Workplace Shell associations in an 
            undocumented way by directly manipulating OS2.INI.
            This only works by magic.
            Use at your own risk.                                         */

ECHandleBin="ERROR:"
do i=1 to 10 until ECHandleBin \== "ERROR:"
/* Find the object handle of Emacsclient */
  ECHandleBin=SysIni(, "PM_Workplace:Location", "<HWB_GNUEMACSCLIENT>")
  if ECHandleBin=="ERROR:" then
  do
    say "Waiting for the Workplace Shell. Stay tuned..."
    call SysSleep i
  end
end
if ECHandleBin=="ERROR:" then
do
  say "*** Can't determine object handle for <HWB_GNUEMACSCLIENT>"
  exit
end

/* convert to 0-terminated decimal string */
ECHandle=c2d(reverse(ECHandleBin)) || "00"x

do i=1 to key.0
  AssocHandles=GetIni(key.i, assoc.i)
  ECPos=pos(ECHandle, AssocHandles)
  if ECPos=0 then
  do
    say "*** Can't find association of "assoc.i" with Emacsclient."
    exit
  end
  NewHandles=ECHandle||left(AssocHandles,ECPos-1)||,
      substr(AssocHandles, ECPos+Length(ECHandle))
  if SysIni(, key.i, assoc.i, NewHandles)="ERROR:" then
  do
    say "*** Can't store new value for "key.i","assoc.i" in OS2.INI"
    exit
  end
end

return 1

/* ---------------------------------------------------------------------- */
GetIni: procedure        /* get a value from OS2.INI and check for errors */

parse arg app, key

IniString=SysIni(, app, key)
if IniString=="ERROR:" then
do
  say "*** Can't find "app","key" in OS2.INI."
  exit
end

return IniString

/* ---------------------------------------------------------------------- */
Usage: procedure

say "Usage: instemacs install [options...]"
say "Options:"
say "  startup      create a shadow of Emacs in your startup folder"
say "  keepvio      don't start the non-PM part of Emacs as a PM program"
say "  associate    associate emacsclient with plain text files etc."
say "  makedefault  make Emacsclient the OS/2 default editor"
exit
