/*
Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of Code Aurora Forum, Inc. nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <pthread.h>
#include "mm_camera_dbg.h"
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <poll.h>
#include "mm_qcamera_app.h"

#define BUFF_SIZE_128 128
static int num_run = 0;

static int mm_app_dump_video_frame(struct msm_frame *frame,
								   uint32_t len)
{
	static int v_cnt = 0;
	char bufp[BUFF_SIZE_128];
	int file_fdp;
	int rc = 0;

	return rc; /* disable dump */

	v_cnt++;
	if(0 == (v_cnt % 10))
		snprintf(bufp, BUFF_SIZE_128, "/data/v_%d.yuv", v_cnt);
	else
		return 0;

	file_fdp = open(bufp, O_RDWR | O_CREAT, 0777);

	if (file_fdp < 0) {
		CDBG("cannot open file %s\n", bufp);
		rc = -1;
		goto end;
	}
	CDBG("%s:dump frame to '%s'\n", __func__, bufp);
	write(file_fdp,
		(const void *)frame->buffer, len);
	close(file_fdp);
end:
	return rc;
}

static int mm_app_set_video_fmt(int cam_id,mm_camera_image_fmt_t *fmt)
{
	int rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	fmt->meta_header = MM_CAMEAR_META_DATA_TYPE_DEF;
	fmt->fmt = pme->dim.enc_format;
	fmt->width = pme->dim.video_width;
	fmt->height = pme->dim.video_height;
	return rc;
}

#if 0
int mm_stream_deinit_video_buf(uint32_t camera_handle,
                      uint32_t ch_id, uint32_t stream_id,
                      void *user_data, uint8_t num_bufs,
                      mm_camera_buf_def_t *bufs)
{
	int i, rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;

	for(i = 0; i < num_bufs; i++) {
		rc = my_cam_app.hal_lib.mm_camera_do_munmap_ion (pme->ionfd, &(pme->video_buf.frame[i].fd_data),
                   (void *)pme->video_buf.frame[i].buffer, pme->video_buf.frame_len);
		if(rc != MM_CAMERA_OK) {
		  CDBG_ERROR("%s: mm_camera_do_munmap err, pmem_fd = %d, rc = %d",
			   __func__, bufs[i].fd, rc);
		}
	}
	return rc;
}

int mm_stream_init_video_buf(uint32_t camera_handle,
                      uint32_t ch_id, uint32_t stream_id,
                      void *user_data,
                      mm_camera_frame_len_offset *frame_offset_info,
                      uint8_t num_bufs,
                      uint8_t *initial_reg_flag,
                      mm_camera_buf_def_t *bufs)
{
	int i,j,num_planes, frame_len, y_off, cbcr_off;
	uint32_t planes[VIDEO_MAX_PLANES];
	uint32_t pmem_addr = 0;

	mm_camera_app_obj_t *pme = (mm_camera_app_obj_t *)user_data;

	num_planes = frame_offset_info->num_planes;
	for ( i = 0; i < num_planes; i++) {
		planes[i] = frame_offset_info->mp[i].len;
	}

	frame_len = frame_offset_info->frame_len;
	y_off = frame_offset_info->mp[0].offset;
	cbcr_off = frame_offset_info->mp[1].offset;

	CDBG("Allocating video Memory for %d buffers frame_len = %d",num_bufs,frame_offset_info->frame_len);

	for (i = 0; i < num_bufs ; i++) {
	    int j;
		pme->video_buf.reg[i] = 1;
		initial_reg_flag[i] = 1;

	    pme->video_buf.frame_len = frame_len;
		pme->video_buf.frame[i].ion_alloc.len = pme->video_buf.frame_len;
		pme->video_buf.frame[i].ion_alloc.flags =
			(0x1 << CAMERA_ION_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID);
		pme->video_buf.frame[i].ion_alloc.align = 4096;

		pmem_addr = (unsigned long) my_cam_app.hal_lib.mm_camera_do_mmap_ion(pme->ionfd,
                       &(pme->video_buf.frame[i].ion_alloc), &(pme->video_buf.frame[i].fd_data),
                       &pme->video_buf.frame[i].fd);

		pme->video_buf.frame[i].buffer = pmem_addr;
		pme->video_buf.frame[i].path = OUTPUT_TYPE_V;
		pme->video_buf.frame[i].y_off = 0;
		pme->video_buf.frame[i].cbcr_off = planes[0];
		pme->video_buf.frame[i].phy_offset = 0;

		CDBG("Buffer allocated Successfully fd = %d",pme->video_buf.frame[i].fd);

		bufs[i].fd = pme->video_buf.frame[i].fd;
		//bufs[i].buffer = pmem_addr;
		bufs[i].frame_len = pme->video_buf.frame[i].ion_alloc.len;
		bufs[i].num_planes = num_planes;

		bufs[i].frame = &pme->video_buf.frame[i];

		/* Plane 0 needs to be set seperately. Set other planes
             * in a loop. */
        bufs[i].planes[0].length = planes[0];
        bufs[i].planes[0].m.userptr = bufs[i].fd;
        bufs[i].planes[0].data_offset = y_off;
        bufs[i].planes[0].reserved[0] = 0;
              //buf_def->buf.mp[i].frame_offset;
		for (j = 1; j < num_planes; j++) {
			 bufs[i].planes[j].length = planes[j];
			 bufs[i].planes[j].m.userptr = bufs[i].fd;
			 bufs[i].planes[j].data_offset = cbcr_off;
			 bufs[i].planes[j].reserved[0] =
				 bufs[i].planes[j-1].reserved[0] +
				 bufs[i].planes[j-1].length;
		}
	}
    return MM_CAMERA_OK;
}
#endif

void video_cb_signal(mm_camera_app_obj_t *pme)
{
	if(pme->cam_state == CAMERA_STATE_RECORD) {
		mm_camera_app_done();
	}
}

static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs,
	void *user_data)
{
	int rc;
	mm_camera_buf_def_t *frame = NULL;
	mm_camera_app_obj_t *pme = NULL;
	CDBG("%s: BEGIN\n", __func__); 
	frame = bufs->bufs[MM_CAMERA_PREVIEW] ;
	pme = (mm_camera_app_obj_t *)user_data;
	
	CDBG("%s: BEGIN - length=%d, frame idx = %d\n", __func__, frame->frame_len, frame->frame_idx);
	//Need to code to Send to Encoder .. Simulat
	CDBG("In CB function i/p = %p o/p = %p",bufs->bufs[MM_CAMERA_PREVIEW],frame);

	dumpFrameToFile(frame,pme->dim.orig_video_width,pme->dim.orig_video_height,"video", 1);
	if(MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,pme->ch_id,frame))
	{
		CDBG_ERROR("%s: Failed in Snapshot Qbuf\n", __func__);
		return;
	}
    video_cb_signal(pme);
	CDBG("%s: END\n", __func__); 

}

int mm_app_config_video(int cam_id)
{
	int rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	mm_app_set_video_fmt(cam_id,&pme->stream[MM_CAMERA_VIDEO].str_config.fmt);
	pme->stream[MM_CAMERA_VIDEO].str_config.need_stream_on = 1;
	pme->stream[MM_CAMERA_VIDEO].str_config.num_of_bufs = VIDEO_BUF_NUM;

	if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id,
								 &pme->stream[MM_CAMERA_VIDEO].str_config))) {
		CDBG_ERROR("%s:MM_CAMERA_VIDEO config streaming err=%d\n", __func__, rc);
		goto end;
	}

	CDBG("config_stream stream is successfull");

	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.need_stream_on = pme->fullSizeSnapshot;
	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.num_of_bufs = 1;

	mm_app_set_live_snapshot_fmt(cam_id,&pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config.fmt);

	if(MM_CAMERA_OK != (rc = pme->cam->ops->config_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id,
								 &pme->stream[MM_CAMERA_SNAPSHOT_MAIN].str_config))) {
		CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
		goto end;
	}
end:
	return rc;

}

int mm_app_prepare_video(int cam_id)
{
	int rc = MM_CAMERA_OK;

	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	pme->stream[MM_CAMERA_VIDEO].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
													   mm_app_video_notify_cb,pme,
												       MM_CAMERA_VIDEO, 0);

	if(!pme->stream[MM_CAMERA_VIDEO].id) {
		CDBG("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
		rc = -1;
		goto end;
	}

	CDBG("Add stream is successfull stream ID = %d",pme->stream[MM_CAMERA_PREVIEW].id);

	/* Code to add live snapshot*/
	pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id = pme->cam->ops->add_stream(pme->cam->camera_handle,pme->ch_id,
												   NULL,pme,
												   MM_CAMERA_SNAPSHOT_MAIN, 0);

	CDBG("Add Snapshot main is successfull stream ID = %d",pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id);
	if(!pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id) {
		CDBG_ERROR("%s:preview streaming err=%d\n", __func__, rc);
		rc = -1;
		goto end;
	}
	/*if(mm_app_config_video(cam_id) != MM_CAMERA_OK)
	{
		CDBG_ERROR("%s:Video config err=%d\n", __func__, rc);
	}*/
end:
	return rc;
}

int mm_app_unprepare_video(int cam_id)
{
	int rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_VIDEO].id))){
		CDBG_ERROR("%s : Delete Stream Video error",__func__);
		goto end;
	}

	if(MM_CAMERA_OK != (rc = pme->cam->ops->del_stream(pme->cam->camera_handle,pme->ch_id,pme->stream[MM_CAMERA_SNAPSHOT_MAIN].id))){
		CDBG_ERROR("%s : Delete Stream Video error",__func__);
		goto end;
	}
end:
	CDBG("del_stream successfull");
	return rc;
}

static int mm_app_streamon_video(int cam_id)
{
	int stream[2];
	int rc = MM_CAMERA_OK;

	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	if(mm_app_config_video(cam_id) != MM_CAMERA_OK)
	{
		CDBG_ERROR("%s:Video config err=%d\n", __func__, rc);
	}

	stream[MM_CAMERA_VIDEO] = pme->stream[MM_CAMERA_VIDEO].id;
	if(MM_CAMERA_OK != (rc = pme->cam->ops->start_streams(pme->cam->camera_handle,pme->ch_id,1,&stream[1])))
	{
		CDBG_ERROR("%s : Start Stream video Error",__func__);
		return -1;
	}
	CDBG("Start video stream is successfull");
	pme->cam_state = CAMERA_STATE_RECORD;
	return rc;
}

static int mm_app_streamoff_video(int cam_id)
{
	int stream[2];
	int rc = MM_CAMERA_OK;

	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	stream[0] = pme->stream[MM_CAMERA_VIDEO].id;

	if(MM_CAMERA_OK != (rc =pme->cam->ops->stop_streams(pme->cam->camera_handle,pme->ch_id,1,&stream)))
	{
		CDBG_ERROR("%s : stop Stream video Error",__func__);
		goto end;
	}
	CDBG("stop video stream is successfull");
	pme->cam_state = CAMERA_STATE_PREVIEW;
end:
	return rc;

}
int mm_app_stop_video(int cam_id)
{
	int stream[2];
	int rc = MM_CAMERA_OK;

	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	stream[0] = pme->stream[MM_CAMERA_VIDEO].id;

	if(MM_CAMERA_OK != (rc = mm_app_streamoff_video(cam_id))){
		CDBG_ERROR("%s : Video Stream off error",__func__);
		goto end;
	}
end:
	return rc;
}

static int mm_app_start_video(int cam_id)
{
	int rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	CDBG("pme = %p, pme->cam =%p, pme->ch = %d pme->cam->camera_handle = %d",
		 pme,pme->cam,pme->ch_id,pme->cam->camera_handle);

	if(MM_CAMERA_OK != (rc =  mm_app_prepare_video(cam_id))){
		CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
		goto end;
	}
	if(MM_CAMERA_OK != (rc =  mm_app_streamon_video(cam_id))){
		CDBG_ERROR("%s:MM_CAMERA_VIDEO streaming err = %d\n", __func__, rc);
		goto end;
	}
	
end:
	CDBG("%s: END, rc=%d\n", __func__, rc); 

	return rc;
}

int mm_app_open_recorder(int cam_id)
{
	int rc = MM_CAMERA_OK;
	int value = 1;
	int powermode = 1;

	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	CDBG("%s: mm_app_open_recorder",__func__);
	if(pme->cam_mode == RECORDER_MODE) {
		CDBG("%s : Already in record mode",__func__);
		return rc;
	}

	if(MM_CAMERA_OK != (rc = mm_app_stop_preview(cam_id))){
		CDBG_ERROR("%s:Stop preview err=%d\n", __func__, rc);
		goto end;
	}

	if(MM_CAMERA_OK != initDisplay())
	{
		CDBG_ERROR("%s : Could not initalize display",__func__);
		goto end;
	}

	pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_RECORDING_HINT, &value);

	pme->cam->ops->set_parm(pme->cam->camera_handle,MM_CAMERA_PARM_LOW_POWER_MODE, &powermode);


	if(MM_CAMERA_OK != (rc = mm_app_prepare_preview(cam_id))){
		CDBG_ERROR("%s:stream on preview err=%d\n", __func__, rc);
		goto end;
	}

	if(MM_CAMERA_OK != (rc = mm_app_prepare_video(cam_id))){
		CDBG_ERROR("%s:stream on video err=%d\n", __func__, rc);
		goto end;
	}

	if(MM_CAMERA_OK != (rc = mm_app_streamon_preview(cam_id))){
		CDBG_ERROR("%s:start preview err=%d\n", __func__, rc);
		goto end;
	}
	pme->cam_mode = RECORDER_MODE;
end:
	CDBG("%s: END, rc=%d\n", __func__, rc);
	return rc;
}

int startRecording(int cam_id)
{
	int rc = MM_CAMERA_OK;
	
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	CDBG("%s: Start Recording mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state);

	if(pme->cam_mode == CAMERA_MODE || pme->cam_mode == ZSL_MODE) {
		switch(pme->cam_state) {
			case CAMERA_STATE_PREVIEW:
				if(MM_CAMERA_OK != mm_app_open_recorder(cam_id)){
					CDBG_ERROR("%s: Open Record Failed \n", __func__);
					return -1;
				}
				break;
			case CAMERA_STATE_RECORD:
			case CAMERA_STATE_SNAPSHOT:
			default:
				break;
		}
	}/*else{
		mm_app_prepare_video(cam_id);
	}*/
	CDBG("%s : startRecording : mode = %d state = %d",__func__,pme->cam_mode,pme->cam_state);
	if(pme->cam_mode == RECORDER_MODE && pme->cam_state == CAMERA_STATE_PREVIEW){
		if(MM_CAMERA_OK != mm_app_streamon_video(cam_id)){
			CDBG_ERROR("%s:start video err=%d\n", __func__, rc);
			return -1;
		}
	}
	CDBG("%s: END, rc=%d\n", __func__, rc);
	return rc;
}

int stopRecording(int cam_id)
{

	int rc = MM_CAMERA_OK;
	mm_camera_app_obj_t *pme = mm_app_get_cam_obj(cam_id);

	if(pme->cam_mode != RECORDER_MODE || pme->cam_state != CAMERA_STATE_RECORD) {
		return rc;
	}
	if(MM_CAMERA_OK != mm_app_stop_video(cam_id)){
		CDBG_ERROR("%s:stop video err=%d\n", __func__, rc);
		return -1;
	}
	return rc;
}

