unit Telega;

interface
uses  Types, Graphics, StdCtrls, SysUtils, Classes, Dialogs,
      ExtCtrls, Controls, ScadaBase, VisMchb, VisDataboard, Messages;

type
  PTelegaPosRec =^ TTelegaPosRec;
  TTelegaPosRec = record
    ReqPos: integer;
    ReqZdv: integer;
    pnl: TPanel;
  end;

  TTelega = class (TCustomScadaObject)
  private
    TagPath          : string; // путь телеги в RpSvrTcp
    Positions        : array of PTelegaPosRec;
    mchb	     : TVisMCHB;
    ModeUseZDV : Boolean;      // Если 1, то задвижка используется


    DefaultX: integer; // дефолтовые координаты mchb-телеги
    DefaultY: integer;

    OffsetX: integer; // смещение mchb-телеги относительно панели соответствующей позиции
    OffsetY: integer; // (смещение относительно левых верхних координат)


    TagCanMove, TagCanChangeZDV : string;

    procedure OnPanelClick(Sender : TObject);

//    index_ReqPos, index_ReqZdv,
//    index_LastPos, index_LastZdv :Integer;

  public
    FlashOn, FlashOff : integer;
    Flashing : boolean;


    procedure Process; override;
    function  AddPosition(pnl:TPanel; ReqPos, ReqZdv: integer): PTelegaPosRec;
    // ReqPos номер позиции от 0
    // ReqZdv 1 и 2 - проверяется на соответствие; 0 - игнорировать положение
    procedure Close;

  private

    FontColor        : TColor;
    BgColor          : TColor;


    DefFontColor     : TColor;
    DefBgColor       : TColor;

    CurFlashTime     : integer;

  end;



function createTelega(TagPath: string;
                      ZDVuse : boolean;
                      var Mchb: TVisMCHB;
                      DefaultX: integer;
                      DefaultY: integer;
                      OffsetX: integer;
                      OffsetY: integer;
                      TagMove    :string;
                      TagZDV     :string;

                      EnableFlashMode : boolean;
                      FlashOn: integer;
                      FlashOff: integer

                     ): TTelega;

implementation
uses
  infodlg, 
  TagStorage,  meslogging,   RpVisualGlobal;



function  TTelega.AddPosition (pnl:TPanel; ReqPos, ReqZdv: integer) : PTelegaPosRec;
var
    k,i   : integer;
begin
  result := nil;
 k := Length(Positions);
 SetLength(Positions, k+1);
 New (Positions[k]);

 Positions[k].ReqPos := ReqPos;
 Positions[k].ReqZdv := ReqZdv;
 Positions[k].pnl    := pnl;

 Positions[k].pnl.OnClick := OnPanelClick;
 Positions[k].pnl.Color   := DefBgColor;
 Positions[k].pnl.Tag     := k;

 for i:=0 to Positions[k].pnl.ControlCount-1 do
  if (Positions[k].pnl.Controls[i] is TLabel) then
    begin
      TLabel(Positions[k].pnl.Controls[i]).OnClick    := OnPanelClick;
      TLabel(Positions[k].pnl.Controls[i]).Font.Color := DefFontColor;
//      TLabel(Positions[k].pnl.Controls[i]).Font.Color := clRed;
      TLabel(Positions[k].pnl.Controls[i]).Tag        := k;
//      TLabel(Positions[k].pnl.Controls[i]).Hint        := IntToStr(k);

    end;

end;


procedure TTelega.Close;
var i:integer;
begin
  for i:=Low(Positions) to High(Positions) do Positions[i] := nil;
end;



procedure TTelega.OnPanelClick(Sender : TObject);
var
    CanMove, CanChangeZDV:boolean;

    CurPos, CurZDV :integer;

    inNewPos, inNewZDV : boolean;

    i,j, ind:Integer;
begin
 // ShowMessage(TagAppr);
  if not rvgLogIn then Exit;

  CanMove := true;
  if (TagCanMove<>'') and (GetTagValueByName(TagCanMove)<=0) then
       CanMove:=false;

  CanChangeZDV := true;
  if (TagCanChangeZDV<>'') and (GetTagValueByName(TagCanChangeZDV)<=0) then
        CanChangeZDV := false;

  if Sender.ClassName = 'TLabel' then begin
     ind := (Sender as TLabel).Tag;
  end else begin
     ind := (Sender as TPanel).Tag;
  end;

  CurPos  := GetTagValueByName (TagPath + '.CurPos');
  CurZDV  := GetTagValueByName (TagPath + '.CurZdv');

  if (Positions[ind].ReqPos = CurPos) then
     inNewPos:=true  else inNewPos:=false;

  if (Positions[ind].ReqZdv = CurZDV) then
     inNewZDV := true else inNewZDV:=false;

{    for i:=Low(Positions) to High(Positions) do
     begin
       if i<>ind then
          begin
             Positions[i].ReqPos
             Positions[i].ReqZdv
          end;

     end;
 }

  if (
         (CanMove) OR ((NOT CanMove) AND inNewPos )
     ) AND // можно двигать
     (
        (((CanChangeZDV) OR ((NOT CanChangeZDV) AND inNewZDV)) AND ModeUseZDV) OR (NOT ModeUseZDV)
      ) // можно кидать
     then
      begin
        //можно дваигать и кидать
      end
     else
      begin
        // нельзя ни двигать не кидать
        ShowMessage('Телега занята, её нельзя сейчас двигать');
        Exit;
      end;


 if GetTagValueByName (TagPath + '.SYSTEM.ErrorFlag')>0 then
   begin
      ShowMessage('Нет связи с телегой');
      Exit;
   end;

 if showInfoDlg('Установить позицию для телеги ', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin

    for i:=Low(Positions) to High(Positions) do
     begin
       //Покрасили все в дефолтный цвет
       Positions[i].pnl.Color := DefBgColor;

       for j:=0 to Positions[i].pnl.ControlCount-1 do
         if (Positions[i].pnl.Controls[j] is TLabel) then
           TLabel(Positions[i].pnl.Controls[j]).Font.Color := DefFontColor;

       if i=ind then
        begin

          if ((CanMove) OR ((NOT CanMove) AND inNewPos )         ) then
            begin
              SetTagValueByName( TagPath + '.ReqPos', Positions[i].ReqPos );
            end;

          if (((CanChangeZDV) OR ((NOT CanChangeZDV) AND inNewZDV)) AND ModeUseZDV) then
            begin
              SetTagValueByName( TagPath + '.ReqZdv', Positions[i].ReqZdv );
            end;


          if ModeUseZDV
             then SaveMessageText('Установка позиции', 'Позиция телеги:' + inttostr(Positions[i].ReqPos) + '  Позиция клапана:' + IntToStr(Positions[i].ReqZdv) + '', TagPath)
             else SaveMessageText('Установка позиции', 'Позиция телеги:' + inttostr(Positions[i].ReqPos) + '. ' + '', TagPath);

          if GetTagValueByName (TagPath + '.SYSTEM.ErrorFlag')>0 then
            begin
              ShowMessage('Ошибка связи');
              SaveMessageText('Установка позиции', 'Ошибка связи с телегой ' + TagPath, TagPath);
            end;

        end;

     end;

  end;

end;

procedure TTelega.Process;
var pos,zdv, i, j : integer;
    w:boolean;
    reqPos,reqZDV :integer;
    fakePos : boolean;

begin
  inherited;

 if (not rvgLogIn) OR (GetTagValueByName (TagPath + '.SYSTEM.ErrorFlag')>0) then
   begin
     mchb.Top := DefaultY;
     mchb.Left := DefaultX;
     mchb.Visible:=true;
     Exit;
   end;

 if Flashing then
   begin
     CurFlashTime := CurFlashTime + 1;
     if FlashOn+FlashOff < CurFlashTime then  CurFlashTime:=1;
   end;

 pos := GetTagValueByName (TagPath + '.CurPos');
 zdv := GetTagValueByName (TagPath + '.CurZdv');

 if (pos = 0) and Flashing then
     begin
       fakePos := true;
       pos := GetTagValueByName (TagPath + '.LastPos');
     end else fakePos := false;


 reqPos := GetTagValueByName (TagPath + '.reqPos');
 reqZDV := GetTagValueByName (TagPath + '.reqZdv');

// if ModeUseZDV and (reqZDV <=0 ) then reqZDV:=1;

 w := false;

 for i:=Low(Positions) to High(Positions) do
  begin
    if  (Positions[i].ReqPos = pos) and
        ((ModeUseZDV and (Positions[i].ReqZdv = zdv)) or ( (not ModeUseZDV) and (Positions[i].ReqZdv=1)) )
    then
    begin
      //делаем грязное дело
      w := True;
      mchb.Top := Positions[i].pnl.Top - mchb.Height - OffsetY;
      mchb.Left := Positions[i].pnl.Left + (Positions[i].pnl.Width div 2)  - (mchb.Width div 2) + OffsetX;

      if fakePos then
        begin
          if CurFlashTime <= FlashOn then mchb.Visible:=true
                                     else mchb.Visible:=false;
        end else mchb.Visible:=true;

    end;

    if  (Positions[i].ReqPos = reqPos) and
        ((Positions[i].ReqZdv = 0) or (Positions[i].ReqZdv = reqZDV) or (not ModeUseZDV))
    then
    begin
      //делаем грязное дело
      Positions[i].pnl.Color := BgColor;
      for j:=0 to Positions[i].pnl.ControlCount-1 do
         if (Positions[i].pnl.Controls[j] is TLabel) then
            TLabel(Positions[i].pnl.Controls[j]).Font.Color := FontColor;
    end
    else
    begin
      Positions[i].pnl.Color := DefBgColor;

      for j:=0 to Positions[i].pnl.ControlCount-1 do
         if (Positions[i].pnl.Controls[j] is TLabel) then
            TLabel(Positions[i].pnl.Controls[j]).Font.Color := DefFontColor;

    end;


  end;

 if NOT w then
  begin
    // А позиция фиг знает какая
    mchb.Top := DefaultY;
    mchb.Left := DefaultX;
  end;
end;


function createTelega( TagPath: string;
                       ZDVuse : boolean;       // false - задвижка игнориться. всегда отображается в 1 положении
                       var Mchb: TVisMCHB;
                       DefaultX: integer;
                       DefaultY: integer;
                       OffsetX: integer;
                       OffsetY: integer;
                       TagMove    :string;
                       TagZDV     :string;

                       EnableFlashMode : boolean;
                       FlashOn: integer;
                       FlashOff: integer

                     ): TTelega;
var t:TTelega;
begin
  t:= TTelega.Create(Mchb.Parent);

  t.ModeUseZDV := ZDVuse;

  SetLength(t.Positions, 0);
  t.MCHB         := MCHB;
  t.TagPath      := TagPath;

  t.DefaultX     := DefaultX;
  t.DefaultY     := DefaultY;

  t.OffsetX      := OffsetX;
  t.OffsetY      := OffsetY;

  t.TagCanMove       := TagMove;
  t.TagCanChangeZDV  := TagZDV;

  t.FontColor    := clBlack;
  t.BgColor      := clYellow;

  t.DefFontColor := clBlack;
  t.DefBgColor   := clBtnFace;

  t.CurFlashTime := 1;
  t.FlashOn      := FlashOn;
  t.FlashOff     := FlashOff;
  t.Flashing     := EnableFlashMode;

  createTelega   := t;
end;

end.



