unit VisZDVB;

interface

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


type

  TVisZDVB = 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;
    FTagOpened: integer;
    FTagClosed: integer;

    FCurSost: integer;
    FCurOpened: integer;
    FCurClosed: integer;


    FCurMode: integer;
    FCurBlok: integer;

    procedure SetImageSost(Value, ValueOpen, ValueClose: 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;


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



procedure Register;

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

procedure Register;
begin
  RegisterComponents('Scada', [TVisZDVB]);
  RegisterComponentEditor(TVisZDVB, TVisZDVBEditor);
end;

{ TVisZDVB }

constructor TVisZDVB.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;
  FCurOpened := -1;
  FCurClosed := -1;
  FCurMode := -1;
  FCurBlok := -1;

  ChnlOutNum := 2;
  ChnlInNum := 2;

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

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


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


procedure TVisZDVB.SetImageSost(Value, ValueOpen, ValueClose: integer);
var v:integer;
begin
  v := 0;

  if ((Value <> FCurSost) OR (ValueOpen <> FCurOpened) OR (ValueClose <> FCurClosed))
     and (Value>=0) and (ValueOpen>=0) and (ValueClose>=0)  //and (Value < FImagePicCount)
       then try

    if (ValueOpen > 0) and (ValueClose = 0) then v := 2; //откр
    if (ValueOpen = 0) and (ValueClose > 0) then v := 1; //закр
    if (ValueOpen = 0) and (ValueClose = 0) then v := 0; //среднее или полуоткрыто
    if (ValueOpen > 0) and (ValueClose > 0) then v := 3; //закр и откр одновременно - ошибка

    //теперь меняем цвет в зависимости от команды
    if Value in [0, 30, 15, 17, 10, 25, 27, 20] //Упр - закрыто
      then v:=v
       else
         if Value in [11, 16, 12, 14, 21, 26, 22, 24 ] //Упр - открыто
           then v := v+4
            else if Value in [18, 19, 28, 29] then v:=3
                  else if Value in [13, 23] then v:=7
                    else v := 8;//неправильный адрес или неизв. состояние

    // v - теперь соответствует Sost'у ZDVA 

    ImageObj.Picture.LoadFromFile(VisImagesPath + FImagePics[v]);

    FCurSost := Value;
    FCurOpened := ValueOpen;
    FCurClosed := ValueClose;
  except
    LabelObj.Caption := 'PIC';
  end;

end;

procedure TVisZDVB.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 TVisZDVB.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 TVisZDVB.Init;
var
  _tagname: string;
begin
  inherited;

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

  IsConnectionBad := false;
  FTagControl := GetTagIndexWithLost(TagPath + '.ZDVB_' + _TagName + '_Control', LostTags);
  FTagSost := GetTagIndexWithLost(TagPath + '.ZDVB_' + _TagName + '_Sost', LostTags);
  FTagBlok := GetTagIndexWithLost(TagPath + '.ZDVB_' + _TagName + '_Blok', LostTags);

  FTagOpened := GetTagIndexWithLost(TagPath + '.ZDVB_' + _TagName + '_Opened', LostTags);
  FTagClosed := GetTagIndexWithLost(TagPath + '.ZDVB_' + _TagName + '_Closed', LostTags);


  IsConnectionBad := (FTagControl<0) or (FTagSost<0) or (FTagBlok<0) or (FTagOpened<0) or (FTagClosed<0);
end;

// PROCESS HANDLER
procedure TVisZDVB.Process;
var
  value, valueo, valuec: integer;
  label_visible: boolean;
begin

  IsValueBad := false;
  label_visible := false;

  value := GetTagValue(FTagSost);
  valueo := GetTagValue(FTagOpened);
  valuec := GetTagValue(FTagClosed);

  SetImageSost(value, valueo, valuec);
  IsValueBad := IsValueBad or (value < 0) or (valuec < 0) or (valueo < 0);

  value := GetTagValue(FTagControl) and $F;
  SetFrameMode(value);
  IsValueBad := IsValueBad or (value < 0);
  label_visible := label_visible or (value > 0);

  value := GetTagValue(FTagBlok);
  SetFrameBlok(value);
  IsValueBad := IsValueBad or (value < 0);
  label_visible := label_visible or (value > 0);


  LabelObj.Visible := label_visible or IsValueBad or (not rvgLogIn);

  inherited;
end;



procedure TVisZDVB.LoadSetupData;
var
  s, s1, s2: string;
  k, i, j, v: integer;
//  img_xs, img_ys, frm_xo, frm_yo, frm_xs, frm_ys, lab_xo, lab_yo: 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 TVisZDVB.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 TVisZDVB.Loaded;
begin
  inherited;
  LoadSetupData;
end;




{ TVisZDVBEditor }

procedure TVisZDVBEditor.Edit;
begin
  inherited;
  VisZDVBSetupForm := TVisZDVBSetupForm.Create(nil);

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

  VisZDVBSetupForm.Free;
end;



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

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

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