#pragma hdrstop
#include <vcl.h>

#include "audio.h"
#include "fstream.h"
#include "math.h"
#include "Video.h"
#include "compress.h"
#pragma package(smart_init)
extern Compressor compressor;
extern Video video;

Video::Video()
{
   //
   packet =   15 ;
   CAPWIDTH = 320 ;
   CAPHEIGHT = 240 ;
   save = false;
   run = false;
   doCompressOrNot = false;
   startcap = false   ;
}
Video::~Video(){}
void Video::init(HWND hWnd)
{
    hParent = hWnd;
    if(!(hdd = DrawDibOpen()))
    {
        Application->MessageBox("initDisplay DrawDipOpen Error!","Error",MB_OK);
    }
    if(!(hdc = GetDC(hParent)))
    {
        Application->MessageBox("initDisplay GetDC Error!","Error",MB_OK);
    }
    if(!(hWndCap = capCreateCaptureWindow ( "Capture Window", WS_CHILD,
               0, 100,CAPWIDTH,CAPHEIGHT, hParent, 7)))

    {
                Application->MessageBox("capCreateCaptureWindow ERROR","Error",MB_OK);
    }

    if(!capDriverConnect(hWndCap,0))
    {
        Application->MessageBox("capDriverConnect ERROR","Error",MB_OK);
    }
    if(!capCaptureGetSetup(hWndCap, &Captures, sizeof(Captures)))
    {
        Application->MessageBox("capCaptureGetSetup ERROR","Error",MB_OK);
    }
    Captures.dwRequestMicroSecPerFrame = 100000;
    Captures.fYield = true;
    Captures.fCaptureAudio = false;
    Captures.fAbortLeftMouse = false;
    Captures.fAbortRightMouse = false;
    if(!capCaptureSetSetup(hWndCap, &Captures, sizeof(Captures)))
    {
        Application->MessageBox("capCaptureSetSetup ERROR","Error",MB_OK);
    }
    if(!(dwSize = capGetVideoFormatSize(hWndCap)))
    {
        Application->MessageBox("capGetVideoFormatSize ERROR","Error",MB_OK);
    }
    if(!capGetVideoFormat(hWndCap, &bmpinfo, dwSize))
    {
        Application->MessageBox("capGetVideoFormat ERROR","Error",MB_OK);
    }
    bmpinfo.bmiHeader.biWidth = CAPWIDTH;
    bmpinfo.bmiHeader.biHeight = CAPHEIGHT;
    bmpinfo.bmiHeader.biSizeImage =  bmpinfo.bmiHeader.biWidth  *  bmpinfo.bmiHeader.biHeight * 3;
    if(!capSetVideoFormat(hWndCap,&bmpinfo,dwSize))
    {
        Application->MessageBox("capSetVideoFormat ERROR","Error",MB_OK);
    }
    
    compressor.Init(Form1->Handle);
    initflag = true;
}
int Video::Display()
{
    if (initflag == false)
    {
         init(Form1->Handle);
    }
    startcap = true;

    if(!capSetCallbackOnVideoStream(hWndCap, fpVideoCallback))
    {
        Application->MessageBox("capSetCallbackOnVideoStream ERROR","Error",MB_OK);
    }
    if(!capCaptureSequenceNoFile(hWndCap))
    {
        Application->MessageBox("capCaptureSequenceNoFile ERROR","Error",MB_OK);
    }

    return 1;
}

int Video::StopCap()
{
    if( initflag == true )
    {
        initflag = false;
        doCompressOrNot = false;
        if(startcap == true)
        {
    	    if(!capCaptureStop(hWndCap))
    	    {
                Application->MessageBox("capCaptureStop Error!","Error",MB_OK);	//Error Handling
            }
            startcap = false;
       	    if(!capSetCallbackOnVideoStream(hWndCap,NULL))
    	    {
            Application->MessageBox("即將關閉視訊!","注意",MB_OK);	//Error Handling
     	    }
        }
        if(!capDriverDisconnect(hWndCap))
        {
            Application->MessageBox("capDriverDisconnect Error!","Error",MB_OK);	//Error Handling
        }
    }
    return 1;
}
LRESULT PASCAL Video::fpVideoCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
{
    if(video.save == true)
    {
        FILE *output;
        if( (output = fopen( "test.dat" /*video.file*/,"wb")) == NULL )
        {
                Application->MessageBoxA("File could not be opened!","error",MB_OK);
        }
        else
        {
                long size =video.CAPWIDTH * video.CAPHEIGHT*3;
                unsigned char header[54];
                for(int p = 0 ; p < 54 ; p++ )
                {
                        header[p] = 0 ;
                }
                //0x42 = "B"
                header[0] = 66 ;
                //0x4D = "M"
                header[1] = 77 ;
                long file_size = size + 54 ;
                header[2] = file_size % 256;
                header[3] = ( long( file_size  / 256 ) % 256 ) ;
                header[4] = long(file_size / pow(256,2) ) % 256 ;
                header[5] = file_size / pow(256,3);
                header[10] = 54 ;
                header[14] = 40 ;
                header[21] = ( video.CAPWIDTH / pow(256,3)  );
                header[20] = long( video.CAPWIDTH / pow(256,2) ) % 256 ;
                header[19] = ( video.CAPWIDTH / 256 ) % 256;
                header[18] = video.CAPWIDTH % 256 ;
                header[25] = ( video.CAPHEIGHT / pow(256,3) ) ;
                header[24] = long( video.CAPHEIGHT / pow(256,2) ) % 256 ;
                header[23] = ( video.CAPHEIGHT / 256 ) % 256;
                header[22] = video.CAPHEIGHT % 256 ;
                header[26] = 1 ;
                header[28] = 24;
                header[29] = 0;
                fwrite(header,54,1,output);
                fwrite(lpVHdr->lpData,size,1,output);
        }
        video.save = false;
    }

    if(!DrawDibBegin(video.hdd,video.hdc,-1,-1,&video.bmpinfo.bmiHeader,video.CAPWIDTH,video.CAPHEIGHT,NULL))
    {
        //Application->MessageBox("initDisplay DrawDibBegin Error!","Error",MB_OK);
    }
    if(!DrawDibDraw(video.hdd,video.hdc,350,30,video.CAPWIDTH,video.CAPHEIGHT,&video.bmpinfo.bmiHeader,lpVHdr->lpData
         ,0,0,video.CAPWIDTH,video.CAPHEIGHT,DDF_SAME_DRAW | DDF_SAME_HDC))
    {
        //Application->MessageBox("DrawDibDraw ERROR","Error",MB_OK);
    }
     


    if (video.doCompressOrNot == true)
    {
        //LPVOID lpcompresseddata;
        /*lpcompresseddata =*/ compressor.compress(lpVHdr->lpData);
    }

}
int Video::StartSend()
{
   doCompressOrNot=true;
}
int Video::StopSend()
{
   doCompressOrNot=false;
}

