unit VisZDVA;

interface

uses
{$ifdef VER150}
  DesignIntf, DesignEditors, DesignWindows, DsnConst,
{$else}
  DsgnIntf,
{$endif}
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, stdctrls, ScadaBase;


type

  TVisZDVA = class(TCustomScadaObject)
  private
    FData: TStringList;
    FLstnPos1: boolean;
    FLstnPos2: boolean;
    FLstnAuto: boolean;

    procedure SetupData(Value: TStringList);
    procedure LoadSetupData;
    procedure SaveSetupData;
    procedure switchLstnPos1(b:Boolean);
    procedure switchLstnPos2(b:Boolean);
    procedure switchLstnAuto(b:Boolean);


  protected
    FImagePics: array of TPicName;
    FImagePicCount: integer;

    FTagControl: integer;
    FTagSost: integer;
    FTagBlok: integer;

    FCurSost: integer;
    FCurMode: integer;
    FCurBlok: integer;

    procedure SetImageSost(Value: integer);
    procedure SetFrameMode(Value: integer);
    procedure SetFrameBlok(Value: integer);

    procedure Loaded; override;
  public
    ImageObj: TImage;
    LabelObj: TLabel;
    FrameModeObj: TShape;
    FrameBlokObj: TShape;

    TagName: TTagName;
    DeviceName: TDeviceName;
    ImagePic: TPicName;

    StateMid: string;
    StateOpen: string;
    StateClose: string;

    ChnlOutNum: integer;
    ChnlInNum: integer;

    constructor Create(AOwner: TComponent); override;

    procedure Init; override;
    procedure Process; override;

  published

    property Pos1ShowMsg: Boolean read FLstnPos1 write switchLstnPos1;
    property Pos2ShowMsg: Boolean read FLstnPos2 write switchLstnPos2;
    property PosAShowMsg: Boolean read FLstnAuto write switchLstnAuto;
    property Data: TStringList read FData write SetupData;


  end;


  TVisZDVAEditor = class(TComponentEditor)
  private
  public
    procedure Edit; override;
  end;



procedure Register;

implementation
uses
  TagStorage,
  numbers,
  ExtDlgs,
  VisZDVASetup,
  RpVisualUtils,
  RpVisualGlobal;

procedure Register;
begin
  RegisterComponents('Scada', [TVisZDVA]);
  RegisterComponentEditor(TVisZDVA, TVisZDVAEditor);
end;

{ TVisZDVA }

constructor TVisZDVA.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FEraseBackground := true;

  Width := 100;
  Height := 100;
  ShowHint := true;

  FData := TStringList.Create;


  // Создание изображения
  ImageObj := TImage.Create(Self);
  ImageObj.Parent := self;
  ImageObj.Stretch := true;
  ImageObj.Visible := true;

  // Создание рамки Mode
  FrameModeObj := TShape.Create(self);
  FrameModeObj.Parent := self;
  FrameModeObj.Visible := true;
  FrameModeObj.Brush.Style := bsClear;
  FrameModeObj.Pen.Color := clAqua;

  // Создание рамки Blok
  FrameBlokObj := TShape.Create(self);
  FrameBlokObj.Parent := self;
  FrameBlokObj.Visible := true;
  FrameBlokObj.Brush.Style := bsClear;
  FrameBlokObj.Pen.Color := clYellow;

  // Создание метки
  LabelObj := TLabel.Create(Self);
  LabelObj.Parent := self;
  LabelObj.Visible := true;
  LabelObj.Transparent := true;
  LabelObj.Font.Color := clWhite;
  LabelObj.Font.Size := 10;
  LabelObj.Font.Style := [fsBold];
  LabelObj.Font.Name := 'Tahoma';

  ImageObj.OnClick := OnDeviceClick;
  LabelObj.OnClick := OnDeviceClick;
  FrameModeObj.OnMouseUp := OnDeviceMouseUp;
  FrameBlokObj.OnMouseUp := OnDeviceMouseUp;

  FTagControl := -1;
  FTagSost := -1;
  FTagBlok  := -1;

  FCurSost := -1;
  FCurMode := -1;
  FCurBlok := -1;

  ChnlOutNum := 2;
  ChnlInNum := 2;

  StateMid := 'Среднее';
  StateOpen := 'Открыто';
  StateClose := 'Закрыто';

  FImagePicCount := 9;
  Setlength(FImagePics, FImagePicCount);

//  SideBar := 'SidebarZdva';
end;


procedure TVisZDVA.SetupData(Value: TStringList);
begin
  FData.Assign(Value);
  LoadSetupData;
end;


procedure TVisZDVA.SetImageSost(Value: integer);
begin
  if (Value <> FCurSost) and (Value>=0) and (Value<FImagePicCount) then try
    ImageObj.Picture.LoadFromFile(VisImagesPath + FImagePics[value]);
    RepaintRect(ImageObj);
    FCurSost := Value;
  except
    LabelObj.Caption := 'PIC';
  end;
end;


procedure TVisZDVA.SetFrameMode(Value: integer);
begin
  if (Value <> FCurMode) then begin
    if (value) > 0 then
      FrameModeObj.Pen.Color := clAqua
    else
      FrameModeObj.Pen.Color := Color;
    FCurMode := Value;
  end;
end;


procedure TVisZDVA.SetFrameBlok(Value: integer);
begin
  if (Value <> FCurBlok) then begin
    if (value) > 0 then
      FrameBlokObj.Pen.Color := clYellow
    else
      FrameBlokObj.Pen.Color := Color;
    FCurBlok := Value;
  end;
end;


// INIT
procedure TVisZDVA.Init;
var
  _tagname: string;
begin
  inherited;

  _tagname := repl(TagName, TagIdRoot, TagRoot);

  IsConnectionBad := false;
  FTagControl := GetTagIndexWithLost(TagPath + '.ZDVA_' + _TagName + '_Control', LostTags);
  FTagSost := GetTagIndexWithLost(TagPath + '.ZDVA_' + _TagName + '_Sost', LostTags);
  FTagBlok := GetTagIndexWithLost(TagPath + '.ZDVA_' + _TagName + '_Blok', LostTags);
  IsConnectionBad := (FTagControl<0) or (FTagSost<0) or (FTagBlok<0);
end;

// PROCESS HANDLER
procedure TVisZDVA.Process;
var
  value: integer;
  allgood: boolean;

  function getval(idx: integer): integer;
  begin
    result := GetTagValue(idx);
    if rvgLogIn then
      allgood := allgood and (result >= 0) and (IsTagStatusGood(idx));
  end;

begin

  allgood := true;

  value := getval(FTagSost);
  SetImageSost(value);

  value := getval(FTagControl) and $F;
  SetFrameMode(value);

  value := getval(FTagBlok);
  SetFrameBlok(value);

  if allgood <> LabelObj.Transparent then begin
    LabelObj.Transparent := allgood;
    if allgood then begin
      RepaintRect(LabelObj);
    end else
      LabelObj.Color := clRed;
  end;

  if (blinkingBadStatus) and (not allgood) then
    Visible := not Visible;

end;



procedure TVisZDVA.LoadSetupData;
var
  s, s1, s2: string;
  k, i, j, v: integer;
begin
  // TagPath
  if FData.Count>0 then s := FData.Strings[0] else s := '';
  k := pos('.', s);
  TagPath := copy(s, 1, k-1);

  // TagName
  delete(s, 1, k); k := pos(';', s);
  TagName := copy(s, 1, k-1);

  // DeviceName
  delete(s, 1, k);
  DeviceName := trim(s);
  Hint := DeviceName;


  // Image size
  if FData.Count>1 then s := FData.Strings[1] else s := '';
  k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  ImageObj.Left := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  ImageObj.Top := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  ImageObj.Width := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  ImageObj.Height := v;


  // BlokFrame offset
  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameBlokObj.Left := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameBlokObj.Top := v;

  // BlokFrame size
  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameBlokObj.Width := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameBlokObj.Height := v;


  // ModeFrame offset
  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameModeObj.Left := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameModeObj.Top := v;

  // ModeFrame size
  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameModeObj.Width := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  FrameModeObj.Height := v;


  // Label offset
  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  LabelObj.Left := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  LabelObj.Top := v;


  // Pic name
  delete(s, 1, k);
  ImagePic := trim(s);


  // Label
  if FData.Count>2 then s := FData.Strings[2] else s := '';
  k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  LabelObj.Left := v;

  delete(s, 1, k); k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  LabelObj.Top := v;

  delete(s, 1, k);
  LabelObj.Caption := trim(s);


  // State names
  if FData.Count>3 then s := FData.Strings[3] else s := '';
  k := pos(',', s);
  StateMid := copy(s, 1, k-1);

  delete(s, 1, k); k := pos(',', s);
  StateOpen := copy(s, 1, k-1);

  delete(s, 1, k);
  StateClose := trim(s);


  // ChnlNum
  if FData.Count>4 then s := FData.Strings[4] else s := '';
  k := pos(',', s);
  val(copy(s, 1, k-1), v, j);
  ChnlOutNum := v;

  delete(s, 1, k);
//  k := pos(',', s);
  val(trim(s), v, j);
  ChnlInNum := v;


  // имена картинок
  s2 := ImagePic;
  i := pos('_',s2);
  s1 := copy(s2, 1, i);
  delete(s2, 1, i+1);

  for i:=0 to FImagePicCount-1 do
    FImagePics[i] := s1 + inttostr(i) + s2;

  if fileexists(VisImagesPath + FImagePics[1]) then
    ImageObj.Picture.LoadFromFile(VisImagesPath + FImagePics[1]);

end;

procedure TVisZDVA.SaveSetupData;
begin

  FData.Clear;
  FData.Add( TagPath + '.' + TagName + ';' + DeviceName );

  FData.Add( format('%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%s', [
        ImageObj.Left,
        ImageObj.Top,
        ImageObj.Width,
        ImageObj.Height,
        FrameBlokObj.Left,
        FrameBlokObj.Top,
        FrameBlokObj.Width,
        FrameBlokObj.Height,
        FrameModeObj.Left,
        FrameModeObj.Top,
        FrameModeObj.Width,
        FrameModeObj.Height,
        LabelObj.Left,
        LabelObj.Top,
        ImagePic]) );

  FData.Add( format('%d,%d,%s', [
        LabelObj.Left,
        LabelObj.Top,
        LabelObj.Caption]) );

  FData.Add( format('%s,%s,%s', [
        StateMid,
        StateOpen,
        StateClose]) );

  FData.Add( format('%d,%d', [
        ChnlOutNum,
        ChnlInNum]) );

end;


procedure TVisZDVA.Loaded;
begin
  inherited;
  LoadSetupData;
end;




{ TVisZDVAEditor }

procedure TVisZDVAEditor.Edit;
begin
  inherited;
  VisZDVASetupForm := TVisZDVASetupForm.Create(nil);

  VisZDVASetupForm.M := Component as TVisZDVA;
  VisZDVASetupForm.D := Self;
  if VisZDVASetupForm.ShowModal = mrOk then
    VisZDVASetupForm.M.SaveSetupData
  else
    VisZDVASetupForm.M.LoadSetupData;

  VisZDVASetupForm.Free;
end;




procedure TVisZDVA.switchLstnPos1(b:Boolean);
begin
  FLstnPos1:=b;
end;

procedure TVisZDVA.switchLstnPos2(b:Boolean);
begin
  FLstnPos2:=b;
end;

procedure TVisZDVA.switchLstnAuto(b:Boolean);
begin
  FLstnAuto:=b;
end;
end.
