/************************************************************************
 * merge frames into stream                                             *
 ************************************************************************/
//#define VIEWER
//#define DUMP_TO_FILE


#ifdef VIEWER
#include "CImg.h"
using namespace cimg_library;
#endif

#include "mergestream.h"

void mergestream_init(DOLProcess *p) {
    Mergestream_State *local = (Mergestream_State *)p->local;

    local->port_count = 0;
    local->num_iter = 0;
#ifdef VIEWER
    local->main_disp = new CImgDisplay(320, 240, "DOL MJPEG");
#endif
#ifdef VSPVIEWER
    local->c_ddev_base = (int *) (DDEV_BASE_ADDR);
    local->c_ddev_resx = (int *) (DDEV_BASE_ADDR + ADDR_DD_RESX);
    local->c_ddev_resy = (int *) (DDEV_BASE_ADDR + ADDR_DD_RESY);
    local-> c_ddev_refr = (int *) (DDEV_BASE_ADDR + ADDR_DD_REFR);
    local->vsp_buffer = (unsigned int *)(DDEV_BASE_ADDR + 
					      ADDR_DD_FRAM);
    *(local->c_ddev_resx) = 320;
    *(local->c_ddev_resy) = 240;
    *(local->c_ddev_refr) = 1;
#endif

}

int mergestream_fire(DOLProcess *p) {
    unsigned int i;
    Mergestream_State *local = (Mergestream_State *)p->local;
    unsigned int *x_size = &(local->x_size);
    unsigned int *y_size = &(local->y_size);
    CREATEPORTVAR(output_port1);
    CREATEPORTVAR(output_port2);

    //dbgprintf(VERBOSE, "\tMERGESTREAM\tthread is alive !\n");

    // create port
    CREATEPORT(output_port1, PORT_MERGESTREAM_IN1, 1, local->port_count, NUM_OF_PAR_PORTS);
    CREATEPORT(output_port2, PORT_MERGESTREAM_IN2, 1, local->port_count, NUM_OF_PAR_PORTS);
    local->port_count = (local->port_count + 1) % NUM_OF_PAR_PORTS;

    // get the size
    DOL_read((void*)output_port2, x_size, sizeof(*x_size), p);
    DOL_read((void*)output_port2, y_size, sizeof(*y_size), p);

    //read picture row-by-row
    unsigned char *FrameBuffer = local->display_buffer;
    for (i=0; i < *y_size / MCU_sy; i++) {
        DOL_read((void*)output_port1,
                 &(FrameBuffer[i * *x_size * MCU_sy]),
                 *x_size * MCU_sy, p);
#ifdef VSPVIEWER
	// copy to the vsp display
	for (int j=0;j<*x_size * MCU_sy;j++)
	  local->vsp_buffer[i * *x_size * MCU_sy+j] = (unsigned int)FrameBuffer[i * *x_size * MCU_sy+j];
#endif
    }
    //    printf("x_size:%d y_size:%d MCU_sy:%d\n", *x_size, *y_size, MCU_sy);
    // show input in HEX
    /*
        printf("\nnumber:%d\n", local->num_iter);
	for (i=0; i < (*y_size) * (*x_size) ;) {
          printf("%x ", FrameBuffer[i]);
          if ((i%1000) == 0) printf("\n");
          i += 100;
	}
    */
    // end show input
#ifdef VSPVIEWER
*(local->c_ddev_refr) = 1;
#endif     

#ifdef VIEWER
    //create image from display_buffer and display it
    CImg<unsigned char> img(local->display_buffer,
            local->x_size, local->y_size),
            visu(local->x_size, local->y_size, 1, 1, 0);
    local->main_disp->display(img);
    local->main_disp->paint();
#endif

#ifdef DUMP_TO_FILE
    // Dump frame in file   
    char buf[256];
    int xidx, yidx;
    snprintf(buf, 256, "frame-%5.5d.ppm", local->num_iter);
    FILE  *ppmout = fopen(buf, "w");
    fprintf(ppmout, "P2\n%d %d\n255\n", local->x_size, local->y_size);
    for (yidx = 0; yidx < local->y_size; yidx++) {
      for (xidx = 0; xidx < local->x_size; xidx++) {	  
        fprintf(ppmout, "%d ", FrameBuffer[yidx*320+xidx]);
      }
      fprintf(ppmout, "\n");
    }
    fclose(ppmout);
    // End dumping frame to file
#else
    // Dump frame in stdout
    char buf[256];
    int xidx, yidx;

    PRINTSTR(P2);
    PRINTSTR(\n);
    PRINTNUM(, %d, local->x_size);
    PRINTSPACE();
    PRINTNUM(, %d, local->y_size);
    PRINTSTR(\n);
    PRINTSTR(255);
    PRINTSTR(\n);
   
    for (yidx = 0; yidx < local->y_size; yidx++) {
      for (xidx = 0; xidx < local->x_size; xidx++) {
        PRINTNUM(, %d, FrameBuffer[yidx*320+xidx]);
        PRINTSPACE();
      }
      PRINTSTR(\n);
    } 
    // End dumping frame to stdout
#endif

    //end this process
    local->num_iter++;
    if (local->num_iter == NUMBER_OF_FRAMES) {

        DOL_detach(p);
        return 0;
    }

    return 0;
}
