
with System;
with Interfaces.C;
pragma Warnings(Off);
with System.Win32;
pragma Warnings(On);
with Interfaces;                  use Interfaces;

with GWindows.GStrings;           use GWindows.GStrings;
with GWindows.GStrings.Handling;  use GWindows.GStrings.Handling;
with Gwindows.Types;              use Gwindows.Types;
with GWindows.GStrings.Constants; use GWindows.GStrings.Constants;
with GWindows.Application;        use GWindows.Application;
with GProfileConfig;              use GProfileConfig;

package body GWindows.AuxHelper is

   function GetVersionString return GString
   is
      szModuleFileName : GString_C := To_GString_C(GetAppFileName);
      dwHandle         : aliased System.Win32.DWORD;
      function GetFileVersionInfoSize(
				      lptstrFilename : access GChar_C := szModuleFileName(0)'Access;
				      lpdwHandle     : access System.Win32.DWORD := dwHandle'Access
				     ) return Integer;
      pragma Import (StdCall, GetFileVersionInfoSize,
		     "GetFileVersionInfoSize" & Character_Mode_Identifier);
      nInfoSize        : Integer := GetFileVersionInfoSize;
   begin
      if nInfoSize = 0 then
	 return "";
      end if;
      declare
	 VersionInfoData : Byte_Array(1 .. nInfoSize);
	 function GetFileVersionInfo(
			      lptstrFilename : access GChar_C := szModuleFileName(0)'Access;
			      dwHandleVal    : System.Win32.DWORD := dwHandle;
			      dwLen          : Integer := nInfoSize;
			      lpData         : access Unsigned_8 := VersionInfoData(1)'Access
			     ) return Integer;
	 pragma Import (StdCall, GetFileVersionInfo,
		 "GetFileVersionInfo" & Character_Mode_Identifier);
	 bRet            : Integer := GetFileVersionInfo;
	 szBS            : GString_C := To_GString_C("\");
	 type VS_FIXEDFILEINFO is record
	    dwSignature        : Unsigned_32;
	    dwStrucVersion     : Unsigned_32;
	    dwFileVersionMS    : Unsigned_32;
	    dwFileVersionLS    : Unsigned_32;
	    dwProductVersionMS : Unsigned_32;
	    dwProductVersionLS : Unsigned_32;
	    dwFileFlagsMask    : Unsigned_32;
	    dwFileFlags        : Unsigned_32;
	    dwFileOS           : Unsigned_32;
	    dwFileType         : Unsigned_32;
	    dwFileSubtype      : Unsigned_32;
	    dwFileDateMS       : Unsigned_32;
	    dwFileDateLS       : Unsigned_32;
	 end record;
	 type LPVS_FIXEDFILEINFO is access all VS_FIXEDFILEINFO;
	 lpFixVersInfo   : aliased LPVS_FIXEDFILEINFO;
	 uOutLength      : aliased Unsigned_32;
	 function VerQueryValue(
			 pBlock     : access Unsigned_8 := VersionInfoData(1)'Access;
			 lpSubBlock : access GChar_C := szBS(0)'Access;
			 lplpBuffer : access LPVS_FIXEDFILEINFO := lpFixVersInfo'Access;
			 puLen      : access Unsigned_32 := uOutLength'Access
			 ) return Integer;
	 pragma Import (StdCall, VerQueryValue,
		 "VerQueryValue" & Character_Mode_Identifier);
	 nFVersion0, nFVersion1, nFVersion2, nFVersion3 : Unsigned_32;
	 function Img4( V : Unsigned_32 ) return GString
	 is
	    sInterm : GString := Trim(Image(Integer(V)), GWindows.GStrings.Constants.Left);
	    nLength : Integer := sInterm'Length;
	 begin
	    case nLength is
	    when 1 =>
	       return "000" & sInterm;
	    when 2 =>
	       return "00" & sInterm;
	    when 3 =>
	       return "0" & sInterm;
	    when others =>
	       return sInterm;
	    end case;
	 end Img4;
      begin
	 pragma Assert(bRet /= 0);
	 bRet := VerQueryValue;
	 pragma Assert(bRet /= 0);
	 nFVersion0 := Shift_Right(lpFixVersInfo.dwFileVersionMS, 16);
	 nFVersion1 := lpFixVersInfo.dwFileVersionMS and 16#ffff#;
	 nFVersion2 := Shift_Right(lpFixVersInfo.dwFileVersionLS, 16);
	 nFVersion3 := lpFixVersInfo.dwFileVersionLS and 16#ffff#;
	 return Trim(Image(Integer(nFVersion0)), GWindows.GStrings.Constants.Left)
	   & "." & Trim(Image(Integer(nFVersion1)), GWindows.GStrings.Constants.Left)
	   & "." & Img4(nFVersion2) & "." & Img4(nFVersion3);
      end;
   end GetVersionString;

end GWindows.AuxHelper;
