unit uBafFmxUtils;

// this code is under the BAF fair use license (BFUL) - https://bafbal.de/index.php?title=Bful
// Some Utils

interface

uses FMX.Forms, System.Math, System.SysUtils, Winapi.Windows, System.UiTypes,
  System.IniFiles, Classes, Fmx.Memo;

procedure BafFormPos2Ini(AForm: TForm; AIni: TCustomIniFile; ASection: string);
procedure BafIni2FormPos(AForm: TForm; AIni: TCustomIniFile; ASection: string;
  ALeft, ATop, AWidth, AHeight: integer);

procedure AddRemovePrefix(APrefix: string; AMemo: TMemo);

implementation

uses dmMain;

procedure BafFormPos2Ini(AForm: TForm; AIni: TCustomIniFile; ASection: string);
begin
  AIni.WriteInteger(ASection, 'Left', AForm.Left);
  AIni.WriteInteger(ASection, 'Top', AForm.Top);
  AIni.WriteInteger(ASection, 'Width', AForm.Width);
  AIni.WriteInteger(ASection, 'Height', AForm.Height);
end;

procedure BafIni2FormPos(AForm: TForm; AIni: TCustomIniFile; ASection: string;
  ALeft, ATop, AWidth, AHeight: integer);
begin
  AForm.Left := AIni.ReadInteger(ASection, 'Left', ALeft);
  AForm.Top := AIni.ReadInteger(ASection, 'Top', ATop);
  AForm.Width := System.Math.Max(AIni.ReadInteger(ASection, 'Width', AWidth), 100);
  AForm.Height := System.Math.Max(AIni.ReadInteger(ASection, 'Height', AHeight), 100);
  if AForm.Left < Screen.DesktopLeft then
    AForm.Left := round(Screen.DesktopLeft);
  if AForm.Top < Screen.DesktopTop then
    AForm.Top := round(Screen.DesktopTop);
//  if (AForm.Left + AForm.Width) > Screen.DesktopRect.Right then
//    AForm.Width := round(Screen.DesktopRect.Right) - AForm.Left;
//  if (AForm.Top + AForm.Height) > Screen.DesktopRect.Bottom then
//    AForm.Height := round(Screen.DesktopRect.Bottom) - AForm.Top;
  if (AForm.Left + AForm.Width) > Screen.DesktopRect.Right then begin
    AForm.Left := round(Screen.DesktopRect.Right) - AForm.Width;
    if (AForm.Left > -33) and (AForm.Left < 0) then begin
      AForm.Left := 0;
      if (AForm.Left + AForm.Width) > Screen.DesktopRect.Right then
        AForm.Width := round(Screen.DesktopRect.Right);
    end;
    if AForm.Left < 0 then begin
      AForm.Left := ALeft;
      AForm.Top := ATop;
      AForm.Width := AWidth;
      AForm.Height := AHeight;
    end;
  end;
  if (AForm.Top + AForm.Height) > Screen.DesktopRect.Bottom then begin
    AForm.Top := round(Screen.DesktopRect.Bottom) - AForm.Height;
    if (AForm.Top > -33) and (AForm.Top < 0) then begin
      AForm.Top := 0;
      if (AForm.Top + AForm.Height) > Screen.DesktopRect.Bottom then
        AForm.Height := round(Screen.DesktopRect.Bottom);
    end;
    if AForm.Top < 0 then begin
      AForm.Left := ALeft;
      AForm.Top := ATop;
      AForm.Width := AWidth;
      AForm.Height := AHeight;
    end;
  end;
  if (AForm.Width < 50) or (AForm.Height < 20) then begin
    AForm.Left := ALeft;
    AForm.Top := ATop;
    AForm.Width := AWidth;
    AForm.Height := AHeight;
  end;
end;

procedure AddRemovePrefix(APrefix: string; AMemo: TMemo);
var
  sl: TStringList;
  LSelStartLine, LSelEndeLine, i: integer;
  s: string;
  LAdd, LLineSql: boolean;

  function lokGetLine(APos: integer): integer;
  var
    i: integer;
  begin
    result := -1;
    for i := 0 to sl.Count - 1 do begin
      if APos >= integer(sl.Objects[i]) then
        result := i;
    end;
    inc(result);
  end;

  procedure lokZeilenPositionen;
  var
    i: integer;
  begin
    s := '';
    for i := 0 to sl.Count - 1 do begin
      s := s + sl[i] + #13#10;
      sl.Objects[i] := TObject(Length(s));
    end;
  end;

  function lokTestStartsWithPrefix(AText: string): boolean;
  var
    l: integer;
  begin
    l := Length(APrefix);
    result := AnsiCompareText(copy(AText, 1, l), APrefix) = 0;
  end;

begin
  sl := TStringList.Create;
  try
    sl.Assign(AMemo.Lines);
    lokZeilenPositionen;
    LSelStartLine := lokGetLine(AMemo.SelStart + 1);
    LSelEndeLine := lokGetLine(AMemo.SelStart + AMemo.SelLength);
    LAdd := not lokTestStartsWithPrefix(sl[LSelStartLine]);
    for i := LSelStartLine to LSelEndeLine do begin
      LLineSql := lokTestStartsWithPrefix(sl[i]);
      if LAdd and not LLineSql then
        sl[i] := APrefix + sl[i]
      else if not LAdd and LLineSql then
        sl[i] := copy(sl[i], Length(APrefix) + 1, MaxInt);
    end;
    AMemo.Lines.Assign(sl);
    lokZeilenPositionen;
    Application.ProcessMessages;
    if LSelStartLine = 0 then
      AMemo.SelStart := 0
    else
      AMemo.SelStart := integer(sl.Objects[LSelStartLine - 1]);
    if LSelEndeLine = 0 then
      AMemo.SelLength := 0
    else
      AMemo.SelLength := integer(sl.Objects[LSelEndeLine]) - AMemo.SelStart - 2;
    AMemo.SetFocus;
  finally
    sl.Free;
  end;
// procedure AddRemovePrefix
end;

end.
