unit CriticalAlerts;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

const
  TIME_POSITION_MAX = 15000; // time to place window to the screen center, ms

type
  PCriticalAlertRec =^TCriticalAlertRec;
  TCriticalAlertRec = record
    tagid: Integer;
    tagidCnt: Integer;
    value: Integer;
    tagname: string;
    tagnameCnt: string;
    msgtext: string;
  end;

  TCriticalAlertsForm = class(TForm)
    Panel1: TPanel;
    lbMessage: TLabel;
  private
    timePosition: Cardinal;
  public
    { Public declarations }
  end;


  procedure initCriticalAlerts;
  procedure processCriticalAlerts;
  procedure closeCriticalAlerts;

var
  CriticalAlertsForm: TCriticalAlertsForm;

implementation
uses
  TagStorage,
  IniFiles,
  RpVisualGlobal;


var
  alerts: array of PCriticalAlertRec;
  alerts_cnt: Integer;

{$R *.dfm}


procedure clearAlerts;
var
  i: Integer;
begin
  for i:=0 to Length(alerts)-1 do
    dispose(alerts[i]);

  alerts := nil;
end;

procedure initCriticalAlerts;
var
  l: TStringList;
  i,k,j: integer;
  s: string;
begin
  clearAlerts;

  l := TStringList.Create;
  with TIniFile.Create(CurDir + RpVisualIniFile) do try
    ReadSection('CriticalAlerts', l);
    alerts_cnt := l.Count;
    SetLength(alerts, alerts_cnt);

    for i:=0 to alerts_cnt - 1 do begin
      New( alerts[i] );
      s := ReadString('CriticalAlerts', l[i], '');

      k := Pos('=', s);
      alerts[i].tagname := Copy(s, 1, k-1);
      alerts[i].tagid := GetTagIndex(alerts[i].tagname);
      Delete(s, 1, k);

      k := Pos(';', s);
      Val(Copy(s, 1, k-1), alerts[i].value, j);
      Delete(s, 1, k);

      k := Pos(';', s);
      if k = 0 then begin
        alerts[i].msgtext := s;
        alerts[i].tagnameCnt := '';
        alerts[i].tagidCnt := -1;
      end else begin
        k := Pos(';', s);
        alerts[i].msgtext := Copy(s, 1, k-1);
        Delete(s, 1, k);

        alerts[i].tagnameCnt := s;
        alerts[i].tagidCnt := GetTagIndex(s);
      end;

    end;

  finally
    Free;
  end;
  l.Free;
end;


procedure closeCriticalAlertsWnd;
begin
  if CriticalAlertsForm <> nil then begin
    CriticalAlertsForm.Free;
    CriticalAlertsForm := nil;
  end;
end;



procedure processCriticalAlerts;
var
  i,x,y: Integer;
  s: string;
begin
  if not rvgLogIn then Exit;

  s := '';
  for i:=0 to alerts_cnt - 1 do
    if GetTagValue(alerts[i].tagid) = alerts[i].value then begin
      s := s + alerts[i].msgtext;
      if alerts[i].tagidCnt <> -1 then begin
        s := s + IntToStr(GetTagValue(alerts[i].tagidCnt));
      end;
      s := s + #13;
    end;

  if s = '' then begin
//    closeCriticalAlertsWnd;
    if CriticalAlertsForm <> nil then begin
      CriticalAlertsForm.Visible := false;
      CriticalAlertsForm.lbMessage.Caption := '';
      CriticalAlertsForm.Visible := false;
      CriticalAlertsForm.Close;
//      closeCriticalAlertsWnd;
    end;
  end else begin
    if CriticalAlertsForm = nil then begin
      CriticalAlertsForm := TCriticalAlertsForm.Create(nil);
      CriticalAlertsForm.Caption := DateTimeToStr(now);
      CriticalAlertsForm.Visible := true;
      CriticalAlertsForm.Show;
    end else
    if not CriticalAlertsForm.Visible then begin
      CriticalAlertsForm.Caption := DateTimeToStr(now);
      CriticalAlertsForm.Visible := true;
      CriticalAlertsForm.Show;
    end;

    with CriticalAlertsForm do begin
      if lbMessage.Caption <> s then begin
        lbMessage.Caption := s;
        Width := lbMessage.Width + lbMessage.Left*2;
        Height := lbMessage.Height  + lbMessage.Top*2 + 10;// - 15;
      end;

      x := Screen.Width div 3 - CriticalAlertsForm.Width div 2;
      y := Screen.Height div 3 - CriticalAlertsForm.Height div 2;

      if(y <> CriticalAlertsForm.Top) or (x <> CriticalAlertsForm.Left) then begin
        if GetTickCount - timePosition > TIME_POSITION_MAX then begin
            CriticalAlertsForm.Top := y;
            CriticalAlertsForm.Left := x;
        end;
      end else
          timePosition := GetTickCount;
    end;

  end;

end;


procedure closeCriticalAlerts;
begin
  clearAlerts;
  closeCriticalAlertsWnd;
end;


end.
