// ScolInstaller.cpp: implementation of the ScolInstaller class.
//
// T.Delprat : 08/08/2001
// Gestion du téléchargement et de l'installation de Scol
//////////////////////////////////////////////////////////////////////

#include "ScolInstaller.h"


bool CALLBACK InstallDlgProc (HWND hwnddialog,UINT iMsg,WPARAM wParam,LPARAM lParam);
bool CALLBACK DownloadDlgProc (HWND hDlg,UINT iMsg,WPARAM wParam,LPARAM lParam);

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ScolInstaller::ScolInstaller(const char * DWURL, const long Size)
{
//::MessageBox(NULL,"ScolInstaller Constructor!","Debug",0);
//char Buf[255];
//sprintf(Buf,"Dll Hinstance=%d",PlugInDllHINSTANCE);
//::MessageBox(NULL,Buf,"Debug",0);

strcpy(m_strDownloadURL,DWURL);
m_longDownloadSize = Size;

}

ScolInstaller::~ScolInstaller()
{
//	::MessageBox(NULL,"Scol Installer destroyed","DEBUG",0);
}

//////////////////////////////////////////////////////////////////////
// Read Accessor for m_strDownloadURL


//////////////////////////////////////////////////////////////////////
// Lance le téléchargement et l'installation de Scol
bool ScolInstaller::LaunchInstaller(HWND PlugHWND)
{
	int res;

	res=DialogBoxParam(PlugInDllHINSTANCE, MAKEINTRESOURCE(INSTALLSCOL),PlugHWND,(DLGPROC)InstallDlgProc,(LPARAM)this);
	if (res==-1)
	{
		LPVOID lpMsgBuf;
		FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
		FORMAT_MESSAGE_FROM_SYSTEM | 
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
		);
	// Display the string.
	::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
	// Free the buffer.
	LocalFree( lpMsgBuf );
	}

	if (res)
	{
		return true;
	}
	else
	{
		::MessageBox(NULL,"The installation was aborted.","Error!",0);
		return false;
	}
return true;

}

//////////////////////////////////////////////////////////////////////
// Gère la boite de dialogue pour le lancement de l'installation de Scol
//bool CALLBACK InstallDlgProc (HWND hwnddialog,UINT iMsg,WPARAM wParam,LPARAM lParam)
bool CALLBACK InstallDlgProc (HWND hwnddialog,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
  HWND hDlg;

  bool resDW;
  char InstallFileName[MAX_PATH];

  switch (iMsg)
  {
  case WM_INITDIALOG:
		{
		hDlg=(HWND)CreateDialogParam(PlugInDllHINSTANCE,MAKEINTRESOURCE(DOWNLOADSCOL),hwnddialog,(DLGPROC)DownloadDlgProc,lParam);
		if (hDlg==NULL)
		{
			LPVOID lpMsgBuf;
			FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(LPTSTR) &lpMsgBuf,
			0,
			NULL 
			);
		// Display the string.
		::MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error;creating INSTWIN", MB_OK | MB_ICONINFORMATION );
		// Free the buffer.
		LocalFree( lpMsgBuf );
		}
		
		::ShowWindow(hDlg,SW_SHOWNORMAL);
		//::MessageBox(hwnddialog,"New Window Created... Start DW","DEbug",0);

		//Launch Download
		resDW=((ScolInstaller *)lParam)->DownloadFile(hDlg,InstallFileName);
		
		DestroyWindow(hDlg);
		SetFocus(hwnddialog);
		
		//::MessageBox(hwnddialog,"Download End","DEBUG",0);
		
		if(resDW)
		{
			::ShowWindow(hwnddialog,SW_SHOWNORMAL);
			SetDlgItemText(hwnddialog,DL_STATUS,"Opening Scol setup...");
			UpdateWindow(hwnddialog);
			EndDialog(hwnddialog,true);
			resDW=((ScolInstaller *)lParam)->ExecInstall(InstallFileName);
			//if(resDW)
			//	EndDialog(hwnddialog,true);
			//else
			//	EndDialog(hwnddialog,false);
		}
		else
			EndDialog(hwnddialog,false);
		}
		return false;
		break;
	}
	UpdateWindow(hwnddialog);
	return true;
}

//////////////////////////////////////////////////////////////////////
// Gère la boite de dialogue de téléchargement de l'archive d'instalation
//bool CALLBACK DownloadDlgProc (HWND hDlg,UINT iMsg,WPARAM wParam,LPARAM lParam)
bool CALLBACK DownloadDlgProc (HWND hDlg,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
  switch (iMsg)
  {
  case WM_INITDIALOG:
	return true;
  }
  return false;
}



/////////////////////////////////////////////////////////////////////
// Main download loop
//bool DownloadLoop(HWND hX, HINTERNET hResource,FILE* file)
bool ScolInstaller::DownloadLoop(HWND hX, HINTERNET hResource,FILE* file)
{
  LPSTR     lpszData;          // buffer for the data
  DWORD     dwSize;               // size of the data available
  DWORD     dwDownloaded;     // size of the downloaded data
  DWORD     dwSizeSum=0;     // size of the data in the textbox

  // Set the cursor to an hourglass.
  SetCursor(LoadCursor(NULL,IDC_WAIT));

  PostMessage(GetDlgItem(hX,IDC_PROGRESS1),PBM_SETRANGE,0,MAKELPARAM(0,100));
  PostMessage(GetDlgItem(hX,IDC_PROGRESS1),PBM_SETPOS,0,0);
  PostMessage(GetDlgItem(hX,IDC_PROGRESS1),PBM_SETSTEP,1,0);

  // This loop handles reading the data.       
  do     
  {
    // The call to InternetQueryDataAvailable determines the amount of 
    // data available to download.
    if (!InternetQueryDataAvailable(hResource,&dwSize,0,0))          
    {
//      ErrorOut(hX,GetLastError(),"InternetReadFile");
      SetCursor(LoadCursor(NULL,IDC_ARROW));
      return false;          
    }          
    else          
    {     
      // Allocates a buffer of the size returned by InternetQueryDataAvailable
      lpszData = new char[dwSize];
      // Reads the data from the HINTERNET handle.
      if(!InternetReadFile(hResource,(LPVOID)lpszData,dwSize,&dwDownloaded))
      {
//        ErrorOut(hX,GetLastError(),"InternetReadFile");
        delete[] lpszData;                    
        break;               
      }
      else               
      {
        // Writes the holding buffer to the textbox
//        SetDlgItemText(hX,intCtrlID,(LPSTR)lpszHolding);
        if (fwrite( lpszData, 1, dwSize, file)!=dwSize)
        {
          ::MessageBox(NULL,"File Write failed.","File Error",0);
          delete[] lpszData;                    
          return false;
        }
//  PostMessage(GetDlgItem(hwnddialog,IDC_FILEPROGRESS),PBM_SETSTEP,1,0);
        PostMessage(GetDlgItem(hX,IDC_PROGRESS1),PBM_SETPOS,dwSizeSum*100/m_longDownloadSize,0);
        {
          char b[80];
          MSG msg;
          sprintf(b,"%d Kb",dwSizeSum/1024);
          SetDlgItemText(hX,DL_STATUS,b);
          UpdateWindow(hX);

          for (int truc=0;truc<5;truc++)
          {
            if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
            {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
            }
          }
        }
        // Delete the two buffers
        delete[] lpszData;
        // Add the size of the downloaded data to the textbox data size
        dwSizeSum = dwSizeSum + dwDownloaded + 1;
        // Check the size of the remaining data.  If it is zero, break.
        if (dwDownloaded == 0)                         
          break;
      }          
    }     
  } while(true);
  // Close the HINTERNET handle     
  InternetCloseHandle(hResource);
  // Set the cursor back to an arrow
  SetCursor(LoadCursor(NULL,IDC_ARROW));   
 
  // Return     
  return true;
}

////////////////////////////////////////////////////////////////////////
// Download Auto-installation exe file
bool ScolInstaller::DownloadFile(HWND hDlg,char * InstallFileName)
{
HINTERNET InetSession;
HINTERNET Download;
FILE* hLocalFile;
char LocalFileName[MAX_PATH];

InetSession=InternetOpen("SCOL Installer",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);

// Opening Inet Session
SetDlgItemText(hDlg,DL_STATUS,"Opening Internet Session...");
UpdateWindow(hDlg);
//::MessageBox(hDlg,"Download begins...","DEBUG",0);

if (!InetSession) 
{
	char buf[80];
	char errMsg[255];
	unsigned long i=80,e;
	InternetGetLastResponseInfo(&e,buf,&i);
	sprintf(errMsg,"Unable to open Internet Session : \n%s",buf);
	::MessageBox(NULL,errMsg,"Error!",NULL);
	return false;
}

// Opening Download URL
SetDlgItemText(hDlg,DL_STATUS,"Contacting server...");
UpdateWindow(hDlg);
//::MessageBox(hDlg,"Opening Download","DEBUG",0);
//::MessageBox(hDlg,m_strDownloadURL,"DEBUG: URL=",0);

Download=InternetOpenUrl(InetSession,m_strDownloadURL,NULL,-1,0 ,0);
if (!Download) 
{
	char buf[80];
	char errMsg[255];
	unsigned long i=80,e;
	InternetGetLastResponseInfo(&e,buf,&i);
	sprintf(errMsg,"Unable to open Internet Session : \n%s",buf);
	::MessageBox(NULL,errMsg,"Error!",NULL);
	return false;
}

// Creating Local File
SetDlgItemText(hDlg,DL_STATUS,"Creating local file");
UpdateWindow(hDlg);
LocalFileName[0] = '\0';
strcpy(LocalFileName,_tempnam(NULL,"scol"));
strcat (LocalFileName,".exe");
hLocalFile=fopen(LocalFileName,"wb");
if (!hLocalFile)
{
    ::MessageBox(NULL,"Unable to open a local file.","Error",0);
    return false;
}

//Lauch download loop
if (DownloadLoop(hDlg,Download,hLocalFile))
	{
	fclose(hLocalFile);
	strcpy(InstallFileName,(const char*)LocalFileName);
//	::MessageBox(NULL,LocalFileName,"DW OK",0);
	return true;
	}
else
	{
	fclose(hLocalFile);
//	::MessageBox(NULL,LocalFileName,"DW Error",0);
	return false;
	}
}


/////////////////////////////////////////////////////////////
// Lauch Scol Setup and wait for it's end
bool ScolInstaller::ExecInstall(char * ExeName)
{
STARTUPINFO StartInfo;    
PROCESS_INFORMATION ProcInfo;    

//::MessageBox(NULL,ExeName,"Try to Exec",0);

ZeroMemory( &StartInfo, sizeof(StartInfo) );

StartInfo.cb = sizeof(StartInfo);        
if (!CreateProcess(  
          NULL,// pointer to name of executable module
          ExeName,  // pointer to command line string
          NULL,  // process security attributes
          NULL,   // thread security attributes
          FALSE,  // handle inheritance flag
          0, // creation flags
          NULL,  // pointer to new environment block
          NULL,   // pointer to current directory name
          &StartInfo,  // pointer to STARTUPINFO
          &ProcInfo   // pointer to PROCESS_INFORMATION
        ))
{


		LPVOID lpMsgBuf;
		FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
		FORMAT_MESSAGE_FROM_SYSTEM | 
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
		(LPTSTR) &lpMsgBuf,
		0,
		NULL
		);

		MessageBox(NULL,"Could not execute install program...","Install Error.",0);
		//MessageBox(NULL,(LPTSTR)lpMsgBuf,"Err",0);
      return false;
};

WaitForSingleObject( ProcInfo.hProcess, INFINITE );
// Close process and thread handles.     
CloseHandle( ProcInfo.hProcess );
CloseHandle( ProcInfo.hThread );
return true;
}