library TestEx;

uses
  SysUtils,
  Windows,
  Classes,
  Graphics,
  CommCtrl,
  Forms,
  IBEIntfEx;

type
  TConvertKind = (ckKeywordsToLowerCase, ckKeywordsToUppercase, ckIdentifiersToLowerCase, ckIdentifiersToUpperCase);

{$R *.RES}


procedure ConvertCase(Intf: TIBEInterfaceEx; ConvertKind : TConvertKind);
var
  s, sKeywords, ss : string;
  CE : hCodeEditor;
  TL : hTokenList;
  Keywords : TStrings;
  i, iCount, KWIndex : integer;
  PTI : PibeiTokenInfo;
begin
  CE := Intf.GetCurrentCodeEditor;
  if not Assigned(CE) then
    Exit;

  s := Intf.GetCodeEditorText(CE);
  if Trim(s) = '' then
    Exit;

  sKeywords := Intf.GetCodeEditorKeywords(CE);

  Screen.Cursor := -11;
  TL := Intf.CreateTokenList(PChar(s));
  try
    Keywords := TStringList.Create;
    try
      Keywords.Text := sKeywords;

      iCount := Intf.GetListCount(TL);
      s := '';
      for i := 0 to pred(iCount) do
      begin
        PTI := Intf.GetTokenInfo(TL,i);
        if PTI.TokenKind = itkIdentifier then
        begin
          KWIndex := Keywords.IndexOf(PTI.Token);
          if (KWIndex <> -1) then
          begin
            case ConvertKind of
              ckKeywordsToLowerCase : s := s + LowerCase(PTI.Token);
              ckKeywordsToUpperCase : s := s + UpperCase(PTI.Token);
            else
              s := s + PTI.Token;
            end;
          end
          else
          begin
            case ConvertKind of
              ckIdentifiersToLowerCase : s := s + LowerCase(PTI.Token);
              ckIdentifiersToUpperCase : s := s + UpperCase(PTI.Token);
            else
              s := s + PTI.Token;
            end;
          end
        end
        else
          s := s + PTI.Token;
      end;
      Intf.SetCodeEditorText(CE, PChar(TrimRight(s)));
    finally
      Keywords.Free;
    end;
  finally
    Intf.FreeTokenList(TL);
    Screen.Cursor := 0;
  end;
end;

function plugin_update_action_ex(Intf: TIBEInterfaceEx) : integer; stdcall;
begin
  Result := Integer(Intf.GetCurrentCodeEditor <> nil);
end;


procedure uppercase_keywords(Intf: TIBEInterfaceEx); stdcall;
begin
  ConvertCase(Intf,ckKeywordsToUpperCase);
end;

procedure uppercase_identifiers(Intf: TIBEInterfaceEx); stdcall;
begin
  ConvertCase(Intf,ckIdentifiersToUpperCase);
end;

procedure lowercase_keywords(Intf: TIBEInterfaceEx); stdcall;
begin
  ConvertCase(Intf,ckKeywordsToLowerCase);
end;

procedure lowercase_identifiers(Intf: TIBEInterfaceEx); stdcall;
begin
  ConvertCase(Intf,ckIdentifiersToLowerCase);
end;

procedure get_plugin_info_ex(Intf: TIBEInterfaceEx; PluginInfo: pointer); stdcall;
var
  BMP : TBitmap;
  Index : integer;
begin
  BMP := TBitmap.Create;
  try
    BMP.LoadFromResourceName(hInstance,'BITMAP_2');
    Index := ImageList_Add(Intf.MainImageList,HBitmap(BMP.Handle),0);
  finally
    BMP.Free;
  end;

  with PIBEPluginInfoEx(PluginInfo)^ do
  begin
    PluginName := 'Just a test plugin';
    Description := 'No description';
    PlaceMenu := '2;11';
    MenuStructure := PChar('CConvert Identifiers/Keywords|B|Uplugin_update_action_ex|I' + IntToStr(Index) + #13 +
                           '    CConvert Keywords|' + #13 +
                           '       CTo UpperCase|Euppercase_keywords|SCtrl+Shift+Up' + #13 +
                           '       CTo LowerCase|Elowercase_keywords|SCtrl+Shift+Down' + #13 +
                           '    CConvert Identifiers|' + #13 +
                           '       CTo UpperCase|Euppercase_identifiers' + #13 +
                           '       CTo LowerCase|Elowercase_identifiers');
  end;
end;

exports
  get_plugin_info_ex,
  plugin_update_action_ex,
  uppercase_identifiers,
  lowercase_identifiers,
  uppercase_keywords,
  lowercase_keywords;

end.

