/*
 * Copyright (C) 2018 Synaptics Incorporated. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND
 * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY
 * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR
 * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND
 * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF
 * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT
 * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY
 * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS.
 */

#include "vpp_module.h"
#include "vpp_cfg.h"
#include "avio_memmap.h"
#include "api_avio_dhub.h"
#include "util.h"
#include "common.h"
#include "vpp_api.h"
#include "show_logoframe.h"

/* Memory is available for only ONE 1080p frame*/
#define     MAX_FRAME_DESC  1

#define bTST(x, b) (((x) >> (b)) & 1)

typedef enum {
    FB_PATTERN_CHECKER = 0,
    FB_PATTERN_VERT_COLORBAR,
    FB_PATTERN_CUSTOM,
    FB_PATTERN_CUSTOM_APM,
    MAX_PATTERNS,
    FB_PATTERN_HORZ_COLORBAR,
} FB_PATTERN_TYPE;

static VBUF_INFO *gDescArray[MAX_FRAME_DESC];
static INT32 gDescIndex;

VOID destroy_vbuf_desc(VBUF_INFO *pVBufInfo)
{
    (void)pVBufInfo;
}

INT32 make_frame_data(UINT32 iVideo, UINT32 *pStartAddr,
              UINT32 uiPicH, UINT32 uiLineV, UINT32 uiWidth,
              UINT32 uiHeight, UINT32 uiPicA, UINT32 uiPicB)
{
    UINT32 *Ptr;
    UINT32 VLines, VRep, HS, HRep, PixVal, VBlock, HBlock, PixelPerWord;
    HRESULT Ret = MV_VPP_OK;

    if (!pStartAddr) {
        printf("invalid input parameters\n");
        Ret = -1;
        goto make_frame_data_exit;
    }

    /**
    * make the whole frame data
    */
    Ptr = pStartAddr;

    if (iVideo)
        PixelPerWord = 2;
    else
        PixelPerWord = 1;

    VBlock = uiLineV;

    for (VLines = 0; VLines < uiHeight; VLines += VBlock) {
        if ((uiHeight - VLines) < VBlock)
            VBlock = uiHeight - VLines;

        for (VRep = 0; VRep < VBlock; VRep++) {
            HBlock = uiPicH * PixelPerWord;

            for (HS = 0; HS < uiWidth; HS += HBlock) {
                if ((VLines / uiLineV +
                        HS/(uiPicH * PixelPerWord))
                        & 0x1)
                    PixVal = uiPicB;
                else
                    PixVal = uiPicA;

                if ((uiWidth - HS) < HBlock)
                    HBlock = uiWidth - HS;

                for (HRep = 0; HRep < HBlock/PixelPerWord;
                        HRep++)
                    *Ptr++ = PixVal;
            }
        }
    }
make_frame_data_exit:
    return Ret;
}

VOID build_frames(VBUF_INFO *vbufinfo, VOID *vbuf,
    INT32 srcfmt, INT32 bit_depth, INT32 x, INT32 y, INT32 width,
    INT32 height, INT32 progressive, INT32 pattern_type, unsigned char IsPatt)
{
    UINT32 datasize;

    if(bit_depth != INPUT_BIT_DEPTH_8BIT || progressive != 1 ||
            pattern_type != FB_PATTERN_CUSTOM)
    {
        printf("Error: Invalid Params\n");
        return;
    }
    /* set other fields of logo frame descriptor */
    if (srcfmt == SRCFMT_YUV422) {
        vbufinfo->m_bytes_per_pixel = 2;
        vbufinfo->m_srcfmt = SRCFMT_YUV422;
        vbufinfo->m_order = ORDER_UYVY;
    } else {
        vbufinfo->m_bytes_per_pixel = 4;
        vbufinfo->m_srcfmt = SRCFMT_ARGB32;
        vbufinfo->m_order = ORDER_RGBA;
    }
    datasize = width * height * vbufinfo->m_bytes_per_pixel;
    vbufinfo->m_content_width = width;
    vbufinfo->m_content_height = height;
    vbufinfo->m_buf_stride = vbufinfo->m_content_width *
                    vbufinfo->m_bytes_per_pixel;
    vbufinfo->m_buf_size = (INT32)datasize;
    vbufinfo->m_flags = 1;
    vbufinfo->m_disp_offset = 0;
    vbufinfo->m_buf_stride = vbufinfo->m_content_width *
                    vbufinfo->m_bytes_per_pixel;
    vbufinfo->m_active_width = width;
    vbufinfo->m_active_height = height;
    vbufinfo->m_active_left = x;
    vbufinfo->m_active_top = y;
    vbufinfo->m_content_offset = 0;
    if (IsPatt) {
        if (srcfmt == SRCFMT_YUV422)
            make_frame_data(1, vbuf, 32, 36, width,
                height, 0x00800080, 0x00800080);
        else
            make_frame_data(0, vbuf, 32, 36, width,
                height, 0xFF000000, 0xFFFFFFFF);
    }
}
INT32 create_new_frame(INT32 width, INT32 height, INT32 progressive,
    INT32 src_fmt, INT32 bit_depth, INT32 pattern_type,
    VBUF_INFO **frame) {

    VBUF_INFO *vbufinfo;
    VOID *base = NULL;
    void*  phy_base;
    VOID *shm_handle;
    INT32 datasize = 0;
    INT32 result = 0;

    vbufinfo  = UtilMemAllocZ(sizeof(VBUF_INFO));
    if (vbufinfo == NULL)
        return -1;

    if (SRCFMT_YUV422 == src_fmt)
        datasize = width*height*2;
    else
        datasize = width*height*4;

    phy_base = base = shm_handle = UtilMemAllocZ(datasize);
    if (base == NULL) {
        result = MV_VPP_EBADCALL;
        printf("share memory get vitual address failed\n");
        goto EXIT;
    }

    build_frames(vbufinfo, base, src_fmt, bit_depth,
            0, 0, width, height,
            progressive, pattern_type, 1);
    vbufinfo->hShm  = shm_handle;
    vbufinfo->m_pbuf_start = phy_base;
    vbufinfo->m_bufferID = base;
    *frame = vbufinfo;
EXIT:
    return result;
}


VOID *MV_VPP_GetFrame(INT32 x,
            INT32 y, INT32 w, INT32 h, INT32 stride)
{
    int Ret = 0;
    VBUF_INFO *vbufinfo = gDescArray[gDescIndex];

    if(vbufinfo == NULL) {
        Ret = create_new_frame(w, h, 1, SRCFMT_YUV422,
                    INPUT_BIT_DEPTH_8BIT, FB_PATTERN_CUSTOM,
                    &(gDescArray[gDescIndex]));
        if (Ret != 0) {
            printf("create_global_desc_array fails\n");
            return NULL;
        }
    }

    vbufinfo = gDescArray[gDescIndex];
    gDescIndex++;
    if (gDescIndex == MAX_FRAME_DESC)
        gDescIndex = 0;

    vbufinfo->m_active_left  = x;
    vbufinfo->m_active_top   = y;
    vbufinfo->m_buf_stride = stride;
    vbufinfo->m_active_width = w;
    vbufinfo->m_active_height = h;

    return vbufinfo;
}

INT32 create_global_desc_array(VOID)
{
    UtilMemSet(gDescArray, 0, MAX_FRAME_DESC * sizeof(VBUF_INFO *));
    return 0;
}

VOID destroy_global_desc_array(VOID)
{
    UtilMemSet(gDescArray, 0, MAX_FRAME_DESC * sizeof(VBUF_INFO *));
}

VOID MV_VPP_InitMemory(VOID)
{
    UtilMemReset();
}
