#include "ImprovMain.h"
#include "Camera.h"
#include "QuickCam.h" 

#include "FW/labImage.h"
#include "FW/labImgDraw.h"

#include <stdio.h>

#if defined(HAVE_V4L)
#include "V4LCamera.h"
#endif

#define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof((a)[0]))

#define DEBUG 0

#if defined(HAVE_V4L2)
#include "V4L2Camera.h"
#endif

#ifndef MAX
#define MAX(a,b) ((a)>=(b)?(a):(b))
#endif
#ifndef MIN
#define MIN(a,b) ((a)>=(b)?(b):(a))
#endif


SeqCamera seqcamera;

Camera *cameras[] = {
#if defined(HAVE_V4L)
  //&v4lcamera,
#endif
#if defined(HAVE_V4L2)
  &v4l2camera,
#endif
#if defined (HAVE_QUICK)
  &quickcam,
#endif
  &seqcamera,
  NULL
};

//Number of cameras incl. NULL !IMPORTANT!
int nr_cameras=ARRAY_SIZE(cameras);


//default image sequence
#define SUBSCALE 1 
#define FACTOR 2

int subscale=SUBSCALE;
int factor=FACTOR;

char seqfilenames[MAXSEQLEN][MAXSEQNAMELEN];
int  seqfile_len;         /* number of frames in sequence           */
char seqfile_info;        /* L=loop, R=reverse (for display)        */
char seqfile_source[300]; /* origin information of sequence         */
int  seqfile_len_old = 0;

extern char img_path[];
extern char seq_path[];
extern int restart;

void GetSFiles(char *dirpath, char namelist[][MAXSEQNAMELEN], int *num, char *ssource, char *sinfo);


/* ************************************************************************* */
bool SeqCamera::open(IPL_CONFIG *ipl_config)
{ char s[300];
  int errtmp=0;
  
  seqfile_len_old=seqfile_len;
  
  // Determine number of files and filenames
  GetSFiles(seq_path, seqfilenames,
            &seqfile_len, seqfile_source, &seqfile_info);

  if (seqfile_len <= 0) return 0;
  else
  { if (DEBUG) fprintf(stderr,"open: seq name >%s< len: %d info: %c\n", seq_path, seqfile_len, seqfile_info);
    fprintf(stderr,"\nLoading Image sequence >%s<\n", seqfile_source);
    // Load image sequence
    for(int i=0; i < seqfile_len; i++)
    { 
      strcpy(s, img_path); 
      strcat(s, seq_path);
      strcat(s, "/");
      strcat(s, seqfilenames[i]);

      test_sequence[i] = newImage();
      fprintf(stderr,".");
      if(!loadImage(s, test_sequence[i])) errtmp=1;
      
      //Scale images to fit
      if(subscale)
	{
	  scaleImage(test_sequence[i],
		     MIN(ipl_config->displayWidth, test_sequence[i]->width),
		     MIN(ipl_config->displayHeight, test_sequence[i]->height ));
	}
      
      if(test_sequence[i]->width > ipl_config->displayWidth)
	test_sequence[i]=cropImage(test_sequence[i],0,0,
				   ipl_config->displayWidth, 
				   test_sequence[i]->height);
      
      if(test_sequence[i]->height > ipl_config->displayHeight)
	test_sequence[i]=cropImage(test_sequence[i],0,0,
				   test_sequence[i]->width,
				   ipl_config->displayHeight);
      
      
      //Init ipl_config
      ipl_config->imageWidth=test_sequence[0]->width;
      ipl_config->imageHeight=test_sequence[0]->height;
      ipl_config->imageType=test_sequence[0]->format;
      ipl_config->image_ratio = (float) ((float)ipl_config->imageHeight / 
					 (float) ipl_config->imageWidth);
      
      if(test_sequence[i]->width!=ipl_config->imageWidth || 
	 test_sequence[i]->height!=ipl_config->imageHeight )
	fprintf(stderr,"Not same size! \n");
    }             

    fprintf(stderr,"\n");
  
    if(errtmp)
    { fprintf(stderr,"One or more image files could not be found!\n" );
      fprintf(stderr,"Make sure the enviroment variable $IMPROVSEQ is set\n" );
      fprintf(stderr,"or specify a path for the images with 'improv -p[path]'!\n" );
    }
  
    printf(seqfile_source);  /* print in Improv */
    seq_index = 0;
    forward=1;

    ipl_config->colorBlack = DEFAULT_BLACK;
    ipl_config->colorWhite = DEFAULT_WHITE;
    
    return 1;
  }
}


void SeqCamera::close(void)
{
}


void SeqCamera::read(Picture *p_frame)
{ 
  //Play sequence forth and back
  if(forward) seq_index++;
  else seq_index--;
  
  if (seqfile_info=='R')  /* reverse */
  { if(seq_index>=seqfile_len-1) forward=0;
    else if (seq_index<=0)   forward=1;
  }
  else  /* seqfile_info=='L' loop */
  { if (seq_index>=seqfile_len-1) seq_index=0;
  } /* only forward */
  
  if(p_frame->format==pix_rgb24)
    {
      memcpy((BYTE *)p_frame->data,
	     (BYTE *)test_sequence[seq_index]->data,
	     test_sequence[seq_index]->datasize);
    }
  else if(p_frame->format==pix_grey)
    {    
      memcpy((BYTE *)p_frame->data,
	     (BYTE *)test_sequence[seq_index]->data,
	     test_sequence[seq_index]->datasize);
	     
    }
  
  frame_count++;
}


bool SeqCamera::iscolor(void)
{
  if(test_sequence[0]->format!=pix_grey)
    return true;
  else
    return false;
}


void SeqCamera::get_info(CamInfo *info)
{
  if(test_sequence[0]->data!=NULL)
    {
      info->width = test_sequence[0]->width;
      info->height = test_sequence[0]->height;
      
      if(test_sequence[0]->format==pix_grey)
	info->bpp = 1;
      else
	info->bpp = 3;
    }
}


bool SeqCamera::get_IPL(IPL_CONFIG *ipl_config)
{
  Picture *p_temp;
  char s[300];

  strcpy(s, img_path);
  strcat(s, seq_path);
  strcat(s, "/");
  strcat(s, seqfilenames[0]);
  
  p_temp=newImage();

  if(!loadImage_Info(s, p_temp))
    fprintf(stdout,"Image not found!");
  
  if(subscale)
    subscaleImage(p_temp,factor);
  
  
  if(p_temp->width > ipl_config->displayWidth)
    p_temp=cropImage(p_temp,0,0,
		     ipl_config->displayWidth, 
		     p_temp->height);
  
  if(p_temp->height > ipl_config->displayHeight)
    p_temp=cropImage(p_temp,0,0,
		     p_temp->width,
		     ipl_config->displayHeight); 
  
  ipl_config->imageWidth = p_temp->width;
  ipl_config->imageHeight= p_temp->height;
  ipl_config->imageType = p_temp->format;
  ipl_config->image_ratio = (float) ((float) p_temp->height / 
				     (float) p_temp->width);
  
  freeImage(p_temp);
 
  return 1;
}


void SeqCamera::params(double *p)
{
}

