/*
**
** Copyright 2009, The Android-x86 Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** Author: Niels Keeman <nielskeeman@gmail.com>
**
*/

#define LOG_TAG "CameraHardware"
#include <utils/Log.h>

#include "CameraHardware.h"
#include <fcntl.h>
#include <sys/mman.h>
#include <cutils/native_handle.h>
#include <hal_public.h>
#include <ui/GraphicBufferMapper.h>
#include <gui/ISurfaceTexture.h>
#define MAX_VIDEONODES      20
#define MIN_WIDTH           320
#define MIN_HEIGHT          240
#define CAM_SIZE            "320x240"
#define PIXEL_FORMAT        V4L2_PIX_FMT_YUYV
#define CAMHAL_GRALLOC_USAGE GRALLOC_USAGE_HW_TEXTURE | \
                             GRALLOC_USAGE_HW_RENDER | \
                             GRALLOC_USAGE_SW_READ_RARELY | \
                             GRALLOC_USAGE_SW_WRITE_NEVER

extern "C" {
    void yuyv422_to_yuv420sp(unsigned char*,unsigned char*,int,int);
    void convertYUYVtoRGB565(unsigned char *buf, unsigned char *rgb, int width, int height);
}

namespace android {


const char supportedFpsRanges [] = "(8000,8000),(8000,10000),(10000,10000),(8000,15000),(15000,15000),(8000,20000),(20000,20000),(24000,24000),(25000,25000),(8000,30000),(30000,30000)";

CameraHardware::CameraHardware(int cameraId)
                  : mCameraId(cameraId),
                    mParameters(),
                    mHeap(0),
                    mPreviewHeap(0),
                    mRecordHeap(0),
                    mRawHeap(0),
                    mPreviewFrameSize(0),
                    mCurrentPreviewFrame(0),
                    mRecordRunning(false),
                    previewStopped(true),
                    nQueued(0),
                    nDequeued(0),
                    mNotifyFn(NULL),
                    mDataFn(NULL),
                    mTimestampFn(NULL),
                    mUser(NULL),
                    mMsgEnabled(0)
{
    initDefaultParameters();
    mNativeWindow=NULL;
}

void CameraHardware::initDefaultParameters()
{
    CameraParameters p;

    p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
    p.setPreviewFrameRate(30);
    p.setPreviewFormat("yuv422sp");
    p.set(p.KEY_SUPPORTED_PREVIEW_SIZES, CAM_SIZE);
    p.set(p.KEY_SUPPORTED_PREVIEW_SIZES, "640x480");
    p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,CameraParameters::PIXEL_FORMAT_YUV420SP);
    p.set(CameraParameters::KEY_FOCUS_MODE,0);
    p.setPictureSize(MIN_WIDTH, MIN_HEIGHT);
    p.setPictureFormat("jpeg");
    p.set(p.KEY_SUPPORTED_PICTURE_SIZES, CAM_SIZE);

    if (setParameters(p) != NO_ERROR) {
        ALOGE("Failed to set default parameters?!");
    }
}

CameraHardware::~CameraHardware()
{
}

sp<IMemoryHeap> CameraHardware::getPreviewHeap() const
{
    return mHeap;
}

sp<IMemoryHeap> CameraHardware::getRawHeap() const
{
    return mRawHeap;
}

// ---------------------------------------------------------------------------

void CameraHardware::setCallbacks(camera_notify_callback notify_cb,
                                  camera_data_callback data_cb,
                                  camera_data_timestamp_callback data_cb_timestamp,
                                  camera_request_memory get_memory,
                                  void *arg)
{
    Mutex::Autolock lock(mLock);
    mNotifyFn = notify_cb;
    mDataFn = data_cb;
    mRequestMemory = get_memory;
    mTimestampFn = data_cb_timestamp;
    mUser = arg;
}

int CameraHardware::setPreviewWindow( preview_stream_ops_t *window)
{
    int err;
    Mutex::Autolock lock(mLock);
        if(mNativeWindow)
            mNativeWindow=NULL;
    if(window==NULL)
    {
        ALOGW("Window is Null");
        return 0;
    }
    int width, height;
    mParameters.getPreviewSize(&width, &height);
    mNativeWindow=window;
    mNativeWindow->set_usage(mNativeWindow,CAMHAL_GRALLOC_USAGE);
    mNativeWindow->set_buffers_geometry(
                mNativeWindow,
                width,
                height,
                HAL_PIXEL_FORMAT_RGB_565);
    err = mNativeWindow->set_buffer_count(mNativeWindow, 3);
    if (err != 0) {
        ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);

        if ( ENODEV == err ) {
            ALOGE("Preview surface abandoned!");
            mNativeWindow = NULL;
        }
    }

    return 0;
}

void CameraHardware::enableMsgType(int32_t msgType)
{
    Mutex::Autolock lock(mLock);
    mMsgEnabled |= msgType;
}

void CameraHardware::disableMsgType(int32_t msgType)
{
    Mutex::Autolock lock(mLock);
    mMsgEnabled &= ~msgType;
}

bool CameraHardware::msgTypeEnabled(int32_t msgType)
{
    Mutex::Autolock lock(mLock);
    return (mMsgEnabled & msgType);
}


//-------------------------------------------------------------
int CameraHardware::previewThread()
{
    int width, height;
    int err;
    IMG_native_handle_t** hndl2hndl;
    IMG_native_handle_t* handle;
    int stride;
    mParameters.getPreviewSize(&width, &height);
    int framesize= width * height * 1.5 ; //yuv420sp

   if (!previewStopped) {
    mLock.lock();
    if (mNativeWindow != NULL)
    {
    if ((err = mNativeWindow->dequeue_buffer(mNativeWindow,(buffer_handle_t**) &hndl2hndl,&stride)) != 0) {
        ALOGW("Surface::dequeueBuffer returned error %d", err);
        return -1;
    }
    mNativeWindow->lock_buffer(mNativeWindow, (buffer_handle_t*) hndl2hndl);
    GraphicBufferMapper &mapper = GraphicBufferMapper::get();

    Rect bounds(width, height);
    void *tempbuf;
    void *dst;
    if(0 == mapper.lock((buffer_handle_t)*hndl2hndl,CAMHAL_GRALLOC_USAGE, bounds, &dst)); 
    {
        // Get preview frame
        tempbuf=camera.GrabPreviewFrame();
        convertYUYVtoRGB565((unsigned char *)tempbuf,(unsigned char *)dst, width, height);
        mapper.unlock((buffer_handle_t)*hndl2hndl);
        mNativeWindow->enqueue_buffer(mNativeWindow,(buffer_handle_t*) hndl2hndl);
        if ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) ||
                (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
            camera_memory_t* picture = mRequestMemory(-1, framesize, 1, NULL);
            yuyv422_to_yuv420sp((unsigned char *)tempbuf,(unsigned char *) picture->data, width, height);
            if ((mMsgEnabled & CAMERA_MSG_VIDEO_FRAME ) && mRecordRunning ) {
                nsecs_t timeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
                //mTimestampFn(timeStamp, CAMERA_MSG_VIDEO_FRAME,mRecordBuffer, mUser);
            }
            mDataFn(CAMERA_MSG_PREVIEW_FRAME,picture,0,NULL,mUser);
	    picture->release(picture);
	}
        camera.ReleasePreviewFrame();
    }
    }
    mLock.unlock();
    }

    return NO_ERROR;
}

status_t CameraHardware::startPreview()
{
    int ret;
    int width, height;
    int i;
    IMG_native_handle_t** hndl2hndl;
    IMG_native_handle_t* handle;
    int stride;
    char devnode[15];
    Mutex::Autolock lock(mLock);
    if (mPreviewThread != 0) {
        //already running
        return INVALID_OPERATION;
    }
#if 1
    ALOGI("startPreview: in startpreview \n");
    mParameters.getPreviewSize(&width, &height);
    for( i=MAX_VIDEONODES; i>=0; i--) {
        sprintf(devnode,"/dev/video%d",i);
        ALOGI("trying the node %s width=%d height=%d \n",devnode,width,height);
        ret = camera.Open(devnode, width, height, PIXEL_FORMAT);
        if( ret >= 0)
            break;
        }

    if( ret < 0)
        return -1;

    mPreviewFrameSize = width * height * 2;

    mHeap = new MemoryHeapBase(mPreviewFrameSize);
    mBuffer = new MemoryBase(mHeap, 0, mPreviewFrameSize);

    ret = camera.Init();
    if (ret != 0) {  
        ALOGI("startPreview: Camera.Init failed\n");
        camera.Close();
        return ret;
    }

    ret = camera.StartStreaming();
    if (ret != 0) {  
        ALOGI("startPreview: Camera.StartStreaming failed\n");
        camera.Uninit();
        camera.Close();
        return ret;
    }

    previewStopped = false;
    mPreviewThread = new PreviewThread(this);

#endif
    return NO_ERROR;
}

void CameraHardware::stopPreview()
{
    sp<PreviewThread> previewThread;

    { // scope for the lock
        Mutex::Autolock lock(mLock);
        previewStopped = true;
    }

    {
        Mutex::Autolock lock(mLock);
        previewThread = mPreviewThread;
    }

    if (previewThread != 0) {
        previewThread->requestExitAndWait();
    }

    if (mPreviewThread != 0) {
        camera.Uninit();
        camera.StopStreaming();
        camera.Close();
    }

    Mutex::Autolock lock(mLock);
    mPreviewThread.clear();
}

bool CameraHardware::previewEnabled()
{
    Mutex::Autolock lock(mLock);
    return ((mPreviewThread != 0) );
}

status_t CameraHardware::startRecording()
{
    Mutex::Autolock lock(mLock);

    mRecordHeap = new MemoryHeapBase(mPreviewFrameSize*3/4);
    mRecordBuffer = new MemoryBase(mRecordHeap, 0, mPreviewFrameSize*3/4);
    mRecordRunning = true;

    return NO_ERROR;
}

void CameraHardware::stopRecording()
{
    mRecordRunning = false;
}

bool CameraHardware::recordingEnabled()
{
    return mRecordRunning;
}

void CameraHardware::releaseRecordingFrame(const void *opaque)
{

}

// ---------------------------------------------------------------------------

int CameraHardware::beginAutoFocusThread(void *cookie)
{
    CameraHardware *c = (CameraHardware *)cookie;
    return c->autoFocusThread();
}

int CameraHardware::autoFocusThread()
{
    if (mMsgEnabled & CAMERA_MSG_FOCUS)
        mNotifyFn(CAMERA_MSG_FOCUS, true, 0, mUser);
    return NO_ERROR;
}

status_t CameraHardware::autoFocus()
{
    Mutex::Autolock lock(mLock);
    if (createThread(beginAutoFocusThread, this) == false)
        return UNKNOWN_ERROR;
    return NO_ERROR;
}

status_t CameraHardware::cancelAutoFocus()
{
    return NO_ERROR;
}

/*static*/ int CameraHardware::beginPictureThread(void *cookie)
{
    CameraHardware *c = (CameraHardware *)cookie;
    return c->pictureThread();
}

int CameraHardware::pictureThread()
{
    unsigned char *frame;
    int bufferSize;
    int w,h;
    int ret;
    struct v4l2_buffer buffer;
    struct v4l2_format format;
    struct v4l2_buffer cfilledbuffer;
    struct v4l2_requestbuffers creqbuf;
    struct v4l2_capability cap;
    int i;
    char devnode[15];
    camera_memory_t* picture = NULL;


   if (mMsgEnabled & CAMERA_MSG_SHUTTER)
        mNotifyFn(CAMERA_MSG_SHUTTER, 0, 0, mUser);

    mParameters.getPictureSize(&w, &h);
    ALOGD("Picture Size: Width = %d \t Height = %d", w, h);

    int width, height;
    mParameters.getPictureSize(&width, &height);
    mParameters.getPreviewSize(&width, &height);

    for(i=MAX_VIDEONODES; i>=0; i--) {
        sprintf(devnode,"/dev/video%d",i);
        ALOGI("trying the node %s \n",devnode);
        ret = camera.Open(devnode, width, height, PIXEL_FORMAT);
        if( ret >= 0)
            break;
    }

    if( ret < 0)
        return -1;

    camera.Init();
    camera.StartStreaming();
    //TODO xxx : Optimize the memory capture call. Too many memcpy
    if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
        ALOGD ("mJpegPictureCallback");
        picture = camera.GrabJpegFrame(mRequestMemory);
        mDataFn(CAMERA_MSG_COMPRESSED_IMAGE,picture,0,NULL ,mUser);
    }

    camera.Uninit();
    camera.StopStreaming();
    camera.Close();

    return NO_ERROR;
}

status_t CameraHardware::takePicture()
{
        ALOGD ("takepicture");
    stopPreview();

    pictureThread();

    return NO_ERROR;
}

status_t CameraHardware::cancelPicture()
{

    return NO_ERROR;
}

status_t CameraHardware::dump(int fd, const Vector<String16>& args) const
{
    return NO_ERROR;
}

status_t CameraHardware::setParameters(const CameraParameters& params)
{
    Mutex::Autolock lock(mLock);

    if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
        ALOGE("Only jpeg still pictures are supported");
        return -1;
    }

    int w, h;
    int framerate;

    mParameters = params;
    params.getPictureSize(&w, &h);
    mParameters.setPictureSize(w,h);
    params.getPreviewSize(&w, &h);
    mParameters.setPreviewSize(w,h);
    framerate = params.getPreviewFrameRate();
    ALOGD("PREVIEW SIZE: w=%d h=%d framerate=%d", w, h, framerate);
    mParameters = params;
    mParameters.setPreviewSize(w,h);
    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, supportedFpsRanges);
    mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240,352x288,640x480,720x480,720x576,848x480");

    return NO_ERROR;
}

status_t CameraHardware::sendCommand(int32_t command, int32_t arg1, int32_t arg2)
{
    return BAD_VALUE;
}

CameraParameters CameraHardware::getParameters() const
{
    CameraParameters params;

    Mutex::Autolock lock(mLock);
    params = mParameters;

    return params;
}

void CameraHardware::release()
{
    close(camera_device);
}

}; // namespace android
