unit EvalDlg;

{$O+,F+,S-,X+}

interface

uses Objects, Drivers, Views, Dialogs;

const

  cmEvaluate = 1030;
  cmModify   = 1031;

type

  PEvalDialog = ^TEvalDialog;
  TEvalDialog = object(TDialog)
    Expression: PInputLine;
    Result: PInputLine;
    NewValue: PInputLine;
    ModifyButton: PButton;
    constructor Init;
    constructor Load(var S: TStream);
    procedure HandleEvent(var Event: TEvent); virtual;
    procedure SetData(var Rec); virtual;
    procedure Store(var S: TStream);
  end;

const

  REvalDialog: TStreamRec = (
    ObjType: 3010;
    VmtLink: Ofs(TypeOf(TEvalDialog)^);
    Load:    @TEvalDialog.Load;
    Store:   @TEvalDialog.Store
  );

implementation

uses App, TVars, Compiler, Controls, Context, StrNames;

constructor TEvalDialog.Init;
var
  R: TRect;
begin
  R.Assign(10, 3, 69, 18);
  TDialog.Init(R, 'Evaluate and Modify');
  Options := Options or ofCentered;
  R.Assign(3, 3, 38, 4);
  Expression := PInputLine(SetHelp(New(PEditLine, Init(R, 127)), hcExpression));
  Insert(Expression);
  Insert(StandardLabel('E~x~pression', Expression, lfTop));
  Insert(StandardHistory(Expression, hlExpression));
  R.Move(0, 3);
  Result := PInputLine(SetHelp(New(PInputLine, Init(R, 255)), hcResult));
  Insert(Result);
  Insert(StandardLabel('~R~esult', Result, lfTop));
  R.Move(0, 3);
  NewValue := PInputLine(SetHelp(New(PInputLine, Init(R, 127)), hcNewValue));
  Insert(NewValue);
  Insert(StandardLabel('~N~ew value', NewValue, lfTop));
  Insert(StandardHistory(NewValue, hlNewValue));
  Insert(NewButton(43, 3, 13, '~E~valuate', cmEvaluate, bfDefault,
    hcEvaluateButton));
  ModifyButton := NewButton(43, 6, 13, '~M~odify', cmModify, bfNormal,
    hcModifyButton);
  Insert(ModifyButton);
  Insert(NewButton(43, 9, 13, 'Cancel', cmCancel, bfNormal, hcCnlButton));
  Insert(NewButton(43, 12, 13, 'Help', cmHelp, bfNormal, hcEvaluateDialog));
  SelectNext(False);
end;

constructor TEvalDialog.Load(var S: TStream);
begin
  TDialog.Load(S);
  GetSubViewPtr(S, Expression);
  GetSubViewPtr(S, Result);
  GetSubViewPtr(S, NewValue);
  GetSubViewPtr(S, ModifyButton);
end;

procedure TEvalDialog.HandleEvent(var Event: TEvent);

procedure Eval(Modi: Boolean);
var
  P: PInputLine;
  L: Longint;
  CanModify: Boolean;
begin
  if Expression^.Data^ <> '' then
  begin
    P := Expression;
    L := Evaluate(P^.Data^, Result^.Data^, CanModify);
    if L = 0 then
    begin
      if Modi and (NewValue^.Data^ <> '') then
      begin
        if not CanModify then
          L := 65536 + 60
        else
        begin
          P := NewValue;
          L := Modify(P^.Data^, Result^.Data^);
          if L = 0 then
            Message(Desktop, evDebugger, cmRefreshInfo, nil);
        end;
      end else
      begin
        NewValue^.Data^ := '';
        NewValue^.SelectAll(False);
      end;
    end;
    P^.Select;
    P^.SelectAll(True);
    if L <> 0 then
    begin
      Result^.Data^ := Strings^.Get(LongRec(L).Lo + sErrorBase);
      P^.CurPos := LongRec(L).Hi - 1;
      P^.DrawView;
    end;
    Result^.DrawView;
  end;
  ClearEvent(Event);
end;

begin
  TDialog.HandleEvent(Event);
  case Event.What of
    evCommand, evBroadcast:
      case Event.Command of
        cmEvaluate:
          Eval(False);
        cmModify:
          Eval(True);
        cmReleasedFocus, cmReceivedFocus:
          if Event.InfoPtr = NewValue then
            ModifyButton^.MakeDefault(Event.Command = cmReceivedFocus);
      end;
  end;
end;

procedure TEvalDialog.SetData(var Rec);
begin
  Expression^.SetData(Rec);
end;

procedure TEvalDialog.Store(var S: TStream);
begin
  TDialog.Store(S);
  PutSubViewPtr(S, Expression);
  PutSubViewPtr(S, Result);
  PutSubViewPtr(S, NewValue);
  PutSubViewPtr(S, ModifyButton);
end;

end.
