unit ScadaBase;

interface
uses
  Math,
  Windows,
  Messages,
  Types,
  Controls,
  Classes,
  sysutils,
  forms,
  dialogs;

Const
  UM_REPAINT_NEIGHBOURS = WM_APP + 1;

  ModeMarginX = 6;
  ModeMarginY = 3;

  BlokMarginX = 4;
  BlokMarginY = 1;


Type
  TPicName = string;
  TTagName = string;
  TTagPath = string;
  TDeviceName = string;
  TChannelName = string;



Type
  TCustomScadaObject = class;

  TScadaObjectClickEvent = procedure(Sender: TObject; obj: TCustomScadaObject; var frm: TForm) of object;
  TScadaObjectProcessEvent = procedure(Sender: TObject) of object;

  TCanClickEvent = procedure(Sender: TObject; var Can: boolean) of object;

  TCustomScadaObject = class(TCustomControl)
  private
    FTagRoot: string;
    FTagIdRoot: string;
    FTagPath: string;
    FSidebar: string;

  protected
    FEraseBackground: boolean;
    FScadaObjectClickEvent: TScadaObjectClickEvent;
    FScadaObjectProcessEvent: TScadaObjectProcessEvent;

    IsConnectionBad: boolean;
    IsValueBad: boolean;

    procedure CreateParams(var Params: TCreateParams); override;
    procedure OnDeviceClick(Sender: TObject);
    procedure OnDeviceDblClick(Sender: TObject);
    procedure OnDeviceMouseUp(Sender: TObject; Button: TMouseButton;
        Shift: TShiftState; X, Y: Integer); virtual;

    procedure OnMouseMoveProc(Sender: TObject; Shift: TShiftState;X, Y: Integer);

    procedure WndProc(var Msg : TMessage); override;
//    procedure OnMove(var Msg: TWMMove); message WM_MOVE;
//    procedure RepaintNeighbours(var Msg: TMessage); message UM_REPAINT_NEIGHBOURS;

    function replaceAllMarkers(s: string): string;
  public
    LostTags: string;

    constructor Create(AOwner: TComponent); override;
    procedure Init; virtual; 
    procedure Process; virtual;
    procedure RepaintRect(Control: TControl = nil);

    property OnScadaObjectClick: TScadaObjectClickEvent read FScadaObjectClickEvent write FScadaObjectClickEvent;
    property OnProcess: TScadaObjectProcessEvent read FScadaObjectProcessEvent write FScadaObjectProcessEvent;
    property EraseBackground: boolean read FEraseBackground;

  published
    property TagPath: string read FTagPath write FTagPath;
    property TagRoot: string read FTagRoot write FTagRoot;
    property TagIdRoot: string read FTagIdRoot write FTagIdRoot;

    property Sidebar: string read FSidebar write FSidebar;

    property OnClick;
    property OnDblClick;
  end;


implementation
uses
  RpVisualUtils,
  RpVisualGlobal;

const
  HINT_MARKER = '{hint}';

procedure TCustomScadaObject.OnMouseMoveProc(Sender: TObject; Shift: TShiftState;X, Y: Integer);
begin
//  Hint := ReplaceStr(Hint, TagIdRoot, TagRoot);
end;


constructor TCustomScadaObject.Create(AOwner: TComponent);
begin
  inherited;
  FEraseBackground := False;
  IsConnectionBad := false;
  IsValueBad := false;
  TagIdRoot := '^';

  OnMouseMove := OnMouseMoveProc;
end;

procedure TCustomScadaObject.OnDeviceClick(Sender: TObject);
begin
  if Assigned(OnClick) then OnClick(Self);
end;

procedure TCustomScadaObject.OnDeviceDblClick(Sender: TObject);
begin
  if Assigned(OnDblClick) then OnDblClick(Self);
end;

procedure TCustomScadaObject.OnDeviceMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Assigned(OnClick) then OnClick(Self);
end;

procedure TCustomScadaObject.Init;
begin
  Hint := ReplaceStr(Hint, TagIdRoot, TagRoot);
end;


procedure TCustomScadaObject.Process;
begin
  if rvgLogIn then
  begin
    if (IsConnectionBad) or (IsValueBad) then
      Visible := not Visible
    else
      Visible := true;
  end;
end;


procedure TCustomScadaObject.RepaintRect(Control: TControl);
var
  r,rc: TRect;
begin
  r := BoundsRect;
  if Control <> nil then
  begin
    rc.Left := r.Left + Control.Left;
    rc.Top := r.Top + Control.Top;
    rc.Right := rc.Left + Control.Width;
    rc.Bottom := rc.Top + Control.Height;

    if (rc.Left > r.right) or (rc.Top > r.Bottom) or (rc.Right < r.Left) or (rc.Bottom < r.Top) then begin
      exit;
    end;

    r.Left := Max(r.Left, rc.Left);
    r.Top := Max(r.Top, rc.Top);
    r.Right := Min(r.Right, rc.Right);
    r.Bottom := Min(r.Bottom, rc.Bottom);
  end;

  InvalidateRect(Parent.Handle, @r, true);
  Parent.Update;
  Repaint;
end;


// ÏÐÎÇÐÀ×ÍÎÑÒÜ
procedure TCustomScadaObject.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  if FEraseBackground then
    Params.ExStyle := Params.ExStyle + WS_EX_TRANSPARENT;
end;

procedure TCustomScadaObject.WndProc(var Msg: TMessage);
begin
  if FEraseBackground and (Msg.Msg = WM_ERASEBKGND) then
  begin
    Msg.Result := 0;
    Exit;
  end;

  inherited;
end;

//procedure TCustomScadaObject.OnMove(var Msg: TWMMove);
//begin
//  if FEraseBackground then
//    PostMessage(Handle, UM_REPAINT_NEIGHBOURS, 0, 0);
//
//end;
//
//procedure InvalidateWithChildren(WinControl: TWinControl);
//var
//  i: integer;
//begin
//  WinControl.Invalidate;
//  for i:=0 to WinControl.ControlCount-1 do
//    if WinControl.Controls[i] is TWinControl then
//      InvalidateWithChildren(TWinControl(WinControl.Controls[i]));
//end;
//
//procedure TCustomScadaObject.RepaintNeighbours(var Msg: TMessage);
//var
//  i: Integer;
//  r, ri: TRect;
//begin
//  r := BoundsRect;
//  InvalidateRect(Parent.Handle, @r, true);
//  Parent.Update;
//  for i:=0 to Parent.ControlCount-1 do
//    if Parent.Controls[i] is TWinControl then
//      if IntersectRect(ri, r, Parent.Controls[i].BoundsRect) then
//        InvalidateWithChildren(TWinControl(Parent.Controls[i]));
//end;


//procedure TCustomScadaObject.replaceHintString(var s: string);
//begin
//  s := ReplaceStr(s, TagIdRoot, TagRoot);
//end;
//
//procedure TCustomScadaObject.replaceTagRootString(var s: string);
//begin
//  s := ReplaceStr(s, HINT_MARKER, hint);
//end;



function TCustomScadaObject.replaceAllMarkers(s: string): string;
begin
  s := ReplaceStr(s, HINT_MARKER, hint);
  s := ReplaceStr(s, TagIdRoot, TagRoot);
  result := s;
end;

end.
