/*
 * Copyright (c) 2007 Intel Corporation. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#define _GNU_SOURCE 1
#include "sysdeps.h"
#include "va.h"
#include "va_backend.h"
#include "va_trace.h"
#include "va_fool.h"
#include "va_android.h"
#include "va_drmcommon.h"
#include "va_drm_utils.h"
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <errno.h>


#define CHECK_SYMBOL(func) { if (!func) printf("func %s not found\n", #func); return VA_STATUS_ERROR_UNKNOWN; }
#define DEVICE_NAME "/dev/dri/card0"

static int open_device (char *dev_name)
{
    struct stat st;
    int fd;

    if (-1 == stat (dev_name, &st))
    {
        printf ("Cannot identify '%s': %d, %s\n",
                dev_name, errno, strerror (errno));
        return -1;
    }

    if (!S_ISCHR (st.st_mode))
    {
        printf ("%s is no device\n", dev_name);
        return -1;
    }

    fd = open (dev_name, O_RDWR);

    if (-1 == fd)
    {
        fprintf (stderr, "Cannot open '%s': %d, %s\n",
                 dev_name, errno, strerror (errno));
        return -1;
    }

    return fd;
}

static int va_DisplayContextIsValid (
    VADisplayContextP pDisplayContext
                                  )
{
    return (pDisplayContext != NULL &&
            pDisplayContext->pDriverContext != NULL);
}

static void va_DisplayContextDestroy (
    VADisplayContextP pDisplayContext
)
{
    struct drm_state *drm_state;

    if (pDisplayContext == NULL)
        return;

    /* close the open-ed DRM fd */
    drm_state = (struct drm_state *)pDisplayContext->pDriverContext->drm_state;
    close(drm_state->fd);

    free(pDisplayContext->pDriverContext->drm_state);
    free(pDisplayContext->pDriverContext);
    free(pDisplayContext);
}

static VAStatus va_DisplayContextGetDriverName (
    VADisplayContextP pDisplayContext,
    char **driver_name
)
{
    VADriverContextP const ctx = pDisplayContext->pDriverContext;
    struct drm_state * drm_state = (struct drm_state *)ctx->drm_state;

    memset(drm_state, 0, sizeof(*drm_state));
    drm_state->fd = open_device((char *)DEVICE_NAME);

    if (drm_state->fd < 0) {
        fprintf(stderr,"can't open DRM devices\n");
        return VA_STATUS_ERROR_UNKNOWN;
    }
    drm_state->auth_type = VA_DRM_AUTH_CUSTOM;

    if (driver_name == NULL)
        return VA_STATUS_ERROR_UNKNOWN;

    if (strncmp((char *)ctx->native_dpy, "libva_driver_name=", 18) == 0) {
            *driver_name = strdup((char *)ctx->native_dpy + 18);
        if (*driver_name == NULL)
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
        else
            return VA_STATUS_SUCCESS;
    } else {
        return VA_DRM_GetDriverName(ctx, driver_name);
    }
}


VADisplay vaGetDisplay (
    void *native_dpy /* implementation specific */
)
{
    VADisplay dpy = NULL;
    VADisplayContextP pDisplayContext;

    if (!native_dpy)
        return NULL;

    if (!dpy)
    {
        /* create new entry */
        VADriverContextP pDriverContext = 0;
        struct drm_state *drm_state = 0;
        pDisplayContext = (VADisplayContextP)calloc(1, sizeof(*pDisplayContext));
        pDriverContext  = (VADriverContextP)calloc(1, sizeof(*pDriverContext));
        drm_state       = (struct drm_state*)calloc(1, sizeof(*drm_state));
        if (pDisplayContext && pDriverContext && drm_state)
        {
            pDisplayContext->vadpy_magic = VA_DISPLAY_MAGIC;          

            pDriverContext->native_dpy       = (void *)native_dpy;
            pDriverContext->display_type     = VA_DISPLAY_ANDROID;
            pDisplayContext->pDriverContext  = pDriverContext;
            pDisplayContext->vaIsValid       = va_DisplayContextIsValid;
            pDisplayContext->vaDestroy       = va_DisplayContextDestroy;
            pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
            pDriverContext->drm_state 	     = drm_state;
            dpy                              = (VADisplay)pDisplayContext;
        }
        else
        {
            if (pDisplayContext)
                free(pDisplayContext);
            if (pDriverContext)
                free(pDriverContext);
            if (drm_state)
                free(drm_state);
        }
    }
  
    return dpy;
}

#define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
#define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }


extern "C"  {
    extern int fool_postp; /* do nothing for vaPutSurface if set */
    extern int trace_flag; /* trace vaPutSurface parameters */

    void va_TracePutSurface (
        VADisplay dpy,
        VASurfaceID surface,
        void *draw, /* the target Drawable */
        short srcx,
        short srcy,
        unsigned short srcw,
        unsigned short srch,
        short destx,
        short desty,
        unsigned short destw,
        unsigned short desth,
        VARectangle *cliprects, /* client supplied clip list */
        unsigned int number_cliprects, /* number of clip rects in the clip list */
        unsigned int flags /* de-interlacing flags */
        );
}

VAStatus vaPutSurface (
    VADisplay dpy,
    VASurfaceID surface,
    sp<ANativeWindow> draw, /* Android Native Window */
    short srcx,
    short srcy,
    unsigned short srcw,
    unsigned short srch,
    short destx,
    short desty,
    unsigned short destw,
    unsigned short desth,
    VARectangle *cliprects, /* client supplied clip list */
    unsigned int number_cliprects, /* number of clip rects in the clip list */
    unsigned int flags /* de-interlacing flags */
)
{
    VADriverContextP ctx;

    if (fool_postp)
        return VA_STATUS_SUCCESS;

    if (draw == NULL)
        return VA_STATUS_ERROR_UNKNOWN;

    CHECK_DISPLAY(dpy);
    ctx = CTX(dpy);

    VA_TRACE_LOG(va_TracePutSurface, dpy, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch,
                 destx, desty, destw, desth,
                 cliprects, number_cliprects, flags );
    
    return ctx->vtable->vaPutSurface( ctx, surface, static_cast<void*>(&draw), srcx, srcy, srcw, srch, 
                                     destx, desty, destw, desth,
                                     cliprects, number_cliprects, flags );
}

