#include "sgl.h"
#include <stdio.h>
#include <math.h>

#pragma warn(disable: 2118 2216)	/* disable some warnings					*/
				/* 2118: Parameter {parameter_name} is not referenced.			*/
				/* 2216: The return value from {function_name} is never used.	*/

/*================================================================= BAR GRAPH ==*/

typedef struct bargraph_t_
{
	HWND caption, bar ;
	double dMin, dMax;
	double dValue ;
	char aValue[16] ;
} BARGRAPH_T ;

static int bargraphCB(HWND hwnd, UINT event, WPARAM wParam, LPARAM lParam)
{
	if (event == WM_PAINT)
	{
		BARGRAPH_T *bargraph ;
		SGL_CallbackDataGet(hwnd, (void**) &bargraph) ;

		PAINTSTRUCT ps ;
		HDC hdc = BeginPaint(hwnd, &ps) ;

		RECT rect = ps.rcPaint ;
		int p = rect.left + lround((rect.right - rect.left)
									* (bargraph->dValue - bargraph->dMin)
									/ (bargraph->dMax - bargraph->dMin)) ;
		rect.right = p ;
		if (bargraph->dValue < (bargraph->dMax + bargraph->dMin) / 2)
			SetDCBrushColor(hdc, 0x00ffff) ;
		else
			SetDCBrushColor(hdc, 0x5555ff) ;
		FillRect(hdc, &rect, GetStockObject(DC_BRUSH)) ;

		rect.left = p ;
		rect.right = ps.rcPaint.right ;
		SetDCBrushColor(hdc, 0xc0c0c0) ;
		FillRect(hdc, &rect, GetStockObject(DC_BRUSH)) ;

		SelectObject(hdc, SGL_FontHandleGet(hwnd, -1, -1)) ;
		SetBkMode(hdc, TRANSPARENT) ;

		DrawText(hdc, bargraph->aValue, -1, &ps.rcPaint, 
					DT_SINGLELINE | DT_VCENTER | DT_CENTER) ;

		EndPaint(hwnd, &ps) ;
		return 0 ;
	}

	return 0 ;
}

void bargraphSet(BARGRAPH_T* bargraph, double dValue)
{
	if (bargraph)
	{
		bargraph->dValue = dValue ;
		sprintf(bargraph->aValue, "%.0f", bargraph->dValue) ;
		SGL_Redraw(bargraph->bar) ;
	}
}

BARGRAPH_T* bargraphNew(HWND parent, char *title,
						int c, int r,					/* position in parent	*/
						double dMin, double dMax,		/* min, max values		*/
						TIMERPROC lpTimerFunc)			/* timer procedure		*/
{
	BARGRAPH_T *bargraph = calloc(1, sizeof(BARGRAPH_T)) ;
	if (bargraph)
	{
		HWND panel = SGL_New(parent, SGL_HIDDENFRAME, 0, "Bar graph", c, r);
		SGL_AlignmentSet(panel, 0) ;

		bargraph->caption = SGL_New(panel, SGL_CTRL_EDIT,
										   ES_RIGHT | ES_READONLY, title, 0, 0);
		SGL_SizeSet(bargraph->caption, SGL_WIDTH, -5);
		SGL_SizeSet(bargraph->caption, SGL_HEIGHT, -1);
		SGL_EditTextSet(bargraph->caption, title);

		bargraph->bar = SGL_New(panel, SGL_CTRL_BUTTON, 0, "Bar", 1, 0);
		SGL_CallbackFunctionSet(bargraph->bar, bargraphCB) ;
		SGL_CallbackDataSet(bargraph->bar, bargraph) ;

		bargraph->dValue = dMin ;						/* start value			*/
		bargraph->dMin = dMin ;
		bargraph->dMax = dMax ;

		SetTimer(bargraph->bar, 1, 500, lpTimerFunc) ;	/* 3rd arg: period (ms)	*/
	}
	return bargraph ;
}

/*==============================================================================*/

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
	BARGRAPH_T *bg ;
	SGL_CallbackDataGet(hwnd, (void*) &bg) ;
	double u = (double) rand() / RAND_MAX ;
	u = bg->dMin + u * (bg->dMax - bg->dMin) ;
	u = 0.1 * u + 0.9 * bg->dValue	;
	bargraphSet(bg, u) ;
}

#define BAR_GRAPH_NB 4								/* number of bar graphs 	*/

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	SGL_Init(hInstance, NULL);
	HWND mainPanel = SGL_New(0, SGL_PANEL, 0, "SGL - Bar graph demo", -1, -1);

	BARGRAPH_T *bargraph[BAR_GRAPH_NB] ;			/* create bar graphs		*/
	char l[BAR_GRAPH_NB][32];
	for (int i = 0 ; i < BAR_GRAPH_NB ; i++)
	{
		sprintf(l[i], "Temp %d (°C)", i) ;
		bargraph[i] = bargraphNew(mainPanel, l[i], 0, i, 200, 1000, TimerProc) ;
	}

	SGL_Layout(mainPanel);
	SGL_VisibleSet(mainPanel, 1);
	SGL_Run();

	SGL_Exit();
	return 0;
}
