unit Myc.Fmx.AstEditor.Handlers.Primitives;

interface

uses
    System.UITypes,
    System.SysUtils,
    Myc.Data.Value,
    Myc.Ast,
    Myc.Ast.Nodes,
    Myc.Fmx.AstEditor.Render,
    Myc.Fmx.AstEditor.Node;

type
    TConstantNodeHandler = class(TBaseNodeHandler<IConstantNode>)
    public
        procedure BuildUI(OwnerNode: TAstViewNode); override;
        function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
    end;

    TIdentifierNodeHandler = class(TBaseNodeHandler<IIdentifierNode>)
    public
        procedure BuildUI(OwnerNode: TAstViewNode); override;
        function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
    end;

    TKeywordNodeHandler = class(TBaseNodeHandler<IKeywordNode>)
    public
        procedure BuildUI(OwnerNode: TAstViewNode); override;
        function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
    end;

    TNopNodeHandler = class(TBaseNodeHandler<INopNode>)
    public
        procedure BuildUI(OwnerNode: TAstViewNode); override;
        function ReconstructAst(OwnerNode: TAstViewNode): IAstNode; override;
    end;

implementation

{ TConstantNodeHandler }

procedure TConstantNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
    valueStr: string;
    isConcise: Boolean;
    titleLabel: TTextNode;
    valLabel: TTextNode;
begin
    valueStr := FNode.Value.ToString;
    isConcise := ((FNode.Value.Kind = TDataValueKind.vkScalar) or (Pos(sLineBreak, valueStr) = 0)) and (Length(valueStr) < 40);

    if isConcise then
    begin
        OwnerNode.Frameless := True;
        OwnerNode.BackgroundColor := TAlphaColors.Null;
        OwnerNode.BorderColor := TAlphaColors.Null;
        OwnerNode.BorderWidth := 0;

        // Compact representation for scalars
        OwnerNode.Margins := TMarginRect.Create(1, 0, 1, 0);
        OwnerNode.Padding := TMarginRect.Create(0, 0, 0, 0);

        valLabel := OwnerNode.AddLabel(OwnerNode, valueStr);
        valLabel.Margins := TMarginRect.Create(1, 0, 1, 0);
    end
    else
    begin
        OwnerNode.Frameless := False;
        OwnerNode.Orientation := loVertical;

        titleLabel := OwnerNode.AddLabel(OwnerNode, 'Const');
        titleLabel.FontSettings.Font.Style := [TFontStyle.fsBold];

        OwnerNode.AddLabel(OwnerNode, valueStr);
    end;
end;

function TConstantNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
    Result := TAst.Constant(FNode.Identity.AsConstant, FNode.StaticType);
end;

{ TIdentifierNodeHandler }

procedure TIdentifierNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
    lbl: TTextNode;
begin
    OwnerNode.Frameless := True;
    OwnerNode.BackgroundColor := TAlphaColors.Null;
    OwnerNode.BorderColor := TAlphaColors.Null;
    OwnerNode.BorderWidth := 0;

    // Compact representation for identifiers
    OwnerNode.Margins := TMarginRect.Create(1, 0, 1, 0);
    OwnerNode.Padding := TMarginRect.Create(0, 0, 0, 0);

    lbl := OwnerNode.AddLabel(OwnerNode, FNode.Name);
    lbl.Margins := TMarginRect.Create(1, 0, 1, 0);
end;

function TIdentifierNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
    Result := TAst.Identifier(FNode.Identity.AsNamed, FNode.Address, FNode.StaticType);
end;

{ TKeywordNodeHandler }

procedure TKeywordNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
    lbl: TTextNode;
begin
    OwnerNode.Frameless := True;
    OwnerNode.BackgroundColor := TAlphaColors.Null;
    OwnerNode.BorderColor := TAlphaColors.Null;
    OwnerNode.BorderWidth := 0;

    // Compact representation for keywords
    OwnerNode.Margins := TMarginRect.Create(1, 0, 1, 0);
    OwnerNode.Padding := TMarginRect.Create(0, 0, 0, 0);

    lbl := OwnerNode.AddLabel(OwnerNode, ':' + FNode.Value.Name);
    lbl.Color := TAlphaColors.Mediumvioletred;
    lbl.Margins := TMarginRect.Create(1, 0, 1, 0);
end;

function TKeywordNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
    Result := TAst.Keyword(FNode.Identity.AsKeyword);
end;

{ TNopNodeHandler }

procedure TNopNodeHandler.BuildUI(OwnerNode: TAstViewNode);
var
    lbl: TTextNode;
begin
    OwnerNode.Frameless := True;
    OwnerNode.Alignment := TLayoutAlignment.laCenter;
    OwnerNode.Orientation := TLayoutOrientation.loHorizontal;
    lbl := OwnerNode.AddLabel(OwnerNode, '...');
    lbl.FontSettings.Font.Style := [TFontStyle.fsBold];
    lbl.Margins := TMarginRect.Create(8, 4, 8, 4);
end;

function TNopNodeHandler.ReconstructAst(OwnerNode: TAstViewNode): IAstNode;
begin
    Result := FNode;
end;

end.
