- uses "Console" 
- uses "iNet" 
- uses "OS" 
-   
- printl "Connect to Firefox web site, determine latest Firefox version and download it" 
-   
- '---Check if computer is connected to internet 
- if INET_GetState Then 
-   '---Get Firefox web site page 
-   string Firefox_Info_Page = INET_UrlGetString("https://www.mozilla.org/en-US/firefox/new/") 
-   
-   '---Get Firefox available version 
-   string Firefox_Available_Version = grab$(Firefox_Info_Page, "data-latest-firefox=""", """") 
-   
-   '---Get Win64 direct download url 
-   string Firefox_DownLoad_Url_Win64 = grab$(Firefox_Info_Page, "<div id=""other-platforms"">", "</div>") 
-   Firefox_DownLoad_Url_Win64 = grab$(Firefox_DownLoad_Url_Win64, "<li class=""os_win64"">", "</li>") 
-   Firefox_DownLoad_Url_Win64 = grab$(Firefox_DownLoad_Url_Win64, "<a href=""", """") 
-   
-   printl "Firefox available version...:", Firefox_Available_Version 
-   printl "Firefox Download url........:", Firefox_DownLoad_Url_Win64 
-   
-   '---Download 
-   string sLocalFile = APP_SourcePath + "Firefox Setup " + Firefox_Available_Version + ".exe" 
-   
-   '---Initializes an application's use of the WinINet Internet functions. 
-   dword hInternet = INET_Internet_Open("Download Fireforx", %INTERNET_OPEN_TYPE_DIRECT) 
-   IF hInternet = %NULL THEN 
-     printl "INET_Internet_Open error" 
-     waitkey 
-     stop 
-   END IF 
-   
-   long MyContext = 1 
-   long hFile = INET_Internet_OpenUrl(hInternet, Firefox_DownLoad_Url_Win64, "", %INTERNET_FLAG_NO_CACHE_WRITE, MyContext) 
-   IF hFile = %NULL THEN 
-     printl "INET_Internet_OpenUrl error. Check url: " & Firefox_DownLoad_Url_Win64 
-     INET_Internet_CloseHandle hInternet 
-     waitkey 
-     stop 
-   END IF 
-   
- '---Set a callback for hInternet events. Driver will automatically call MyStatusFunction on status change 
-   long bResult = INET_Internet_SetStatusCallBack(hFile, MyStatusFunction) 
-   
- '---Query remote server about the size of the file we are going to download 
-   long FileSize = INET_Http_QueryInfo(hFile, %HTTP_QUERY_CONTENT_LENGTH) 
-   printl "Real file size in bytes: " & FileSize 
-   IF FileSize = %NULL THEN 
-     printl "INET_Http_QueryInfo(hInternet, %HTTP_QUERY_CONTENT_LENGTH) error. Check url: " & Firefox_DownLoad_Url_Win64 
-     INET_Internet_CloseHandle hInternet 
-     INET_Internet_CloseHandle hFile 
-     waitkey 
-     stop 
-   END IF 
-   
-      
- '---Ok we can start a loop for file download. This can be automated in a loop or in a timer function 
- '---Reads the data in %BufferLen bytes chunks 
-   double T0 = timer 
-   double T1 
-    
-   '---Setup a %BufferLen bytes buffer 
-     long  lBufferLen    = 500000 '500k 
-     string strBuffer    = STRING$(lBufferLen, $SPC) 
-     dword pstrBuffer    = STRPTR(strBuffer) 
-     String strData 
-     dword cbBytesRead    
-     DWord TotalBytesRead 
-     long  lScreenLine   = 8 
-     long  lScreenPos    = 20 
-   
-   string sSave = Console_SaveScreen(1, 1, 80, 24) 
-   Console_Box(lScreenPos - 1, lScreenLine - 1, 40, 8, 24, 24, "Downloading ...", 26, %Console_BOX_FLAG_3DOFF) 
-   DO 
-     bResult = INET_Internet_ReadFile(hFile, pstrBuffer, len(strBuffer), cbBytesRead) 
-     IF bResult = 0 OR cbBytesRead = 0 THEN EXIT DO 
-     IF cbBytesRead = LEN(strBuffer) THEN 
-       strData &= strBuffer 
-     ELSE 
-       strData &= LEFT$(strBuffer, cbBytesRead) 
-     END IF 
-     TotalBytesRead += cbBytesRead 
-     T1 = Timer 
-      
-     PrintAt "Elapsed seconds  : " & LSet$(Format$(T1-T0, "0"), 19)                                         , lScreenPos + 1, lScreenLine + 1, 24 
-     PrintAt "Bytes read so far: " & LSet$(TotalBytesRead, 19)                                              , lScreenPos + 1, lScreenLine + 2, 24 
-     PrintAt "KBytes per second: " & LSet$(Format$((TotalBytesRead / Max(T1-T0, 1))/1024, "0.00"), 19)      , lScreenPos + 1, lScreenLine + 3, 24 
-     PrintAt "Estimated seconds: " & LSet$(Format$((FileSize * (T1-T0))/TotalBytesRead, "0"), 19)           , lScreenPos + 1, lScreenLine + 4, 24 
-     PrintAt "Seconds to go    : " & LSet$(Format$(((FileSize * (T1-T0))/TotalBytesRead)-(T1-T0), "0"), 19) , lScreenPos + 1, lScreenLine + 5, 24 
-      
-     Console_ProgressBar(1, lScreenPos + 1, lScreenLine + 7, 40-1, 27, 1, FileSize, TotalBytesRead) 
-   LOOP 
-   
-   Console_RestoreScreen(1, 1, 80, 24, sSave) 
-   
- '---Closes all used handles 
-   INET_Internet_CloseHandle hInternet 
-   INET_Internet_CloseHandle hFile 
-   
-   
-   printl "Saving file: " & sLocalFile 
-   Save_File(sLocalFile, strData) 
-   
-   printl "File saved." 
-   printl 
-   printl "Press ESC to end or any other key within 10 secs to execute setup" 
-   
-   
-   '---Ask if execute setup 
-   string sUserReply = WaitKey(10) 
-   if sUserReply <> "[ESC]" and sUserReply <> "[TIMEOUT]" Then 
-     printl "Executing " + sLocalFile 
-     OS_Shell(sLocalFile, %OS_WNDSTYLE_NORMAL, %OS_SHELL_SYNC) 
-   Else 
-     printl "No execution. Execute manually if needed." 
-   end If 
-   
- Else 
-   printl "! it seems you are not connected to internet." in %CCOLOR_FLIGHTRED 
- end If 
-   
- printl "---All done, press a key to end or wait 5 secs---" 
- WaitKey(5) 
-   
-   
- '------------------------------------------------------------------ 
- ' CallBack function automatically called by Internet driver when 
- ' status change for a specific Internet handle to which a callback 
- ' function has been installed. 
- ' Parameters are mandatory and are defined my Microsoft 
- ' callback template. More info at: http://msdn.microsoft.com/en-us/library/aa385121(VS.85).aspx 
- '------------------------------------------------------------------ 
- callback function MyStatusFunction( _ 
-                 byval hInternet                 as long , _   '---Mandatory in thinBasic and in API 
-                 byval dwContext                 as long , _   '---Mandatory in thinBasic and in API 
-                 byval dwInternetStatus          as long , _   '---Mandatory in thinBasic and in API 
-                 byval lpvStatusInformation      as long , _   '---Optional in thinBasic, mandatory in API 
-                 byval dwStatusInformationLength as long   _   '---Optional in thinBasic, mandatory in API 
-              ) as long 
- '------------------------------------------------------------------ 
-   dim BytesReceived     as dword at 0 
-   static TotBytes       as dword 
-   
-   static MoreStatusLine as long = 20 
-        
-   'printat "Data from " & function_name & " callback"          , 1, 17 
-   'printat "  Internet handle: " & hInternet & "  Internet dwContext: " & dwContext, 1, 18 
-   
-   select case dwInternetStatus  
-     case %INTERNET_STATUS_RECEIVING_RESPONSE 
-   
-     case %INTERNET_STATUS_RESPONSE_RECEIVED 
-       '---  Successfully received a response from the server. 
-       '---  The lpvStatusInformation parameter points to a DWORD value that contains the number, in bytes, received. 
-       setat(BytesReceived, lpvStatusInformation) 
-       TotBytes += BytesReceived 
-   
-       '---ATTENTION: TotalBytes received can differ from total bytes of the file to be downloaded 
-   
-       'printat "  Receiving data (" & dwInternetStatus & " " & INET_Internet_StatusGetDescription(dwInternetStatus) & ") TotBytes: " & TotBytes, 1, 19 
-   
-     case else 
-       '---In case of other status, just decode it at the bottom. 
-       'printat "  (" & dwInternetStatus & " " & INET_Internet_StatusGetDescription(dwInternetStatus) & ")", 1, MoreStatusLine 
-       incr MoreStatusLine 
-   
-   end select             
-   
-   
- end function 
-   
-