{
       почти системные функции
}
{не удалять эту строку
uses
  'Un_Log',
  'Un_Debug';
{не удалять эту строку}
var
  // процедура в главном скрипте, которая будет вызываться
  // при вызове оператора Halt
  vFinalizeProc: string = '';
  // каталог скриптов. это нужно для логирования сбоев (там ведется журнал
  // сбоя) и может понадобится при динамеской загрузки и выполнения скриптов.
  // в этом случае в этом каталоге лежат скрипты, вызываемые из AzkExchange.
  vDirScripts: string;

const
  // требуемая версия AZK Exchange
  cnVersionAzkExchangeForUnSystem = '5.0.4.2';//'5.0.3.48';


{~InitializeSystem
  инициализация модуля.
  aProc - имя подпрограммы в главном модуле скрипта, которая будет выполняться
  при вызове подпрограммы HaltEx, описанная ниже в этом модуле.
  если параметр не указывается, то при прерывании работы скрипта подпрограммой
  HaltEx, выполняться ничего не будет.
  в этом случае все окна, созданные и открытые скриптом, остануться открытыми.}
procedure InitializeSystem( aProc: string);
begin
  vFinalizeProc := TRIM( aProc);
  vDirScripts   := '';
end;


{~Assigned
  макрос: result := aObject <> nil. }
function Assigned( aObject: TObject): boolean;
begin
  Result := (aObject <> NIL);
end;


{~IfThenElseStr
  макрос: if (aIF) then result := aThen else Result := aElse. }
function IfThenElseStr( aIF: boolean; aThen, aElse: string): string;
begin
  if aIF then Result := aThen else Result := aElse;
end;


{~IfThenElse
  макрос: if (aIF) then result := aThen else Result := aElse. }
function IfThenElse( aIF: boolean; aThen, aElse: variant): variant;
begin
  if aIF then Result := aThen else Result := aElse;
end;


{~StrExpandLeft
  возвращает строку, которая является расширенной строкой aStr до длины
  aLength посредством добавления подстроки aSubStr слева к строке aStr.
  строка добавляется так, чтобы общая длина не превышала указанную aLength.
  при превышении итоговая строка зарезается справа. }
function StrExpandLeft( aStr: string;
                        aLength: integer;
                        aSubStr: string): string;
begin
  try
    Result := aStr;
    while (Length(Result) < aLength)
      do Result := aSubStr + Result;
    if (Length(Result) > aLength)
      then Result := Copy( Result, 1, aLength);
    except
      ExceptionLog( 'Сбой скрипта: "Un_ToolsXML.StrExpandLeft".');
  end;
end;


{~HaltEx
  остановка скрипта.
  перед остановкой будет залогировано и отображено (если sShowMessage=true)
  сообщение aMsg. если sShowMessage =false, сообщение aMsg отображаться не
  будет (только сохранено в логе).
  после этого будет вызван метод, указанный в подпрограмме InitializeSystem.
  после этого работа скрипта будет остановлена.
  подпрограмма работает только с определенными версиями AZK exchange.

  ошибка в Azkexchange в том, что не везде, при запуске скрипта
  инициализируется переменная MainUnitName, да еще и полным путем, а не
  только именем файла!}
procedure HaltEx( aMsg: string; sShowMessage: boolean = TRUE);
begin

  try
    if CompareVersion( AppVersion, cnVersionAzkExchangeForUnSystem) < 0 then begin

      EXIT;
    end;
    // отображаем сообщение, если указано его отображать

    if (LENGTH( aMsg) > 0) then begin

      if sShowMessage then ShowMessage( aMsg);
    end;
    // если указан модуль и подпрограмма - вызываем их перед остановкой
    if ( vFinalizeProc <> '') then
      try

        if fsGlobalUnit.ParentLead.FindEx( vFinalizeProc)
          then fsGlobalUnit.ParentLead.CallFunctionEx( vFinalizeProc, null)
          else
        if fsGlobalUnit.FindEx( vFinalizeProc)
          then fsGlobalUnit.CallFunctionEx( vFinalizeProc, null)
          ;
        except
          ExceptionLog( 'Сбой выполнения финализации.');
      end;

    fsGlobalUnit.ParentLead.Halt;
//    fsGlobalUnit.Halt;
    Halt;
    // контрольная проверка.
    // если скрипт продолжает выполняться, значит это сбой в подпрограмме
    // финализации или модуле AzkExchange: "UnLib70.bpl"
    // модуль:Un_FsSystemRtti, класс:TFunctions, метод:CallMethod
    // операция: if MethodName = 'HALT' then begin...

    except
      ShowMessage( 'Системный сбой Un_System.HaltEx.'#13#10 + LastException.Message);
  end;
end;


{~SystemScriptInfo
  информация о скрипте xScript в логе.
  подпрограмма сохраняет в логе описание скрипта (текст) и системную информацию
  об объекте скрипта.
  xMsg - дополнительное сообщение к описанию скрипта в логе.
  подпрограмма работает только с определенными версиями AZK exchange.}
procedure SystemScriptInfo( xScript: TFsScript; xMsg: string);
var i: integer;
begin
  if (xScript = nil) then EXIT;
  try

    if CompareVersion( AppVersion, cnVersionAzkExchangeForUnSystem) < 0 then begin

      EXIT;
    end;

    //  if xScript.ParentLead <> nil then Info(xScript.ParentLead, 'ParentLead');
    //  if xScript.Parent <> nil then Info(xScript.Parent, 'Parent');
    finally

  end;
end;


{~ExceptionHandler
  главный обработчик исключений.
  именно этим методом нужно завершать обработку исключений в главной программе!
  подпрограмма логирует текст исключения в логе, а так же системную информацию
  о текущем скрипте.
  подпрограмма работает только с определенными версиями AZK exchange.}
procedure ExceptionHandler;
var xExceptMsg: string;
begin
  xExceptMsg := LastException.Message;
  try

    // сохраняем файл со сбоем
    WriteLogFile( vDirScripts + 'сбой_скрипта.txt', xExceptMsg);
    ShowMessage( 'Сбой выполнения скрипта.'#13#10
                 + FORMAT( 'В каталоге "%s" создан файл: сбой_скрипта.txt',
                            [ vDirScripts]));
    except
      ShowMessage( 'Системный сбой Un_System.ExceptionHandler.'#13#10 + LastException.Message);
  end;
end;

begin
  InitializeSystem( '');
end.
  
