#include "Common.h"
#include <string>
#include <iostream>

using namespace CALIB; 
using namespace std;

int CALIB::Common::doubleNum(int num,bool up)
{
	if(up)
		num = num * 2;
	else
		num = num / 2;
	return num;
}

void CALIB::Common::countCoordinates(int index,int srcX,int srcY,int * dstX,int *dstY,bool inverseY)
{
	if(inverseY)
	{
		switch(index)
		{
			case UPPER_LEFT:
				*dstY = srcY;
				break;
			case UPPER_RIGHT:
				*dstX = srcX;
				*dstY = srcY;
				break;				
			case BOTTOM_RIGHT:
				*dstX = srcX;
				break;
			default:			
				break;
		}
		return;
	}
	switch(index)
	{
		case UPPER_RIGHT:
			*dstX = srcX;
			break;
		case BOTTOM_LEFT:
			*dstY = srcY;
			break;
		case BOTTOM_RIGHT:
			*dstX = srcX;
			*dstY = srcY;
			break;
		default:			
			break;
	}
}

float CALIB::Common::convertUnsignedCharToFloat(unsigned char value)
{
	float result = value;
	if(result < 0)
		result += CHAR_LENGHT;
	return result;
}

//void CALIB::Common::TakeScreenShot(char* filename)
//{
//	keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0);
//	keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
//	HBITMAP h;
//
//	OpenClipboard(NULL);
//	h = (HBITMAP) GetClipboardData(CF_BITMAP);
//	CloseClipboard();
//	HDC hdc = NULL;
//	FILE *fp = NULL;
//	LPVOID pBuf = NULL;
//	BITMAPINFO bmpInfo;
//	BITMAPFILEHEADER bmpFileHeader;
//	do {
//		hdc = GetDC(NULL);
//		ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
//		bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//		GetDIBits(hdc, h, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS);
//		if (bmpInfo.bmiHeader.biSizeImage <= 0)
//			bmpInfo.bmiHeader.biSizeImage = bmpInfo.bmiHeader.biWidth
//					* abs(bmpInfo.bmiHeader.biHeight)
//					* (bmpInfo.bmiHeader.biBitCount + 7) / 8;
//		if ((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) {
//			MessageBox(NULL, "Unable to Allocate Bitmap Memory", "Error",
//					MB_OK | MB_ICONERROR);
//			break;
//		}
//		bmpInfo.bmiHeader.biCompression = BI_RGB;
//		GetDIBits(hdc, h, 0, bmpInfo.bmiHeader.biHeight, pBuf, &bmpInfo,
//				DIB_RGB_COLORS);
//		if ((fp = fopen(filename, "wb")) == NULL) {
//			MessageBox(NULL, "Unable to Create Bitmap File", "Error",
//					MB_OK | MB_ICONERROR);
//			break;
//		}
//		bmpFileHeader.bfReserved1 = 0;
//		bmpFileHeader.bfReserved2 = 0;
//		bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER)
//				+ sizeof(BITMAPINFOHEADER) + bmpInfo.bmiHeader.biSizeImage;
//		bmpFileHeader.bfType = 'MB';
//		bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)
//				+ sizeof(BITMAPINFOHEADER);
//		fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
//		fwrite(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp);
//		fwrite(pBuf, bmpInfo.bmiHeader.biSizeImage, 1, fp);
//	}
//
//	while (false);
//	if (hdc)
//		ReleaseDC(NULL, hdc);
//	if (pBuf)
//		free (pBuf);
//	if (fp)
//		fclose(fp);
//}


int CALIB::Common::GetEncoderClsid(WCHAR *format, CLSID *pClsid)
{
        unsigned int num = 0,  size = 0;
        GetImageEncodersSize(&num, &size);
        if(size == 0) return -1;
        ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
        if(pImageCodecInfo == NULL) return -1;
        GetImageEncoders(num, size, pImageCodecInfo);
        for(unsigned int j = 0; j < num; ++j)
        {
                if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
                        *pClsid = pImageCodecInfo[j].Clsid;
                        free(pImageCodecInfo);
                        return j;
                }
        }
        free(pImageCodecInfo);
        return -1;
}

IplImage * CALIB::Common::GetScreeny(LPWSTR lpszFilename, ULONG uQuality) // by Napalm
{
        ULONG_PTR gdiplusToken;
        GdiplusStartupInput gdiplusStartupInput;
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
        HWND hMyWnd = GetDesktopWindow(); // get my own window
        RECT  r;             // the area we are going to capture
        int w, h;            // the width and height of the area
        HDC dc;              // the container for the area
        int nBPP;
        HDC hdcCapture;
        LPBYTE lpCapture;
        int nCapture;
        int iRes;
        CLSID imageCLSID;
        Bitmap *pScreenShot;
        HGLOBAL hMem;
        int result;

        // get the area of my application's window
        //GetClientRect(hMyWnd, &r);
        GetWindowRect(hMyWnd, &r);
        dc = GetWindowDC(hMyWnd);//   GetDC(hMyWnd) ;
        w = r.right - r.left;
        h = r.bottom - r.top;
        nBPP = GetDeviceCaps(dc, BITSPIXEL);
        hdcCapture = CreateCompatibleDC(dc);


        // create the buffer for the screenshot
        BITMAPINFO bmiCapture = {
                  sizeof(BITMAPINFOHEADER), w, -h, 1, (WORD)nBPP, BI_RGB, 0, 0, 0, 0, 0,
        };

        // create a container and take the screenshot
        HBITMAP hbmCapture = CreateDIBSection(dc, &bmiCapture,
                DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0);

        // failed to take it
        if(!hbmCapture)
        {
                DeleteDC(hdcCapture);
                DeleteDC(dc);
                GdiplusShutdown(gdiplusToken);
                std::cerr << "failed to take the screenshot. err: " <<  GetLastError() << std::endl;
                return 0;
        }

        // copy the screenshot buffer
        nCapture = SaveDC(hdcCapture);
        SelectObject(hdcCapture, hbmCapture);
        BitBlt(hdcCapture, 0, 0, w, h, dc, 0, 0, SRCCOPY);
        RestoreDC(hdcCapture, nCapture);
        DeleteDC(hdcCapture);
        DeleteDC(dc);

        GpImage *bob;
        IStream *ssStr;

        // save the buffer to a file
        pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
        EncoderParameters encoderParams;

        //Save image into File
//        encoderParams.Count = 1;
//        encoderParams.Parameter[0].NumberOfValues = 1;
//        encoderParams.Parameter[0].Guid  = EncoderQuality;
//        encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
//        encoderParams.Parameter[0].Value = &uQuality;
//        GetEncoderClsid(L"image/jpeg", &imageCLSID);
//
//        iRes = (pScreenShot->Save(lpszFilename, &imageCLSID, &encoderParams) == Ok);

        Rect rect(0, 0, w,h);
        BitmapData *bmD = new BitmapData;
        memset(bmD, 0, sizeof(BitmapData));
        pScreenShot->LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, bmD);
        //int a = PixelFormat32bppARGB;
        int nChannels = 3; //depands on pixel format
        IplImage * image = Cvh::CreateIplimage(w,h,NULL,nChannels);
        memcpy(image->imageData, bmD->Scan0, w*h*nChannels);
        pScreenShot->UnlockBits(bmD);
        //cvSaveImage("tmp.png",tmp);

        delete pScreenShot;
        DeleteObject(hbmCapture);
        GdiplusShutdown(gdiplusToken);
        return image;
}

vector<string> CALIB::Common::GetDir (string dir, vector<string> files)
{
    DIR *dp;
    struct dirent *dirp;
    if((dp  = opendir(dir.c_str())) == NULL) {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return files;
    }

    while ((dirp = readdir(dp)) != NULL)
    {
    	string fileName = string(dirp->d_name);
    	if(fileName != "." && fileName != "..")
    	   	files.push_back(dir+string("/")+fileName);
    }
    closedir(dp);
    return files;
}
