/*
** Copyright (c) 2011-2012 The Linux Foundation. All rights reserved.
**
** 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.
*/

/*#error uncomment this for compiler test!*/

#define ALOG_NDEBUG 0
#define ALOG_NIDEBUG 0

#define LOG_TAG __FILE__
#include <utils/Log.h>
#include <utils/threads.h>


#include "QCameraStream.h"

/* QCameraStream class implementation goes here*/
/* following code implement the control logic of this class*/

namespace android {

StreamQueue::StreamQueue(){
    mInitialized = false;
}

StreamQueue::~StreamQueue(){
    flush();
}

void StreamQueue::init(){
    Mutex::Autolock l(&mQueueLock);
    mInitialized = true;
    mQueueWait.signal();
}

void StreamQueue::deinit(){
    Mutex::Autolock l(&mQueueLock);
    mInitialized = false;
    mQueueWait.signal();
}

bool StreamQueue::isInitialized(){
   Mutex::Autolock l(&mQueueLock);
   return mInitialized;
}

bool StreamQueue::enqueue(
                 void * element){
    Mutex::Autolock l(&mQueueLock);
    if(mInitialized == false)
        return false;

    mContainer.add(element);
    mQueueWait.signal();
    return true;
}

bool StreamQueue::isEmpty(){
    return (mInitialized && mContainer.isEmpty());
}
void* StreamQueue::dequeue(){

    void *frame;
    mQueueLock.lock();
    while(mInitialized && mContainer.isEmpty()){
        mQueueWait.wait(mQueueLock);
    }

    if(!mInitialized){
        mQueueLock.unlock();
        return NULL;
    }

    frame = mContainer.itemAt(0);
    mContainer.removeAt(0);
    mQueueLock.unlock();
    return frame;
}

void StreamQueue::flush(){
    Mutex::Autolock l(&mQueueLock);
    mContainer.clear();
}


// ---------------------------------------------------------------------------
// QCameraStream
// ---------------------------------------------------------------------------

/* initialize a streaming channel*/
status_t QCameraStream::initChannel(int cameraId,
                                    uint32_t ch_type_mask)
{
#if 0
    int rc = MM_CAMERA_OK;
    int i;
    status_t ret = NO_ERROR;
    int width = 0;  /* width of channel      */
    int height = 0; /* height of channel */
    cam_ctrl_dimension_t dim;
    mm_camera_ch_image_fmt_parm_t fmt;

    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
    rc = cam_config_get_parm(cameraId, MM_CAMERA_PARM_DIMENSION, &dim);
    if (MM_CAMERA_OK != rc) {
      ALOGE("%s: error - can't get camera dimension!", __func__);
      ALOGE("%s: X", __func__);
      return BAD_VALUE;
    }

    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask) {
        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
        ALOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);

        if(MM_CAMERA_OK != rc) {
                ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
                ALOGE("%s: X", __func__);
                return BAD_VALUE;
        }
        else{
            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
            fmt.ch_type = MM_CAMERA_CH_PREVIEW;
            fmt.def.fmt = CAMERA_YUV_420_NV12; //dim.prev_format;
            fmt.def.dim.width = dim.display_width;
            fmt.def.dim.height =  dim.display_height;
            ALOGV("%s: preview channel fmt = %d", __func__,
                     dim.prev_format);
            ALOGV("%s: preview channel resolution = %d X %d", __func__,
                     dim.display_width, dim.display_height);

            rc = cam_config_set_parm(cameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
            ALOGV("%s: preview MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
            if(MM_CAMERA_OK != rc) {
                    ALOGE("%s:set preview channel format err=%d\n", __func__, ret);
                    ALOGE("%s: X", __func__);
                    ret = BAD_VALUE;
            }
        }
    }


    if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask)
    {
        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
        ALOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);

        if(MM_CAMERA_OK != rc) {
                ALOGE("%s: video channel acquir error =%d\n", __func__, rc);
                ALOGE("%s: X", __func__);
                ret = BAD_VALUE;
        }
        else {
            memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
            fmt.ch_type = MM_CAMERA_CH_VIDEO;
            fmt.video.video.fmt = CAMERA_YUV_420_NV12; //dim.enc_format;
            fmt.video.video.dim.width = dim.video_width;
            fmt.video.video.dim.height = dim.video_height;
            ALOGV("%s: video channel fmt = %d", __func__,
                     dim.enc_format);
            ALOGV("%s: video channel resolution = %d X %d", __func__,
                 dim.video_width, dim.video_height);

            rc = cam_config_set_parm(cameraId,  MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);

            ALOGV("%s: video MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
            if(MM_CAMERA_OK != rc) {
                ALOGE("%s:set video channel format err=%d\n", __func__, rc);
                ALOGE("%s: X", __func__);
                ret= BAD_VALUE;
            }
        }

  } /*MM_CAMERA_CH_VIDEO*/
#endif

    int rc = MM_CAMERA_OK;
    status_t ret = NO_ERROR;
    mm_camera_op_mode_type_t op_mode=MM_CAMERA_OP_MODE_VIDEO;
    int i;

    ALOGV("QCameraStream::initChannel : E");
    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_PREVIEW);
        ALOGV("%s:ch_acquire MM_CAMERA_CH_PREVIEW, rc=%d\n",__func__, rc);
        if(MM_CAMERA_OK != rc) {
                ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
                ALOGV("%s: X", __func__);
                return BAD_VALUE;
        }
        /*Callback register*/
        /* register a notify into the mmmm_camera_t object*/
       /* ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_PREVIEW,
                                                preview_notify_cb,
                                                this);
        ALOGV("Buf notify MM_CAMERA_CH_PREVIEW, rc=%d\n",rc);*/
    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
        rc = cam_ops_ch_acquire(cameraId, MM_CAMERA_CH_VIDEO);
        ALOGV("%s:ch_acquire MM_CAMERA_CH_VIDEO, rc=%d\n",__func__, rc);
        if(MM_CAMERA_OK != rc) {
                ALOGE("%s: preview channel acquir error =%d\n", __func__, rc);
                ALOGV("%s: X", __func__);
                return BAD_VALUE;
        }
        /*Callback register*/
        /* register a notify into the mmmm_camera_t object*/
        /*ret = cam_evt_register_buf_notify(mCameraId, MM_CAMERA_CH_VIDEO,
                                                record_notify_cb,
                                                this);
        ALOGV("Buf notify MM_CAMERA_CH_VIDEO, rc=%d\n",rc);*/
    }

    ret = (MM_CAMERA_OK==rc)? NO_ERROR : BAD_VALUE;
    ALOGV("%s: X, ret = %d", __func__, ret);
    return ret;
}

status_t QCameraStream::deinitChannel(int cameraId,
                                    mm_camera_channel_type_t ch_type)
{

    int rc = MM_CAMERA_OK;

    ALOGV("%s: E, channel = %d\n", __func__, ch_type);

    if (MM_CAMERA_CH_MAX <= ch_type) {
        ALOGE("%s: X: BAD_VALUE", __func__);
        return BAD_VALUE;
    }

    cam_ops_ch_release(cameraId, ch_type);

    ALOGV("%s: X, channel = %d\n", __func__, ch_type);
    return NO_ERROR;
}

status_t QCameraStream::setMode(int enable) {
  ALOGV("%s :myMode %x ", __func__, myMode);
  if (enable) {
      myMode = (camera_mode_t)(myMode | CAMERA_ZSL_MODE);
  } else {
      myMode = (camera_mode_t)(myMode & ~CAMERA_ZSL_MODE);
  }
  return NO_ERROR;
}

status_t QCameraStream::setFormat(uint8_t ch_type_mask, cam_format_t previewFmt)
{
    int rc = MM_CAMERA_OK;
    status_t ret = NO_ERROR;
    int width = 0;  /* width of channel      */
    int height = 0; /* height of channel */
    cam_ctrl_dimension_t dim;
    mm_camera_ch_image_fmt_parm_t fmt;
    ALOGV("%s: E",__func__);

    memset(&dim, 0, sizeof(cam_ctrl_dimension_t));
    rc = cam_config_get_parm(mCameraId, MM_CAMERA_PARM_DIMENSION, &dim);
    if (MM_CAMERA_OK != rc) {
      ALOGE("%s: error - can't get camera dimension!", __func__);
      ALOGV("%s: X", __func__);
      return BAD_VALUE;
    }
    char mDeviceName[PROPERTY_VALUE_MAX];
    property_get("ro.product.device",mDeviceName," ");
    memset(&fmt, 0, sizeof(mm_camera_ch_image_fmt_parm_t));
    if(MM_CAMERA_CH_PREVIEW_MASK & ch_type_mask){
        fmt.ch_type = MM_CAMERA_CH_PREVIEW;
        fmt.def.fmt = (cam_format_t)previewFmt;
        fmt.def.dim.width = dim.display_width;
        fmt.def.dim.height =  dim.display_height;
    }else if(MM_CAMERA_CH_VIDEO_MASK & ch_type_mask){
        fmt.ch_type = MM_CAMERA_CH_VIDEO;
        fmt.video.video.fmt = CAMERA_YUV_420_NV21; //dim.enc_format;
        fmt.video.video.dim.width = dim.video_width;
        fmt.video.video.dim.height = dim.video_height;
    }/*else if(MM_CAMERA_CH_SNAPSHOT_MASK & ch_type_mask){
        if(mHalCamCtrl->isRawSnapshot()) {
            fmt.ch_type = MM_CAMERA_CH_RAW;
            fmt.def.fmt = CAMERA_BAYER_SBGGR10;
            fmt.def.dim.width = dim.raw_picture_width;
            fmt.def.dim.height = dim.raw_picture_height;
        }else{
            //Jpeg???
            fmt.ch_type = MM_CAMERA_CH_SNAPSHOT;
            fmt.snapshot.main.fmt = dim.main_img_format;
            fmt.snapshot.main.dim.width = dim.picture_width;
            fmt.snapshot.main.dim.height = dim.picture_height;

            fmt.snapshot.thumbnail.fmt = dim.thumb_format;
            fmt.snapshot.thumbnail.dim.width = dim.ui_thumbnail_width;
            fmt.snapshot.thumbnail.dim.height = dim.ui_thumbnail_height;
        }
    }*/

    rc = cam_config_set_parm(mCameraId, MM_CAMERA_PARM_CH_IMAGE_FMT, &fmt);
    ALOGV("%s: Stream MM_CAMERA_PARM_CH_IMAGE_FMT rc = %d\n", __func__, rc);
    if(MM_CAMERA_OK != rc) {
        ALOGE("%s:set stream channel format err=%d\n", __func__, ret);
        ALOGV("%s: X", __func__);
        ret = BAD_VALUE;
    }
    ALOGV("%s: X",__func__);
    return ret;
}

QCameraStream::QCameraStream (){
    mInit = false;
    mActive = false;
    /* memset*/
    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
}

QCameraStream::QCameraStream (int cameraId, camera_mode_t mode)
              :mCameraId(cameraId),
               myMode(mode)
{
    mInit = false;
    mActive = false;

    /* memset*/
    memset(&mCrop, 0, sizeof(mm_camera_ch_crop_t));
}

QCameraStream::~QCameraStream () {;}


status_t QCameraStream::init() {
    return NO_ERROR;
}

status_t QCameraStream::start() {
    return NO_ERROR;
}

void QCameraStream::stop() {
    return;
}

void QCameraStream::release() {
    return;
}

void QCameraStream::setHALCameraControl(QCameraHardwareInterface* ctrl) {

    /* provide a frame data user,
    for the  queue monitor thread to call the busy queue is not empty*/
    mHalCamCtrl = ctrl;
}

}; // namespace android
