/***************************************************************************
 * 
 * Copyright 1995  by  the  Massachusetts Institute  of Technology.   All  
 * rights reserved.
 * 
 * Developed  by the Perceptual Computing Section 
 * at the Media Laboratory, MIT, Cambridge, Massachusetts.
 * 
 * Permission to use, copy,  or modify this software and  its documentation
 * for  educational  and  research purposes only and without fee  is hereby
 * granted, provided  that this copyright notice and the original authors's
 * names appear  on all copies and supporting documentation.  If individual
 * files are  separated from  this  distribution directory  structure, this
 * copyright notice must be included.  For any other uses of this software,
 * in original or  modified form, including but not limited to distribution
 * in whole or in  part, specific  prior permission  must be  obtained from
 * MIT.  These programs shall not  be  used, rewritten, or  adapted as  the
 *   basis  of  a commercial  software  or  hardware product  without first
 * obtaining appropriate licenses  from MIT.  MIT. makes no representations
 * about the suitability of this  software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 * 
 **************************************************************************/

/* pf-proc.cpp */

#include <stdio.h>
#include <stdlib.h>
#define _BSD_SIGNALS
#include <signal.h>
#include <unistd.h>
#include <iostream.h>
#include <bstring.h>
#include <math.h>

#include "Parse/Parse.h++"
#include "VLImage.h++"
#include "pfGesture.h++"
#include "pfContour.h++"

#define Time MYTIME
#include "lite.h++"
#undef Time
    VLControlValue timing;
extern "C"
{
#include "ivePoint.h"
#include "iveBitmap.h"
#include "iveImage.h"
#include "bsColor.h"
#include "bsClassify.h"
#include "bsSegment.h"
#include "pfMorphology.h"
}

static int decimate = 1;
static int maxForegroundClasses = 8;
static int numberOfBGFrames = 5;
static iveImage **BackgroundFrames = NULL;
Point lowerLeft;
Point lowerRight;

extern "C" {
Point seed_points_for_morphology[1024];
int erodemultiple = 10;
}

int THAD_TRACKER = 0; /* track green and red blobs for thad */
int INITCLASSFLAG = 0;


extern int FOREGROUND;  // should be in bsClassify.h (or something)
static int FRAMEZERO;

int SEGMENT=1; /* continous */
int SEGMENT_TRIGGER=0; /* one shot */

void cleanup( void );
void cleanup_sig( ... );


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * segmentFrame
 *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

static int frameNumber = -1;

int bsMainGetFrameNumber()
{
  return frameNumber;
}

void
segmentFrame( iveImage *image)
{
  /* does not need frameNumber as an arg; can keep track internally */

  int  x,y;
  static Point centroid;
  static iveBitmap *newMap = (iveBitmap *)NULL;
  static iveBitmap *oldMap = (iveBitmap *)NULL;
  iveBitmap *tempMap = NULL;

  frameNumber++;

  /* First time call */
  if (FRAMEZERO) {
    frameNumber = 0;
    FRAMEZERO = 0;
  }  

  /* Allocate memory for segmentation maps */
  if( newMap == (iveBitmap *)NULL )
    {
      int height = image->height;
      int width = image->width;
      
      newMap = iveBitmapMake( height, width );
      oldMap = iveBitmapMake( height, width );
      iveBitmapZero( oldMap );
      centroid.x = 0;
      centroid.y = 0;	
    }

  /* Store background frames */
  if (frameNumber < numberOfBGFrames) {
    BackgroundFrames[frameNumber] = iveImageMakeCopy(image);   
    return;
  }

  /* Analyze background frames */
  if (frameNumber == numberOfBGFrames){ 
     bsClassifyMakeBackgroundClasses(BackgroundFrames, numberOfBGFrames);
  }  

  /* classify */
  iveBitmapZero( newMap );

  /* Segment image */
  bsSegmentFindSilhouette( image, newMap, oldMap, decimate, &(centroid));

  /* Update foreground model */
  bsClassifySetForegroundStats(image,newMap);
 
  /* Update background model */
  bsClassifyUpdateBG( image, newMap );

  /* Copy segmentation to alpha channel */
  for (y=0; y<(int)(image->height/2);++y)
    for (x=0; x<(int)(image->width/2);++x)
       if (iveBitmapGetBit(newMap,2*y,2*x))
	   image->data[(y*image->width+x)*4]=255;  

  tempMap = oldMap;
  oldMap = newMap;
  newMap = tempMap;

  return;
}

 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * cleanup
 * cleanup_sig
 *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

void cleanup_do( void ) 
{
}

void cleanup( void )
{
  cleanup_do();
  exit(1);
}

void cleanup_sig( ... )
{
  cerr << "Caught Signal" << getpid()  << endl;       
  cleanup();
}

void
pfinderinit(int width, int height)
{
  signal(SIGINT, cleanup_sig);
  signal(SIGPIPE, cleanup_sig); 
  signal(SIGHUP, cleanup_sig);
  signal(SIGILL, cleanup_sig);

  lite::initialize(); 
  /* Initialize models*/
  bsClassifyInitialize(width,height,maxForegroundClasses);

  /* Allocate memory for initialization frames*/
  BackgroundFrames=(iveImage **) malloc(sizeof(iveImage *) * numberOfBGFrames);

  FRAMEZERO=1;  
  return;
}



