void MainWindow::OnPaint( wxPaintEvent& event )
{
	wxPaintDC dc(wxDynamicCast(event.GetEventObject(), wxWindow)); 

	int id = wxDynamicCast(event.GetEventObject(), wxWindow)->GetId();
	BlendingModeRef blendingmode = _blendingModes->GetBlendingModeByBitmapId(id);
	std::string s = blendingmode.GetRenderModeLabel();
	
	WXHDC wxHDC = wxPaintDC::FindDCInCache((wxWindow*) event.GetEventObject());
	HDC hDC = (HDC) wxHDC;

	bool isCacheAvailable = _cachedOutputBitmaps.find(id) != _cachedOutputBitmaps.end();
	if (isCacheAvailable) {
		// Cache available
		BITMAP *cachedBmp = _cachedOutputBitmaps.find(id)->second;
		draw_to_hdc(hDC, cachedBmp, 0, 0); 
		return;
	}

	BITMAP *imageBitmap = create_bitmap(250, 188);
	clear_to_color(imageBitmap, makecol(0, 0, 0));

	BITMAP *baseBitmap = load_bitmap("images/Base_250x188.bmp", NULL);
	BITMAP *blendBitmap = load_bitmap("images/Blend_250x188.bmp", NULL);

	blit(baseBitmap, baseBitmap, 0, 0, 0, 0, baseBitmap->w, baseBitmap->h);
	
	wxString type(blendingmode.GetRenderModeLabel().c_str(), wxConvUTF8);
	for (int w=0; w<baseBitmap->w; w++) {
		for (int h=0; h<baseBitmap->h; h++) {
			if (type.IsSameAs(_T("Lighten"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_lighten);
			} else if (type.IsSameAs(_T("Darken"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_darken);
			} else if (type.IsSameAs(_T("Multiply"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_multiply);
			} else if (type.IsSameAs(_T("Average"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_average);
			} else if (type.IsSameAs(_T("Add"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_add);
			} else if (type.IsSameAs(_T("Subtract"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_subtract);
			} else if (type.IsSameAs(_T("Difference"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_difference);
			} else if (type.IsSameAs(_T("Negation"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_negation);
			} else if (type.IsSameAs(_T("Screen"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_screen);
			} else if (type.IsSameAs(_T("Exclusion"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_exclusion);
			} else if (type.IsSameAs(_T("Overlay"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_overlay);
			} else if (type.IsSameAs(_T("SoftLight"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_softlight);
			} else if (type.IsSameAs(_T("HardLight"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_hardlight);
			} else if (type.IsSameAs(_T("ColorDodge"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_colordodge);
			} else if (type.IsSameAs(_T("ColorBurn"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_colorburn);
			} else if (type.IsSameAs(_T("LinearDodge"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_lineardodge);
			} else if (type.IsSameAs(_T("LinearBurn"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_linearburn);
			} else if (type.IsSameAs(_T("LinearLight"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_linearlight);
			} else if (type.IsSameAs(_T("VividLight"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_vividlight);
			} else if (type.IsSameAs(_T("PinLight"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_pinlight);
			} else if (type.IsSameAs(_T("HardMix"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_hardmix);
			} else if (type.IsSameAs(_T("Reflect"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_reflect);
			} else if (type.IsSameAs(_T("Glow"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_glow);
			} else if (type.IsSameAs(_T("Phoenix"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_phoenix);
			} else if (type.IsSameAs(_T("Hue"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_hue);
			} else if (type.IsSameAs(_T("Saturation"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_saturation);
			} else if (type.IsSameAs(_T("Color"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_color);
			} else if (type.IsSameAs(_T("Luminosity"))) {
				put_blended_pixel(baseBitmap, w, h, getpixel(blendBitmap, w, h), blender_luminosity);
			}
		}
	}

	draw_to_hdc(hDC, baseBitmap, 0, 0); 
	
	// Store in cache
	_cachedOutputBitmaps[id] = baseBitmap;

	destroy_bitmap(imageBitmap);
	destroy_bitmap(blendBitmap);
}
void __fastcall TMainCaptureForm::DoFrame(BITMAP *aBmp, HANDLE hmut)
{

		bool paint = false;

		if(hmut == hMutex) {
			if(CaptureWorkerForm->nFrames % frameDivisor == 0)	paint = true;
			if(paint) {
				edFrame->Text = CaptureWorkerForm->nFrames;
				edTimestamp->Text = CaptureWorkerForm->timestamp;
				stretch_blit(aBmp, bmpCanvas,
					0,0, aBmp->w, aBmp->h,
					0,0, bmpCanvas->w,bmpCanvas->h);

				HWND hWnd = tPanel->Handle;
				HDC  hDC  = GetDC(hWnd);
				draw_to_hdc (hDC,bmpCanvas,0,0);
				ReleaseDC(hWnd,hDC);

			}
		}

		if(hmut == hMutex1) {
			if(CaptureWorkerForm1->nFrames % frameDivisor == 0)	paint = true;
			if(paint) {
				stretch_blit(aBmp, bmpCanvas1,
					0,0, aBmp->w, aBmp->h,
					0,0, bmpCanvas1->w,bmpCanvas1->h);

				HWND hWnd = tPanel1->Handle;
				HDC  hDC  = GetDC(hWnd);
				draw_to_hdc (hDC,bmpCanvas1,0,0);
				ReleaseDC(hWnd,hDC);

			}
		}

		if(hmut == hMutex2) {
			if(CaptureWorkerForm2->nFrames % frameDivisor == 0)	paint = true;
			if(paint) {
				stretch_blit(aBmp, bmpCanvas2,
					0,0, aBmp->w, aBmp->h,
					0,0, bmpCanvas2->w,bmpCanvas2->h);

				HWND hWnd = tPanel2->Handle;
				HDC  hDC  = GetDC(hWnd);
				draw_to_hdc (hDC,bmpCanvas2,0,0);
				ReleaseDC(hWnd,hDC);
	
			}
		}

		if(hmut == hMutex3) {
			if(CaptureWorkerForm3->nFrames % frameDivisor == 0)	paint = true;
			if(paint) {
				stretch_blit(aBmp, bmpCanvas3,
					0,0, aBmp->w, aBmp->h,
					0,0, bmpCanvas3->w,bmpCanvas3->h);

				HWND hWnd = tPanel3->Handle;
				HDC  hDC  = GetDC(hWnd);
				draw_to_hdc (hDC,bmpCanvas3,0,0);
				ReleaseDC(hWnd,hDC);

			}
		}



}