#include "CVBS.h"
#include "loc_graphics_def.h"
#include "davehd_driver.h"
#include "Graphic.h"
#include "r_config_drw2d.h"
#include "r_drw2d_ctx_dhd.h"
#include "write.h"
#include "images.h"
#include "jcua.h"
#include "Watchdog.h"
#include "Data_ReversingImage.h"
#include "GUI.h"
#include "BackLight_APP.h"
#include "TW9990.h"
#include "r_wm_api.h"
#include "Common_Interface.h"

#define ALIGN_UP(x, a)  ( (x + a - 1) & ~(a - 1) )
#define MIN(a, b)       ( (a > b) ? b : a )
#define MAX(a, b)       ( (a < b) ? b : a )

/************************CVBS*************************/ 
extern r_wm_Window_t loc_WmWindowJcua;
r_wm_Window_t loc_CaptureWindow;

r_wm_Window_t *p_CaptureWindow = &loc_CaptureWindow;
r_wm_Capture_t loc_CaptureDevice = {0};

uint32_t loc_WM_UNIT = 0;
uint32_t loc_CAPT_UNIT = 0;

/* Real dimensions of the camera signal */
#define LOC_CAMERA_WIDTH                    700 //712
#define LOC_CAMERA_HEIGHT                   480

#define LOC_CAPTURE_INPUT_WIDTH             (LOC_CAMERA_WIDTH * 2)
#define LOC_CAPTURE_INPUT_HEIGHT            (LOC_CAMERA_HEIGHT) /* Interlaced video has halfed vertical resolution */

#define LOC_CAPTURE_INPUT_STARTX            16
#define LOC_CAPTURE_INPUT_STARTY            30
#define LOC_CAPTURE_INPUT_DELAY             70
#define LOC_CAPTURE_INPUT_STRIDE            736 //ALIGN_UP(LOC_CAMERA_WIDTH, 32)

/* Video input layout excluding special handling of ITU565 */
#define LOC_CAPTURE_WINDOW_STRIDE           LOC_CAPTURE_INPUT_STRIDE
#define LOC_CAPTURE_WINDOW_WIDTH            700 /* here we need the size without every pixel captured twice */
#define LOC_CAPTURE_WINDOW_HEIGHT           480

/* Down-scaling of the input video. Not possible for VI1 to VO0! */
#define LOC_CAPTURE_WINDOW_SCALED_WIDTH     LOC_CAPTURE_WINDOW_WIDTH
#define LOC_CAPTURE_WINDOW_SCALED_HEIGHT    (LOC_CAPTURE_WINDOW_HEIGHT - 4)

void loc_UpdateScreen(void)
{
    R_WM_FrameEndMark(loc_WM_UNIT, 0);
    R_WM_FrameWait(loc_WM_UNIT, 0);
}

void loc_UpdateCtrl(void)
{
    R_WM_WindowEnable(loc_WM_UNIT, &loc_CaptureWindow);
    R_WM_CaptureEnable(loc_WM_UNIT, &loc_CaptureDevice);
}

void loc_CloseCtrl(void)
{
   R_WM_CaptureDisable(loc_WM_UNIT, &loc_CaptureDevice);
   R_WM_WindowDisable(loc_WM_UNIT, &loc_CaptureWindow);
}

void loc_CVBS(void)
{
    Gfx_Create_Window (    
                            R_WM_WINMODE_FB,
                            290,
                            0,
                            0,
                            LOC_CAPTURE_WINDOW_WIDTH,    
                            LOC_CAPTURE_WINDOW_HEIGHT,   
                            LOC_CAPTURE_WINDOW_STRIDE,
                            1,
                            R_WM_COLORFMT_RGB0888,
                            &loc_CaptureWindow
                        );   
 
    loc_CaptureDevice.Mode   =   (r_wm_CapMode_t)(R_WM_CAPMODE_YUV_ITU656 | R_WM_CAPMODE_YUV_Y_UV_INVERT | R_WM_CAPMODE_DATA_CLK_INVERT | R_WM_CAPMODE_FIXED_VSYNC|R_WM_CAPMODE_WEAVE);

    loc_CaptureDevice.StartX        =   LOC_CAPTURE_INPUT_STARTX;
    loc_CaptureDevice.StrideX       =   LOC_CAPTURE_INPUT_STRIDE;
    loc_CaptureDevice.StartY1       =   LOC_CAPTURE_INPUT_STARTY;
    loc_CaptureDevice.StartY2       =   0;
    loc_CaptureDevice.Width         =   LOC_CAPTURE_INPUT_WIDTH;
    loc_CaptureDevice.Height        =   LOC_CAPTURE_INPUT_HEIGHT;
    loc_CaptureDevice.ScaledWidth   =   LOC_CAPTURE_WINDOW_SCALED_WIDTH;
    loc_CaptureDevice.ScaledHeight  =   LOC_CAPTURE_WINDOW_SCALED_HEIGHT;
    loc_CaptureDevice.Window        =   &loc_CaptureWindow;
    loc_CaptureDevice.Delay         =   LOC_CAPTURE_INPUT_DELAY;
    loc_CaptureDevice.CapUnit       =   loc_CAPT_UNIT;
    
   R_WM_CaptureCreate(loc_WM_UNIT, &loc_CaptureDevice);
}
extern uint32_t u32adress;
void loc_cvbs_ClearVRAM(void)
{
    unsigned int *pp;
    
    pp = u32adress;//0x40558000;
    
    for (int ii=0; ii<358400/*x192000*/; ii++)
    {
        pp++;
        *pp=0;
    }
}

void loc_cvbs_service(void)
{
    if ((Common_Get_IG_Sts() && (Common_GetIgnOnTime() < 3500))/* || (Common_Get_IG_Sts() == 0u)*/)
    { 
        //ReversingImage_CVBS_Ctrl_Step = em_CVBS_Ctrl_Step_Closed;
        //return;
    }

    e_CVBS_Ctrl_Step tmpStep = ReversingImage_Get_CVBS_Status();
    
    static unsigned char Openflag = 0u;
    static unsigned char CVBS_Close_Step = 0;
    static unsigned char CVBS_Open_Step = 0;

    if (tmpStep == em_CVBS_Ctrl_Step_Opening)
    {
        if (CVBS_Open_Step == 0)
        {
            CVBS_Open_Step++;
            JCUA_Disable_window();
            //R_WM_CaptureDisable(loc_WM_UNIT, &loc_CaptureDevice);
            loc_cvbs_ClearVRAM(); //20211027 由下面调到这里,解决首次进入倒车时花屏问题
        }
        else
        {
            R_WM_WindowDisable(0, &loc_WmWindowJcua);
            R_WM_WindowEnable(0, &loc_CaptureWindow);
            //loc_cvbs_ClearVRAM();
            R_WM_CaptureEnable(loc_WM_UNIT, &loc_CaptureDevice);  
            loc_UpdateScreen();
            ReversingImage_Cmd(em_ReversingImageCMD_OpenCompletion);
        }
    }
    else if (tmpStep == em_CVBS_Ctrl_Step_Opened)
    {
        CVBS_Close_Step = 0;
    }
    else if (tmpStep == em_CVBS_Ctrl_Step_Closing)
    {
        Openflag = 0u;
        
        if (CVBS_Close_Step == 0)
        {
            R_WM_CaptureDisable(loc_WM_UNIT, &loc_CaptureDevice);    
            
            R_WM_WindowDisable(0, &loc_CaptureWindow);
            loc_UpdateScreen();
            CVBS_Close_Step++;
        }
        else if (CVBS_Close_Step == 1)
        {
            Bottom_Display_Service();

            //if (GUI_IGNOFF_ClearingSprite() != 1u)
            {
               R_WM_WindowEnable(0, &loc_WmWindowJcua);
            }
            
            ReversingImage_Cmd(em_ReversingImageCMD_CloseCompletion);
            GUI_DisplUpdTimRst();
            CVBS_Close_Step = 0;

            CVBS_Open_Step = 0;
        }
    }
}
void Bottom_Display_Service1(void)
{
    R_WM_CaptureDisable(loc_WM_UNIT, &loc_CaptureDevice);    
    R_WM_WindowDisable(0, &loc_CaptureWindow);
    loc_UpdateScreen();
    for (uint32_t u32Delay = 0UL; u32Delay < 10000000UL; u32Delay++)
    {
    
    }
    Bottom_Display_Service();
    R_WM_WindowEnable(0, &loc_WmWindowJcua);
    ReversingImage_Cmd(em_ReversingImageCMD_CloseCompletion);
}

void CVBS_free_mem(void)
{
    R_WM_WindowDisable(0, &loc_CaptureWindow);
    R_WM_FrameEndMark(0, 0);
    R_WM_FrameWait(0, 0); 
}

void cvbs_enable_mem(void)
{
    R_WM_WindowEnable(0, &loc_CaptureWindow);
    R_WM_FrameEndMark(0, 0);
    R_WM_FrameWait(0, 0); 
}

void CaptureDisable(void)
{ 
    R_WM_CaptureDisable(loc_WM_UNIT, &loc_CaptureDevice);    
    R_WM_WindowDisable(0, &loc_CaptureWindow);
    loc_UpdateScreen();
}
