// ImageTP.cpp :
//

#include "stdafx.h"
#include "BaseClient.h"
#include "ImageTP.h"
#include "BaseClientDlg.h"

#define IMAGE_HIGHT 320
#define IMAGE_WIDTH 412
#define TEMP_OUTPUT_BMPFILE "picture.bmp"
#define BITMAP_FILESIZE 412 * 320 * 3 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + 4
#define BITMAP_SIZE 412 * 320 * 3 + sizeof(BITMAPINFO) + 4

// CImageTP

CImageTP::CImageTP(CVAIBO *pVAibo, CBaseClientDlg *pDlg)
{
    m_pVAibo = pVAibo;
    m_pDlg = pDlg;
    m_imagebuf.SetSize(IMAGE_WIDTH * IMAGE_HIGHT);
    m_DoTakePicture = FALSE;
    m_bDoneSetWindowHandle = FALSE;
	m_bDoneSetParam = FALSE;
    m_bActiveImagePlay = FALSE;
    m_bUpdateBmpFile = FALSE;
    m_bNewPhoto = FALSE;
    m_pImageBufF.SetSize(BITMAP_FILESIZE);
    m_pImageBufN.SetSize(BITMAP_SIZE);
    m_uLen = 0;
}

CImageTP::~CImageTP()
{
}


// CImageTP Member Functions

BOOL CImageTP::Initialize(void)
{
    int result, state, lcount(0);
    CString strMsg;

    state = m_pVAibo->GetStateImageTP();
	switch (state) {
	case IMAGETP_STATE_CLOSE : 
        result = m_pVAibo->ImageInit();
	    if (result != IMAGETP_NOERROR) {
	    strMsg.Format(IDS_IMAGETP_ERROR, result);
			AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
			return FALSE;
		}
        // no break
	case IMAGETP_STATE_INIT : 
        result = m_pVAibo->ImageOpen();
	    if (result != IMAGETP_NOERROR) {
		    strMsg.Format(IDS_IMAGETP_ERROR, result);
			AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
			return FALSE;
		}
        // no break
	case IMAGETP_STATE_OPEN : 
        if (!m_pDlg->m_bNetServiceImageEnable) {
	        BOOL bOK = m_pVAibo->RequestNetService(IMAGE_ID); // Start ImageTP NetService
			if (!bOK) {
				m_pVAibo->ImageClose();
				strMsg.Format(IDS_REQNETSERVICE_ERROR, "IMAGE");
				AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
				return FALSE;
		    }
			m_pDlg->m_bNetServiceImageEnable = TRUE;
	    }
        m_bActiveImagePlay = FALSE;
		break;
		// SendCmd( APPCMD_IMAGE_PLAY )  will be invoked in OnVAIBOSemantics()
	case IMAGETP_STATE_SERVICE : 
	case IMAGETP_STATE_PLAY :
		// Someone has started RequestNetService(IMAGE_ID)
		// ImageTP may be stopped by SendCmd(APPCMD_IMAGE_STOP); even if state == IMAGETP_STATE_PLAY
		result = m_pVAibo->SendCmd( APPCMD_IMAGE_PLAY ); 
	    if (result != VAIBO_NOERROR) {
		    strMsg.Format(IDS_SENDCMD_ERROR, "APPCMD_IMAGE_PLAY", result);
			AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
			return FALSE;
	    }
        m_bActiveImagePlay = TRUE;
		break;
	case IMAGETP_STATE_PAUSE :
		result =  m_pVAibo->ImageResume();
	    if (result != VAIBO_NOERROR) {
		    strMsg.Format(IDS_IMAGERESUME_ERROR, result);
			AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
			return FALSE;
	    }
        m_bActiveImagePlay = TRUE;
	}
    return TRUE;
}

BOOL CImageTP::HandleImageData(UINT uLen)
{
    if (!m_bActiveImagePlay)
        return TRUE;

    if (!m_bDoneSetWindowHandle) {
        m_bDoneSetWindowHandle = TRUE;
        int result = m_pVAibo->ImageSetWindowHandle(m_pDlg->staticMovie().GetSafeHwnd(), m_pDlg->GetSafeHwnd());
        if (result != VAIBO_NOERROR) {
            CString strMsg;
            strMsg.Format(IDS_IMAGESET_WINDOW_HANDLE_ERROR, result);
            AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
            return FALSE;
        }
    }

    if (m_bUpdateBmpFile) {
        CFile fi(TEMP_OUTPUT_BMPFILE, CFile::modeRead);
        UINT nBytesRead  = fi.Read(m_pImageBufF.GetData(), BITMAP_FILESIZE);
        fi.Close();
        memcpy(m_pImageBufN.GetData(),
            m_pImageBufF.GetData() + sizeof(BITMAPFILEHEADER),
            sizeof(BITMAPINFOHEADER));
        BITMAPINFO* bmi = (BITMAPINFO*)m_pImageBufN.GetData();
        bmi->bmiColors[0].rgbGreen     = 0;
        bmi->bmiColors[0].rgbBlue      = 0;
        bmi->bmiColors[0].rgbReserved  = 0;
        memcpy(m_pImageBufN.GetData() + sizeof(BITMAPINFO),
            m_pImageBufF.GetData() + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER),
            nBytesRead - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER));
        m_bUpdateBmpFile = FALSE;
        m_bNewPhoto = TRUE;
        m_pDlg->Invalidate();
        m_pDlg->UpdateWindow();
    }

    if (m_DoTakePicture) {
        m_pVAibo->ImageOutputCaptureData(TEMP_OUTPUT_BMPFILE);
        m_bUpdateBmpFile = TRUE; // Next time, TEMP_OUTPUT_BMPFILE is created
        m_DoTakePicture = FALSE;
    }

    // Update image data every time
    m_pVAibo->ImageGetData((UCHAR*)m_imagebuf.GetData(), uLen);
    m_uLen = uLen;

    return TRUE;
}

BOOL CImageTP::TakePicture(LPCSTR pFileName)
{
    m_PhotoFileName = pFileName;
    m_DoTakePicture = TRUE;
    if (!m_PhotoFileName.IsEmpty() && m_uLen != 0) {
        CFile fi(m_PhotoFileName, CFile::modeCreate|CFile::modeWrite);
        fi.Write(m_imagebuf.GetData(), m_uLen);
        fi.Close();
        // must call HandleImageData() to update the picture in the dialog
        return TRUE;
    }
    CString strMsg;
    strMsg.Format(IDS_TAKEPICTURE_ERROR);
    AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
    return FALSE;
}

BOOL CImageTP::Terminate(void)
{
    int result;

// Keep sending Image to the other applications when this appicaiton disconnect to the AIBO
    result = m_pVAibo->GetStateImageTP();
    if ( result != IMAGETP_STATE_CLOSE ) {
        result = m_pVAibo->ImageClose();
        if (result != VAIBO_NOERROR) {
            CString strMsg;
            strMsg.Format(IDS_IMAGECLOSE_ERROR, result);
            AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
            return FALSE;
        }
    }
    m_bDoneSetWindowHandle = FALSE;
    return TRUE;
}

BOOL CImageTP::ImageStop(void)
{
    int result;
    CString strMsg;

    if (m_bActiveImagePlay) {
        m_bActiveImagePlay = FALSE;
        result = m_pVAibo->GetStateImageTP();
        if (result == IMAGETP_STATE_PAUSE || IMAGETP_STATE_PLAY || result == IMAGETP_STATE_SERVICE ) {
            result = m_pVAibo->SendCmd( APPCMD_IMAGE_STOP, TRUE );
            if (result != VAIBO_NOERROR) {
                strMsg.Format(IDS_SENDCMD_ERROR, "APPCMD_IMAGE_STOP", result);
                AfxMessageBox( strMsg, MB_OK|MB_ICONSTOP );
                return FALSE;
            }
        }
    }
    return TRUE;
}
