unit uBafCodeUtils;

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

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, System.Rtti, FMX.Grid.Style, FMX.Grid, uBafTypes,
  FMX.ScrollBox, FMX.Memo, FMX.TabControl, FMX.ListBox, System.IniFiles,
  Data.DB, System.Math, FMX.Layouts, uBafControls, FMX.Edit, FMX.ComboEdit,
  FMX.Memo.Types, contnrs, StrUtils, foBafCode;

type
  TBafCodeUtils = class

  public
    class procedure SqlOpen(AGrid: TStringGrid; AData: TDataset; AMax: integer);
    class function FindFirstLine(AList: TStrings; AText: string;
        AAtFirst: boolean): integer;
  end;

implementation

{ TBafCodeUtils }

class function TBafCodeUtils.FindFirstLine(AList: TStrings; AText: string;
  AAtFirst: boolean): integer;
var
  i, LPos: integer;
  s: string;
begin
  result := -1;
  AText := AnsiLowerCase(AText);
  for i := 0 to AList.Count - 1 do begin
    s := AnsiLowerCase(AList[i]);
    LPos := Pos(AText, s);
    if LPos > 0 then begin
      if AAtFirst then begin
        s := Trim(copy(s, 1, LPos + Length(AText) - 1));
        if s = AText then begin
          result := i;
          Break;
        end;
      end
      else begin
        result := i;
        Break;
      end;
    end;
  end;
end;

class procedure TBafCodeUtils.SqlOpen(AGrid: TStringGrid; AData: TDataset;
    AMax: integer);
var
  LText: string;
  LColumn: TStringColumn;

  procedure lokColumns;
  var
    i, w: integer;
  begin
    LColumn := TStringColumn.Create(AGrid);
    LColumn.Parent := AGrid;
    LColumn.Header := 'Row';
    LColumn.Width := 42;
    for i := 0 to AData.FieldCount - 1 do begin
      LText := AData.Fields[i].FieldName;
      LColumn := TStringColumn.Create(AGrid);
      LColumn.Parent := AGrid;
      LColumn.Header := LText;
      LColumn.Width := AGrid.Canvas.TextWidth(LText) + 10;
      if AData.Fields[i].DataType in [ftString, ftWideString] then begin
        w := System.Math.Min(40, AData.Fields[i].DataSize) * 7;
        if LColumn.Width < w then
          LColumn.Width := w;
      end
      else if AData.Fields[i].DataType in [ftMemo] then
        LColumn.Width := 150
      else if AData.Fields[i].DataType in [ftDate, ftDateTime] then
        LColumn.Width := 70;
    end;
  end; // procedure lokColumns

  procedure lokData;
  var
    i, LCount, LRow: integer;
  begin
    LCount := 0;
    while not AData.Eof do begin
      LRow := AGrid.RowCount;
      AGrid.RowCount := AGrid.RowCount + 1;
      for i := 0 to AData.FieldCount - 1 do
        AGrid.Cells[i + 1, LRow] := AData.Fields[i].AsString;

      inc(LCount);
      AGrid.Cells[0, LRow] := LCount.ToString;
      if LCount >= AMax then
        exit;
      AData.Next;
    end;
  end; // procedure lokData

begin
  AGrid.ClearColumns;
  AGrid.RowCount := 0;
  lokColumns;
  lokData;
end;

end.
