unit uFarCtags;
{$INCLUDE 'FarCtags.inc'}

interface

implementation

uses
  Windows, SysUtils, Classes,
  {$INCLUDE 'DelphiFarUnits.inc'} ,
  {$IFDEF DEBUG_LOGS} uLog, {$ENDIF}
  uSystem,
  uOptions, uOptionsUI,
  uMessages, uEditorTasks, uFarCtagsConsts;

type
  TFarCtagsPlugin = class(TFarPlugin)
  private
    fPluginInfoAvailable: boolean;
    fPluginInfo: TPluginInfo;
    fOptions: TOptions;
    function GetOptions: TOptions;
  protected
    function PluginID: TGUID; override;
    function GetPluginTitle(out Description, Author: string): string; override;
    function GetPluginInfo(out Info: TPluginInfo): boolean; override;
    function Execute(OpenFrom: DWORD; GUID: PGUID; Data: TIntPtr): THandle; override;
    function GetCommonString(ID: TFarPlugin.TCommonString): string; override;
    function PluginConfig(GUID: PGUID; MenuItem: TIntPtr): boolean; override;
    function ProcessMacroCall(const Params: array of Variant): boolean;
    procedure DoLog(const Msg: string); override;
    procedure RefreshOptions;
    property Options: TOptions read GetOptions;
  public
    constructor Create;
    destructor Destroy; override;
  end;

const
  PLUGIN_TITLE = 'FarCtags';
  PLUGIN_DESCRIPTION = 'FAR Ctags';
  PLUGIN_AUTHOR = 'Pepak, https://www.pepak.net';

{ TFarCtagsPlugin }

constructor TFarCtagsPlugin.Create;
begin
  inherited;
  fPluginInfoAvailable := False;
  fOptions := nil;
end;

destructor TFarCtagsPlugin.Destroy;
begin
  FreeAndNil(fOptions);
  if fPluginInfoAvailable then begin
    DeletePluginInfo(fPluginInfo);
  end;
  inherited;
end;

procedure TFarCtagsPlugin.DoLog(const Msg: string);
begin
  {$IFDEF DEBUG_LOGS}
  uLog.Log(Msg);
  {$ENDIF}
end;

function TFarCtagsPlugin.Execute(OpenFrom: DWORD; GUID: PGUID; Data: TIntPtr): THandle;
var
  Tasks: TEditorTasks;
begin
  Result := {$IFDEF FAR3_UP} 0 {$ELSE} INVALID_HANDLE_VALUE {$ENDIF} ;
  RefreshOptions;
  {$IFDEF FAR3_UP}
  if OpenFrom = OPEN_FROMMACRO_ then
  begin
    if ProcessMacroCall(TFarMacro.MacroParamsToDelphi(Data)) then
      Result := 1;
  end;
  {$ENDIF}
  if OpenFrom = OPEN_EDITOR then begin
    Tasks := TEditorTasks.Create;
    try
      Tasks.EditorID := -1;
      Tasks.Execute;
    finally
      FreeAndNil(Tasks);
    end;
  end;
end;

function TFarCtagsPlugin.GetCommonString(ID: TFarPlugin.TCommonString): string;
begin
  case ID of
    TFarPlugin.TCommonString.MTitle:
      Result := GetMsg(MTitle);
    TFarPlugin.TCommonString.MExceptionOccurredIn:
      Result := GetMsg(MExceptionOccurredIn);
    TFarPlugin.TCommonString.MOk:
      Result := GetMsg(MOk);
    TFarPlugin.TCommonString.MCancel:
      Result := GetMsg(MCancel);
    TFarPlugin.TCommonString.MYes:
      Result := GetMsg(MYes);
    TFarPlugin.TCommonString.MNo:
      Result := GetMsg(MNo);
    else
      Result := inherited GetCommonString(ID);
  end;
end;

function TFarCtagsPlugin.GetOptions: TOptions;
begin
  if fOptions = nil then
  begin
    fOptions := TOptions.Create;
    fOptions.Load;
  end;
  Result := fOptions;
end;

function TFarCtagsPlugin.GetPluginInfo(out Info: TPluginInfo): boolean;
var
  fMainMenu: TFarPlugin.TFarPluginMenu;
  fConfigMenu: TFarPlugin.TFarPluginMenu;
  fDiskMenu: TFarPlugin.TFarPluginMenu;
begin
  if not fPluginInfoAvailable then begin
    SetLength(fMainMenu, 1);
    fMainMenu[0].Title := GetMsg(MTitle);
    fMainMenu[0].ID := MENU_PANEL_GUID;
    SetLength(fConfigMenu, 1);
    fConfigMenu[0].Title := GetMsg(MTitle);
    fConfigMenu[0].ID := MENU_OPTIONS_GUID;
    SetLength(fDiskMenu, 0);
    Self.fPluginInfo := CreatePluginInfo(
      PF_EDITOR or PF_DISABLEPANELS,
      fMainMenu, fConfigMenu, fDiskMenu,
      ''
    );
    fPluginInfoAvailable := True;
  end;
  Info := Self.fPluginInfo;
  Result := True;
end;

function TFarCtagsPlugin.GetPluginTitle(out Description, Author: string): string;
begin
  Result := PLUGIN_TITLE;
  Description := PLUGIN_DESCRIPTION;
  Author := PLUGIN_AUTHOR;
end;

function TFarCtagsPlugin.PluginConfig(GUID: PGUID; MenuItem: TIntPtr): boolean;
var
  Dialog: TOptionsDialog;
begin
  Result := False;
  RefreshOptions;
  Dialog := TOptionsDialog.Create;
  try
    Dialog.Options := Options;
    if Dialog.Execute then
    begin
      Options.Save;
      Result := True;
    end;
  finally
    FreeAndNil(Dialog);
  end;
end;

function TFarCtagsPlugin.PluginID: TGUID;
begin
  Result := PLUGIN_GUID;
end;

function TFarCtagsPlugin.ProcessMacroCall(const Params: array of Variant): boolean;
var
  FunctionName: string;
  Tasks: TEditorTasks;
begin
  Result := False;
  if Length(Params) > 0 then
  begin
    FunctionName := Params[0];
    if FunctionName = 'execute' then
    begin
      Tasks := TEditorTasks.Create;
      try
        Tasks.EditorID := -1;
        if Tasks.Execute then
          Result := True;
      finally
        FreeAndNil(Tasks);
      end;
      Exit;
    end;
  end;
end;

procedure TFarCtagsPlugin.RefreshOptions;
begin
  FreeAndNil(fOptions);
end;

initialization
  TFarPlugin.InitInstance(TFarCtagsPlugin.Create);

end.
