unit epiUDFTypes;
interfaceuses classes;
TypeTEpiFileName=array[0..31] of char;
TEpiFilePath=array[0..255] of char;
TEpiCommandString=array[0..255] of char;TEpiHandle=LongWord;
TEpiErrorCode = word;
TPEpiDataModuleInfo=^TEpiDataModuleInfo;
TPEpiMenuCommand=^TEpiMenuCommand;
TPEpiDataModuleRec=^TEpiDataModuleRec;TEpiInitLibProc=procedure(ModuleInfo: TPEpiDataModuleInfo);
TEpiRegCmdProc=procedure(CommandInfo: TPEpiMenuCommand);TUDFFunction=procedure(const ParamList:variant;var ReturnValue:variant);
//TUDFFunction=function(const ParamList:variant):variant;
TUDFValidateFunction=function(ParamList:variant):integer;
TEpiGetIntFunction=function :integer;
TEpiGetUDFInfo=procedure (Const UDFid:integer; var functionString:variant;var ReturnType:variant;
       var FunctionName:variant;var ParamCount:integer);TUDFReturnType=word;TEpiDataVersionInfo=record
  Major,
  Minor,
  BuildNo :word;
end;TEpiContext=record
  RegisterCommand:TEpiRegCmdProc;
  UnRegisterCommand:TEpiRegCmdProc;
end;TEpiDataModuleInfo=record
  ModuleID     :TEpiHandle;
  ModuleHandle     : TEpiHandle;
  ModuleType   :Word;
  ModulePriority :word;
  szModuleName: TEpiFileName;
  szHelpfileName: TEpiFilePath;
  MinimumEpiDataVersion : TEpiDataVersionInfo;
  EpiDataVersion : TEpiDataVersionInfo;
  OSRequired: word;
  MinimumOSVersion : TEpiDataVersionInfo;
  EpiDataHandle    : TEpiHandle;
  ErrorCode        : TEpiErrorCode;
  UDFCount      :Word;
//  Context          : TEpiContext;
end;
TEpiDataModuleRec=record
 ModuleInfo: TEpiDataModuleInfo;
 szModulefileName: TEpiFilePath;
 ModuleHandle     : TEpiHandle;
 InitializeModule,
 finalizeModule : TEpiInitLibProc;
 ExecuteCommand:TEpiRegCmdProc;
end;
TEpiMenuCommand=record
 ModuleId : word;
 CommandType  :word;
 szCommandName:TEpiCommandString;
 szCommandHint:TEpiCommandString;
 commandID    :word;
end;PTEpiUDF=^TEpiUDF;
TEpiUDF=record
 ModuleId : integer;
 szUDFName:TEpiCommandString;
 szUDFCommandString:TEpiCommandString;
 szUDFDescription:TEpiCommandString;
 UDFID    :word;
 ExecuteUDF  :  TUDFFunction;
 ValidateParam: TUDFValidateFunction;
 ReturnType:TUDFReturnType;
 ParamCount  : Word;
end;
const
  Epi_OK=0;
  Epi_Cancel=1;  UDFReturnString=0;
  UDFReturnInteger=1;
  UDFReturnFloat=2;
  UDFReturnBoolean=3;implementationend.library epiGumm;uses
 sysutils,
  variants,
  epiUDFTypes in 'epiUDFTypes.pas';function gumm_add(x, y: integer): integer;
var
  z : integer;
begin
  if x<5 then
   begin
    z := x+y;
    if y<5 then
      gumm_add := z mod 5
    else
      gumm_add := (z mod 5)+5;
   end
  else
   begin
    if y<5 then
     begin
      z := x-y;
      gumm_add := (z mod 5)+5;
     end
    else
     begin
      z := x-y+5;
      gumm_add := z mod 5;
     end;
   end;
end;function gumm_phi(i,x : integer): integer;
var
  z: integer;
begin
  if x=0 then
    gumm_phi := 0
  else if x<5 then
   begin
    z := i mod 10;
    if (z mod 2)= 0 then
      gumm_phi := x
    else
      gumm_phi := 5-x;
   end
  else
   begin
    z := 3 * (i mod 10) + x;
    gumm_phi := (z mod 5) + 5;
   end;
end;function gumm_inv(x : integer): integer;
var
  z : integer;
begin
  if x<5 then
   begin
    z := 5-x;
    gumm_inv := z mod 5;
   end
  else
    gumm_inv := x;
end;function get_gumm_digit(id : real): integer;
var
  dig, summa, aux, k : integer;
  num : real;
begin
  summa := 0;
  num := id;
  k := 0;
  while num > 0 do
   begin
    k := k + 1;
    dig := round(Frac(num/10)*10);
    num := int(num/10);
    aux := gumm_phi(k, dig);
    summa := gumm_add(aux, summa);
  end;
  get_gumm_digit := gumm_inv(summa);
end;function verify_gumm_digit(id : real): boolean;
var
  gumm : integer;
  num  : real;
begin
  num := id;
  gumm := round(Frac(num/10)*10);
  num := int(num/10);
  verify_gumm_digit := (get_gumm_digit(num)=gumm);
end;procedure get_id(const ParamList:variant;var ReturnValue:variant);
var
 num : real;
 gummdigit : integer;
 va : variant;
begin
 va :=VarArrayCreate([0,0],Varvariant);
 va := ParamList;
 num := va[0];
 gummdigit := get_gumm_digit(num);
 ReturnValue:=VarAsType(num*10+gummdigit,  varDouble );
end;procedure get_gumm(const ParamList:variant;var ReturnValue:variant);
var
 num : real;
 gummdigit : integer;
 va : variant;
begin
 va :=VarArrayCreate([0,0],Varvariant);
 va := ParamList;
 num := va[0];
 gummdigit := get_gumm_digit(num);
 ReturnValue:=VarAsType(gummdigit,  varInteger );
end;procedure verify_gumm(const ParamList:variant;var ReturnValue:variant);
var
 num : real;
 gumm_ok : boolean;
 va : variant;
begin
 va :=VarArrayCreate([0,0],Varvariant);
 va := ParamList;
 num := va[0];
 gumm_ok := verify_gumm_digit(num);
 ReturnValue:=VarAsType(gumm_ok,  varBoolean );
end;function GetUDFCount:integer;
begin
  result:=3;
end;procedure GetUDFInfo(Const UDFid:integer; var functionString:variant;var ReturnType:variant;
       var FunctionName:variant;var ParamCount:integer);
begin
case  UDFid of
1:
begin
  functionString:= VarAsType('get_id',  varOleStr );
  ReturnType:=UDFReturnFloat;
  FunctionName:=VarAsType('get_id',  varOleStr );
  ParamCount:=1;
end;
2:
begin
  functionString:= VarAsType('get_gumm',  varOleStr );
  ReturnType:=UDFReturnInteger;
  FunctionName:=VarAsType('get_gumm',  varOleStr );
  ParamCount:=1;
end;
3:
begin
  functionString:= VarAsType('verify_gumm',  varOleStr );
  ReturnType:=UDFReturnBoolean;
  FunctionName:=VarAsType('verify_gumm',  varOleStr );
  ParamCount:=1;
end;
end;
end;
exports get_id index 1,
   get_gumm index 2,
   verify_gumm index 3,
   GetUDFCount index 4,
   GetUDFInfo index 5;begin
end.