/**********************************************/
/*                                            */    
/* iBackground.cpp                            */
/*                                            */
/* windows background management              */
/*                                            */
/* scol v 4                                   */
/*                                            */
/**********************************************/




#include <windows.h>
#include <stdio.h>
#include "defines.h"
#include "scolinstaller.h"
#include "iwinversion.h"







/*********************************************************************************/
/*                                                                               */
/*         C O N T E N T                                                         */
/*                                                                               */
/*                                                                               */
/* INTERNAL BODY                                                                 */
/*                                                                               */
/*    BOOL iBkg_initBitmap             ()                                        */
/*                                                                               */
/*    BOOL iBkg_applyBackground95NT4   ()                                        */
/*                                                                               */
/*    BOOL iBkg_applyBackgroundWindows ()                                        */
/*                                                                               */
/*                                                                               */
/*                                                                               */
/* EXTERNAL BODY                                                                 */
/*                                                                               */
/*    BOOL iBkg_applyBackground ()                                               */
/*                                                                               */
/*    BOOL iBkg_applyLogo       ()                                               */
/*                                                                               */
/*    BOOL iBkg_applyText       ()                                               */
/*                                                                               */
/*    BOOL iBkg_close           ()                                               */
/*                                                                               */
/*    BOOL iBkg_paint           ()                                               */
/*                                                                               */
/*                                                                               */
/*********************************************************************************/















/******************************************************************************************/
/*                                                                                        */
/*         D A T A                                                                        */
/*                                                                                        */
/******************************************************************************************/



PAINTSTRUCT MainPS;
HBITMAP bkgBitmap = NULL;



//gradient shading function
typedef BOOL (WINAPI *GRADIENTFILL) (HDC, PTRIVERTEX, ULONG, PVOID, ULONG, ULONG);
static GRADIENTFILL dll_pGradientFill	= NULL;


// 2 triangles to shade
TRIVERTEX vrt[4]; 
GRADIENT_TRIANGLE gTri[2];


//colors for triangle shading
TCHAR gc1[12];
int tmp1, tmp2, tmp3;
COLOR16 GCR1, GCG1, GCB1;
COLOR16 GCA1 = 0xFF00;
COLOR16 GCR2, GCG2, GCB2;
COLOR16 GCA2 = 0xFF00;
COLOR16 GCR3, GCG3, GCB3;
COLOR16 GCA3 = 0xFF00;
















/******************************************************************************************/
/*                                                                                        */
/*         I N T E R N A L      B O D Y                                                   */
/*                                                                                        */
/******************************************************************************************/




/*****************************************************/
/*                                                   */
/* BOOL iBkg_initBitmap ()                           */
/*                                                   */
/* initialize the bitmap background                  */
/*                                                   */
/* if fails, returns 0. if success, returns non zero */
/*                                                   */
/*****************************************************/  

BOOL iBkg_initBitmap ()
{
	if (!bkgBitmap)
	{
	HDC hwinDC = GetDC (MainHWND);

		bkgBitmap = CreateCompatibleBitmap (hwinDC, MainHWNDwidth, MainHWNDheight);
		ReleaseDC (MainHWND, hwinDC);
		if (!bkgBitmap)
			return 0;
	}

	return 1;
}









/*****************************************************/
/*                                                   */
/* BOOL iBkg_applyBackground95NT4 ()                 */
/*                                                   */
/* apply background on bitmap background             */
/*                                                   */
/* if fails, returns 0. if success, returns non zero */
/*                                                   */
/* only for Win 95 and Win NT4                       */
/*                                                   */
/*****************************************************/  

BOOL iBkg_applyBackground95NT4 ()
{
HBRUSH MainBrush;
COLORREF bkgColorRef;
DWORD tmp1, tmp2, tmp3;
HDC memDC;


	memDC = CreateCompatibleDC (NULL);

	//get background color
    sscanf (getvar ("BKG_COLOR"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
	bkgColorRef = RGB (tmp1, tmp2, tmp3);

	MainBrush = CreateSolidBrush (bkgColorRef);

    SelectObject (memDC, bkgBitmap);

	//apply color on background
	FillRect (memDC, &MainPS.rcPaint, MainBrush); 
 	SetBkColor(memDC, RGB(0,0,0x50));

	DeleteDC (memDC);

	return 1;
}










/*****************************************************/
/*                                                   */
/* BOOL iBkg_applyBackgroundWindows ()               */
/*                                                   */
/* apply background on bitmap background             */
/*                                                   */
/* if fails, returns 0. if success, returns non zero */
/*                                                   */
/* only for Win 98 / ME / 2000 / Whistler            */
/*                                                   */
/*****************************************************/  

BOOL iBkg_applyBackgroundWindows ()
{
HINSTANCE MSimgDLL;
HDC memDC;



    // get COLOR16 values from environnement variables

    sscanf (getvar ("BKG_GRADIENTCOLOR_1"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
	// low bytes become high bytes 
	GCR1 = (COLOR16) ((tmp1<<8) & 0xFF00);
	GCG1 = (COLOR16) ((tmp2<<8) & 0xFF00);
	GCB1 = (COLOR16) ((tmp3<<8) & 0xFF00);
	

    sscanf (getvar ("BKG_GRADIENTCOLOR_2"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
	// low bytes become high bytes 
	GCR2 = (COLOR16) ((tmp1<<8) & 0xFF00);
	GCG2 = (COLOR16) ((tmp2<<8) & 0xFF00);
	GCB2 = (COLOR16) ((tmp3<<8) & 0xFF00);

    sscanf (getvar ("BKG_GRADIENTCOLOR_3"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
	// low bytes become high bytes 
	GCR3 = (COLOR16) ((tmp1<<8) & 0xFF00);
	GCG3 = (COLOR16) ((tmp2<<8) & 0xFF00);
	GCB3 = (COLOR16) ((tmp3<<8) & 0xFF00);


	//open the dll
    MSimgDLL = LoadLibrary ("MSimg32.dll");

	if (!MSimgDLL)
		return 0;

	//get function pointer
	dll_pGradientFill =
        (GRADIENTFILL)GetProcAddress ( MSimgDLL , "GradientFill" ) ;

	if (dll_pGradientFill == NULL)
	{
		FreeLibrary (MSimgDLL);
		return 0;
	}


	//setting triangles for shading
	vrt[0].x = 0;	vrt[0].y = 0;
    vrt[1].x = 0;	vrt[1].y = MainHWNDheight-1;
	vrt[2].x = MainHWNDwidth-1;	vrt[2].y = MainHWNDheight-1;
	vrt[3].x = MainHWNDwidth-1; vrt[3].y = 0;

	vrt[0].Red  = GCR2;	vrt[0].Green = GCG2;	vrt[0].Blue  = GCB2;	vrt[0].Alpha = GCA2;
	vrt[1].Red  = GCR1;	vrt[1].Green = GCG1;	vrt[1].Blue  = GCB1;	vrt[1].Alpha = GCA1;
	vrt[2].Red  = GCR2;	vrt[2].Green = GCG2;	vrt[2].Blue  = GCB2;	vrt[2].Alpha = GCA2;
	vrt[3].Red  = GCR3;	vrt[3].Green = GCG3;	vrt[3].Blue  = GCB3;	vrt[3].Alpha = GCA3;

	gTri[0].Vertex1 = 0;	gTri[0].Vertex2 = 1;	gTri[0].Vertex3 = 2;
	gTri[1].Vertex1 = 0;	gTri[1].Vertex2 = 2;	gTri[1].Vertex3 = 3;


	//store the colors gradient 
	memDC = CreateCompatibleDC (NULL);
	SelectObject (memDC, bkgBitmap);
	dll_pGradientFill (memDC, vrt, 4, gTri, 2, GRADIENT_FILL_TRIANGLE);
	DeleteDC (memDC);

	FreeLibrary (MSimgDLL);


	return 1;
}














/******************************************************************************************/
/*                                                                                        */
/*         E X T E R N A L      B O D Y                                                   */
/*                                                                                        */
/******************************************************************************************/







/*****************************************************/
/*                                                   */
/* BOOL iBkg_applyBackground ()                      */
/*                                                   */
/* apply background on background bitmap             */
/*                                                   */
/* return 0 if fails, non zero if success            */
/*                                                   */
/*****************************************************/  

BOOL iBkg_applyBackground ()
{
	if (!iBkg_initBitmap())
		return 0;

	if ((iGetWinVersion() == I_WINVER_95) || (iGetWinVersion() == I_WINVER_NT4))
		return iBkg_applyBackground95NT4();
	else return iBkg_applyBackgroundWindows ();
}







/*****************************************************/
/*                                                   */
/* BOOL iBkg_applyLogo ()                            */
/*                                                   */
/* apply the logo defined by environnement variables */
/* on the background.                                */
/*                                                   */
/* return 0 if fails, non zero if success            */
/*                                                   */
/*****************************************************/  

BOOL iBkg_applyLogo ()
{
TCHAR logo  [256];        // filename
DWORD logoX, logoY;       // x and y coord on background
int tmp1, tmp2, tmp3;     // temp for env. var scanning
COLORREF transpPixel;     // transparency color
DWORD transpTolerance;    // tolerance of transparency color



	if (!iBkg_initBitmap())
		return 0;


	//get logo filename
	sprintf (logo, "%s\\", SRCDIR);
    strcat (logo,  getvar ("BKG_LOGO"));


	//get logo coord. on background
	sscanf (getvar ("BKG_LOGO_X"), "%d", &logoX);
	sscanf (getvar ("BKG_LOGO_Y"), "%d", &logoY);

	//get transparency color
    sscanf (getvar ("BKG_LOGO_TRANSPARENCY_COLOR"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
    transpPixel = RGB (tmp1, tmp2, tmp3);

	//get tolerance of transparency color
	sscanf (getvar ("BKG_LOGO_TRANSPARENCY_TOLERANCE"), "%d", &transpTolerance);


	

    if ((logo == NULL) || (!strcmp (logo, "")))
		return 0;
	
	{
	HBITMAP bmpLogo = NULL;

		//load logo bitmap
	    bmpLogo = (HBITMAP) LoadImage (0, logo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

		if (bmpLogo == NULL)
			return 0;

		{
		HDC bmpDC, memDC;
		BITMAP bmp;
		int i,j;
		COLORREF pixel;

			//dest
			memDC = CreateCompatibleDC (NULL);
			SelectObject (memDC, bkgBitmap);

			//source
			bmpDC = CreateCompatibleDC (NULL);
			GetObject (bmpLogo, sizeof(BITMAP), &bmp);
			SelectObject (bmpDC, bmpLogo);

			//for all pixels, copy source pixel into dest only if
			//if has to be copyied (<=> not transparent)
			for (i=0; i < bmp.bmWidth; i++)
				for (j=0; j < bmp.bmHeight; j++)
				{
					pixel = GetPixel (bmpDC, i, j);

					
					if (  (  (unsigned)(abs((pixel & 0x00FF0000)  - (transpPixel & 0x00FF0000))) > (unsigned)(transpTolerance<<16)   )
					   || (  (unsigned)(abs((pixel & 0x0000FF00)  - (transpPixel & 0x0000FF00))) > (unsigned)(transpTolerance<<8))
					   || (  (unsigned)(abs((pixel & 0x000000FF)  - (transpPixel & 0x000000FF))) > (unsigned)transpTolerance)
					   )
						SetPixel (memDC, logoX+i, logoY+j, pixel);
				}

			DeleteObject (&bmp);
			DeleteObject (bmpLogo);
			DeleteDC (bmpDC);
			DeleteDC (memDC);
		}
		

	}
	
	return 1;
}







/*****************************************************/
/*                                                   */
/* BOOL iBkg_applyText ()                            */
/*                                                   */
/* apply the text defined by environnement variables */
/* on the background.                                */
/*                                                   */
/* return 0 if fails, non zero if success            */
/*                                                   */
/*****************************************************/  

BOOL iBkg_applyText ()
{
COLORREF fontColorRef1, fontColorRef2, fontColorRef3;
HFONT MainFont;
DWORD fontX, fontY;
TCHAR fname [256];
TCHAR ftxt  [256];
DWORD fheight, fwidth, fweight;

DWORD tmp1, tmp2, tmp3;
HDC hmemDC;

	if (!iBkg_initBitmap())
		return 0;


	//get font name
    sprintf (fname, "%s", getvar ("BKG_TXTFONT"));

	//get text to print
	sprintf (ftxt, "%s", getvar ("BKG_TXTFONT_TXT"));

	//get font values (size, weight, ...)
	sscanf (getvar ("BKG_TXTFONT_HEIGHT"), "%d", &fheight);
	sscanf (getvar ("BKG_TXTFONT_WIDTH"), "%d", &fwidth);
	sscanf (getvar ("BKG_TXTFONT_WEIGHT"), "%d", &fweight);

	//get the 3 text colors
    sscanf (getvar ("BKG_TXTFONT_COLOR1"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
    fontColorRef1 = RGB (tmp1, tmp2, tmp3);
    sscanf (getvar ("BKG_TXTFONT_COLOR2"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
    fontColorRef2 = RGB (tmp1, tmp2, tmp3);
    sscanf (getvar ("BKG_TXTFONT_COLOR3"), "0x%2x%2x%2x", &tmp1, &tmp2, &tmp3);
    fontColorRef3 = RGB (tmp1, tmp2, tmp3);

	//get text coord. on background
	sscanf (getvar ("BKG_TXTFONT_X"), "%d", &fontX);
	sscanf (getvar ("BKG_TXTFONT_Y"), "%d", &fontY);


	//create font
    MainFont = CreateFont(fheight, fwidth, 0, 0, fweight, TRUE,FALSE,FALSE,DEFAULT_CHARSET,
      OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH, fname);


	hmemDC = CreateCompatibleDC (NULL);

    SelectObject (hmemDC, bkgBitmap);
	SelectObject (hmemDC, MainFont);
	SetBkMode(hmemDC, TRANSPARENT);

	//print text
	SetTextColor (hmemDC, fontColorRef3);
	TextOut (hmemDC, fontX+4, fontY+4, ftxt, strlen(ftxt));
	SetTextColor(hmemDC, fontColorRef2);
	TextOut(hmemDC, fontX+2, fontY+2, ftxt, strlen(ftxt));
	SetTextColor (hmemDC, fontColorRef1);
	TextOut (hmemDC, fontX, fontY, ftxt, strlen(ftxt));

	DeleteDC (hmemDC);
	DeleteObject (MainFont);

	return 1;	
}










/*****************************************************/
/*                                                   */
/* BOOL iBkg_close ()                                */
/*                                                   */
/* clean background objects                          */
/*                                                   */
/* return 0 if fails, non zero if success            */
/*                                                   */
/*****************************************************/  

BOOL iBkg_close()
{
	DeleteObject (bkgBitmap);
	bkgBitmap = NULL;
	return 1;
}








/*****************************************************/
/*                                                   */
/* BOOL iBkg_paint ()                                */
/*                                                   */
/* background paint callback                         */
/*                                                   */
/* return 0 if fails, non zero if success            */
/*                                                   */
/*****************************************************/

BOOL iBkg_paint ()
{
HDC hwinDC, hcDC;

    if (bkgBitmap)
	{
		hwinDC = GetDC (MainHWND);
		hcDC = CreateCompatibleDC (hwinDC);
		SelectObject (hcDC, bkgBitmap);
		BitBlt (hwinDC, 0, 0, MainHWNDwidth, MainHWNDheight, hcDC, 0, 0, SRCCOPY);
		DeleteDC (hcDC);
		ReleaseDC (MainHWND, hwinDC);
	}

	return 1;
}


