////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2001-2024 DaqGroup daqgroup@mail.ru under MIT license        //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// This file is part of the CRW-DAQ project by DaqGroup - addon user program. //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Purpose:                                                                   //
// Create shell link - *.lnk or *.desktop.                                    //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// History:                                                                   //
// 20241022 - Sample created by A.K.                                          //
// 20241220 - First release by A.K.                                           //
////////////////////////////////////////////////////////////////////////////////

program crtlnk;

{$I _crw_sysdef.inc}

{$I _crw_sysmode.inc}

{$R *.res}

uses
 //////////////////////////////////////////////////////
 {$I _crw_uses_first.inc} // NB: MUST BE FIRST USES !!!
 //////////////////////////////////////////////////////
 sysutils, classes, math, graphics, interfaces, forms,
 _crw_alloc, _crw_cmdargs, _crw_environ, _crw_proc, _crw_rtc, _crw_ef,
 _crw_str, _crw_utf8, _crw_fio, _crw_fifo, _crw_hl, _crw_ee, _crw_colors,
 _crw_xdg;

function GetVersionInfo(const Name:LongString):LongString;
begin
 Result:=CookieScan(GetFileVersionInfoAsText(ProgName),Name);
end;
function DotEnding(const S:LongString):LongString;
const dot='.';
begin
 Result:=S;
 if (Result<>'') then if (StrFetch(Result,Length(Result))<>dot) then Result:=Result+dot;
end;
procedure PrintVersionInfo(const Fallback:LongString);
begin
 if not IsEmptyStr(GetVersionInfo('ProductName')) then begin
  writeln(DotEnding(GetVersionInfo('ProductName')+' version '+GetVersionInfo('ProductVersion')));
  writeln(DotEnding(GetVersionInfo('FileDescription')));
  writeln(DotEnding(GetVersionInfo('LegalCopyright')));
 end else begin
  writeln(Fallback);
 end;
end;
function HelpScreen:LongString;
begin
 Result:='Usage:'+EOL
        +' mkshlnk [-Options] [Parameters]'+EOL
        +'Parameters:'+EOL
        +' target           - set target file name '+AdaptLnkFileName('*.lnk')+EOL
        +'Options (common):'+EOL
        +'  --version            - print version'+EOL
        +'  -h,--help            - print help screen'+EOL
        +'Options (XDG):'+EOL
        +'  --type s             - set desktop entry type: {Application,Link,Directory}'+EOL
        +'  --exec s             - set command line (c) to execute'+EOL
        +'  --version s          - set uses version of XDG specification'+EOL
        +'  --name l             - set application name for Shell Link'+EOL
        +'  --genericname l      - set application generic name'+EOL
        +'  --nodisplay b        - set flag "no display in Menu"'+EOL
        +'  --comment s          - set tooltip for the entry'+EOL
        +'  --icon s             - set icon name to display in file manager'+EOL
        +'  --hidden b           - set flag "hide this desktop entry"'+EOL
        +'  --onlyshowin l       - set list of environs where to show entry'+EOL
        +'  --notshowin l        - set list of environs where not show entry'+EOL
        +'  --dbusactivatable b  - set flag "DBUS activation supported"'+EOL
        +'  --tryexec s          - set file to check before Exec'+EOL
        +'  --path s             - set working directory to run program in'+EOL
        +'  --terminal b         - set flag "runs in a terminal window"'+EOL
        +'  --actions s          - set list of application actions'+EOL
        +'  --mimetype s         - set MIME type(s) supported by application'+EOL
        +'  --categories s       - set list of categories for menus'+EOL
        +'  --keywords l         - set list of keywords'+EOL
        +'  --startupnotify b    - set flag of startup notifications'+EOL
        +'  --startupwmclass s   - set startup WM class'+EOL
        +'  --url s              - set URL to access if entry Type is Link'+EOL
        +'Options (Win):'+EOL
        +'  --targetpath s       - set application file path'+EOL
        +'  --arguments s        - set command line arguments'+EOL
        +'  --iconlocation s     - set icon location'+EOL
        +'  --description s      - set comment'+EOL
        +'  --workingdirectory s - set working directory to run program in'+EOL
        +'  --hotkey s           - set hotkey'+EOL
        +'  --showcmd i          - set ShowWindow command 0..10'+EOL
        +'  --windowstyle i      - set ShowWindow command 0..10'+EOL
        ;
end;

procedure ExecuteMakeShellLink;
var Content,TargetLnk,args,exe,opt,sn,sv,line:LongString; narg,wc:Integer;
begin
 narg:=0;
 line:='';
 Content:='';
 TargetLnk:='';
 args:=GetCommandLine;
 exe:=ExtractPhrase(1,args,JustBlanks);
 args:=SkipPhrases(1,args,JustBlanks);
 wc:=WordCount(args,JustBlanks);
 if (wc=1) then begin
  opt:=ExtractWord(1,args,JustBlanks);
  if IsOption(opt,'--version') then begin
   PrintVersionInfo('mkshlnk - make shell link utility.');
   Exit;
  end;
  if IsOption(opt,'-h') or IsOption(opt,'-help','--help') then begin
   PrintVersionInfo('mkshlnk - make shell link utility.');
   write(HelpScreen);
   Exit;
  end;
 end;
 while IsNonEmptyStr(args) do begin
  inc(narg);
  if IsOption(args) then begin
   sn:=Trim(ExtractPhrase(1,args,JustBlanks));
   sv:=Trim(ExtractPhrase(2,args,JustBlanks));
   while IsOption(sn) do Delete(sn,1,1);
   if IsNonEmptyStr(sn) and IsNonEmptyStr(sv)
   then Content:=Content+Trim(sn+'='+sv)+EOL;
   args:=SkipPhrases(1,args,JustBlanks);
  end else begin
   if IsEmptyStr(TargetLnk) then begin
    sn:=Trim(ExtractPhrase(1,args,JustBlanks));
    sn:=AdaptLnkFileName(sn);
    sn:=UnifyFileAlias(sn,ua_FileDefLow);
    TargetLnk:=sn;
   end else begin
    sn:=Trim(ExtractPhrase(1,args,JustBlanks));
    raise EMakeShellLink.Create('Unexpected argument: '+sn+'.');
   end;
  end;
  args:=SkipPhrases(1,args,JustBlanks);
 end;
 if IsEmptyStr(Content) then
 if (GetFileType(Input)=FILE_TYPE_PIPE) then begin
  while not eof(Input) do begin
   System.Readln(Input,line);
   if (IoResult<>0) then raise EMakeShellLink.Create('Pipe read error.');
   if IsNonEmptyStr(line) then Content:=Content+Trim(line)+EOL;
  end;
 end;
 FakeNOP(exe);
 if IsEmptyStr(TargetLnk)
 then raise EMakeShellLink.Create('Empty target filename.');
 if not MakeShellLinkFromText(TargetLnk,Content)
 then raise EMakeShellLink.Create('Fail creating shell link: '+TargetLnk+'.');
end;

begin
 try
  ExecuteMakeShellLink;
 except
  on E:Exception do begin
   writeln(StdErr,'Error: '+E.Message);
   ExitCode:=1;
  end;
 end;
end.

//////////////
// END OF FILE
//////////////
