
#include <OpenCV/OpenCV.h>
#include <stdio.h>
#include <ctype.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>       // for memset
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

#define BUFFER_SIZE 1024  // maximum network message size
#define DEFAULT_PORT 2000 // maximum network message size

CvConnectedComp getDot();

int timeToQuitNow = 0;    // global flag so that either thread can tell the other to quit

FILE *fp = NULL;

struct CC
{
int npixels;
double xavg;
double yavg;
};

void print_CC(struct CC x)
{
printf("CC: %d %g %g\n", x.npixels, x.xavg, x.yavg);
}

void printCC(CvConnectedComp cc)
{
printf("Area: %g\n", cc.area);
//printf("Value: %d %d %d\n", cc.value.val[0], cc.value.val[1], cc.value.val[2]);
}

struct color
{
int hmi, hma, smi, sma, vmi, vma, rmi, rma, gmi, gma, bmi, bma;
};

struct object
{
int col[10];
};


int drawingRectangle=0;

struct CC thecc;
int current_color;
CvScalar fill_colors[10];	
struct color colors[11];					  
int color_nums[11]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1};
struct object objects[10];
int object_nums[10]={1,-1,-1,-1,-1,-1,-1,-1,-1,-1};

int xclick=-1;
int yclick=-1;
IplImage *image = 0, *hsv = 0, *mask = 0, *frame=0;
int ourmode = 0;
int range=30;
CvPoint origin;
CvRect selection;
int vmin = 0, vmax = 256,smin = 0, smax=256, hmin=0, hmax=256 ;
int rmin = 0, rmax = 256;
int gmin = 0, gmax = 256;
int bmin = 0, bmax = 256;
int found_dot=0;

/*
 * error prints and quits
 */
void error(char *msg)
{
    perror(msg);
    exit(1);
}

/*
 * the server thread
 */
void *runServerThread(void *portid)
{
  char buffer[BUFFER_SIZE];                // the message buffer (input)
  char outputBuffer[BUFFER_SIZE];          // the output buffer
  unsigned int sockfd, newsockfd, clilen;  // network variables
  struct sockaddr_in serv_addr, cli_addr;  // network configuration
  int i,n;                    // indices
  int portno = (int)portid;   // the input port number

  memset(buffer,0,BUFFER_SIZE);  // clear out the network message buffer
  memset((char *) &serv_addr, 0, sizeof(serv_addr)); // clear serv_addr

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) error("ERROR opening socket");

  serv_addr.sin_family = AF_INET;         // parameters to bind to port
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);
  if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    error("ERROR on binding");  

  printf("Server listening on port %d.\n", portno);
  listen(sockfd,1);          // no need to wait for more than 1 connection!
  clilen = sizeof(cli_addr); // needed for the call to accept

  /*
   * this loop allows it to connect to clients repeatedly via the call to accept
   */
  while (!timeToQuitNow) // in case the main thread shuts the server down
  {

    /*
     * this next call (to accept) blocks
     */
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
    printf("Server accepted a connection... .\n");

    if (newsockfd < 0) error("ERROR on accept");

    /*
     * conversation with this client...
     */
    while (!timeToQuitNow) // in case the main thread shuts the server down
    {
      /*
       * read in the message
       */
      n = read(newsockfd,buffer,BUFFER_SIZE-1); // trailing zero
      if (n < 0) 
      {
        printf("Error reading from socket, n = %d\n", n);
        break;
      }
	  buffer[n]=0;
      printf("I read the message: %s\n",buffer);
	  
	  if (strncmp(buffer,"v",1) == 0)   // we can shut everything down from here
      {
        xclick=200;
		yclick=200;
		ourmode=3;
	  }

	  else if(strncmp(buffer, "getdata", 7)==0) 
	  {
		snprintf(outputBuffer,BUFFER_SIZE-1,"Color %d %d %d %d %d %d ",colors[current_color].rmi, colors[current_color].rma, 
		colors[current_color].gmi, colors[current_color].gma,	colors[current_color].bmi, colors[current_color].bma);
		n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	   
	  else if(strncmp(buffer, "sendingdata", 11)==0)
	  {
	  
	  char s[30];
	  sscanf(buffer, "%s %d %d %d %d %d %d", s, &colors[current_color].rmi, &colors[current_color].rma, 
			&colors[current_color].gmi, &colors[current_color].gma,	&colors[current_color].bmi, &colors[current_color].bma);
	  color_nums[current_color]=1;
	  printf("%s %d %d %d %d %d %d\n", s, colors[current_color].rmi, colors[current_color].rma, colors[current_color].gmi, 
			colors[current_color].gma,	colors[current_color].bmi, colors[current_color].bma);
	  
	  snprintf(outputBuffer,BUFFER_SIZE-1,"Received Data");
	  n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	  
	  else if(strncmp(buffer, "getdotdata", 10)==0) 
	  {
		snprintf(outputBuffer,BUFFER_SIZE-1,"Color %d %d %d %d %d %d ",colors[10].rmi, colors[10].rma, 
		colors[10].gmi, colors[10].gma,	colors[10].bmi, colors[10].bma );
		n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	  
	  else if(strncmp(buffer, "sendingdotdata", 14)==0)
	  {
	  
	  char s[30];
	  sscanf(buffer, "%s %d %d %d %d %d %d", s, &colors[10].rmi, &colors[10].rma, 
			&colors[10].gmi, &colors[10].gma,	&colors[10].bmi, &colors[10].bma);
	  color_nums[10]=1;
	  printf("%s %d %d %d %d %d %d\n", s, colors[current_color].rmi, colors[current_color].rma, colors[current_color].gmi, 
			colors[current_color].gma,	colors[current_color].bmi, colors[current_color].bma);
	  
	  snprintf(outputBuffer,BUFFER_SIZE-1,"Received Data");
	  n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	  
	  else if(strncmp(buffer, "getpos", 6)==0)
	  {
	  CvConnectedComp comp= getDot();
	  if(found_dot==0)
		snprintf(outputBuffer,BUFFER_SIZE-1, "%d %d %d", 0, -1, -1);
	  else
	    snprintf(outputBuffer,BUFFER_SIZE-1, "%d %d %d", 1, (comp.rect.x+comp.rect.width)/2, (comp.rect.y+comp.rect.height)/2);
	  n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	  
	  
	  else if (strncmp(buffer,"quit",4) == 0)   // we can shut everything down from here
      {
        timeToQuitNow = 1;    // tell the other thread to quit, too!
        printf("Received a shutdown message from the client.\n");
		snprintf(outputBuffer,BUFFER_SIZE-1,"echo -> %s",buffer);
		n = write(newsockfd, outputBuffer, strlen(outputBuffer));
      }
	   
	  else
	  {
	  
	   snprintf(outputBuffer,BUFFER_SIZE-1,"echo -> %s",buffer);
		n = write(newsockfd, outputBuffer, strlen(outputBuffer));
	  }
	      
	   
	   if (n < 0) 
      {
        printf("Error writing to socket, n = %d\n", n);
        break;
      }
	  
	  

	   	   
	   
     
	  
	
	  

      // clear out old data from the buffer... 
      memset(buffer, 0, n);  // there were n bytes written last time...
    }
    printf("Lost that connection.\n");
    if (timeToQuitNow) break;  // is it time to quit?
  }

  printf("Server thread quitting.\n");
  pthread_exit(NULL);   // allows other threads to continue running...
}






void bfs(int xpos, int ypos, struct color col)
{
CvPoint cvp = cvPoint(xpos,ypos);
CvMemStorage* storage=cvCreateMemStorage(0);
CvSeq* queue= cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), storage);
cvSeqPush(queue, &cvp);			  
((uchar*)(image->imageData + image->widthStep*ypos))[xpos*3+1] = 0;
((uchar*)(image->imageData + image->widthStep*ypos))[xpos*3+2] = 255;
((uchar*)(image->imageData + image->widthStep*ypos))[xpos*3] = 255;

while(queue->total>0)
{
CvPoint pt;
cvSeqPopFront(queue,&pt);
int neigh_width=9,i,j,r,g,b,h,s,v;
int mincol= ((pt.x-(neigh_width/2))>=0)?(pt.x-(neigh_width/2)):0;
int maxcol= ((pt.x+(neigh_width/2))<=image->width)?(pt.x+(neigh_width/2)):image->width;
int minrow= ((pt.y-(neigh_width/2))>=0)?(pt.y-(neigh_width/2)):0;
int maxrow= ((pt.y+(neigh_width/2))<=image->height)?(pt.y+(neigh_width/2)):image->height;

for ( i=mincol ; i<=maxcol ; ++i)
{
	for ( j=minrow ; j<=maxrow ; ++j) 
	{
		b = ((uchar*)(image->imageData + image->widthStep*j))[i*3];
		g = ((uchar*)(image->imageData + image->widthStep*j))[i*3+1];
		r = ((uchar*)(image->imageData + image->widthStep*j))[i*3+2];
		h = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3];
		s = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3+1];
		v = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3+2];
		
		if(r>=col.rmi && r<=col.rma && g>=col.gmi && g<=col.gma && b>=col.bmi && b<=col.bma && h>=col.hmi && h<=col.hma && s>=col.smi && s<=col.sma && v>=col.vmi && v<=col.vma )
		{
			if (!(r==255 && g==0 && b==255))
			{ 		
			((uchar*)(image->imageData + image->widthStep*j))[i*3] = 255;
			((uchar*)(image->imageData + image->widthStep*j))[i*3+1] = 0;
			((uchar*)(image->imageData + image->widthStep*j))[i*3+2] = 255;
			thecc.npixels+=1;
			thecc.xavg += i;
			thecc.yavg += j;
			cvp.x= i;
			cvp.y=j;
			cvSeqPush(queue, &cvp);
			
			}
		}
	}
}
		 
}
thecc.xavg/=thecc.npixels;
thecc.yavg/=thecc.npixels;

}

  
  int testPixel(int x,int y, int color_num )
  //tests pixel at x,y to see if it is in range of the color defined by color_num. If yes, returns 1. Else 0.
  {
	int r,g,b,h,s,v;
	b = ((uchar*)(image->imageData + image->widthStep*y))[x*3];
	g = ((uchar*)(image->imageData + image->widthStep*y))[x*3+1];
	r = ((uchar*)(image->imageData + image->widthStep*y))[x*3+2];
	//h = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3];
	//s = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3+1];
	//v = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3+2];
	if(r>=colors[color_num].rmi && r<=colors[color_num].rma &&
	   g>=colors[color_num].gmi && g<=colors[color_num].gma && 
	   b>=colors[color_num].bmi && b<=colors[color_num].bma)// && 
	   //h>=colors[color_num].hmi && h<=colors[color_num].hma && 
	   //s>=colors[color_num].smi && s<=colors[color_num].sma && 
	   //v>=colors[color_num].vmi && v<=colors[color_num].vma )
	   return 1;
	else
	   return 0;
	}
	
	
  int testPixel_Object(int x, int y, int obj_num)
  {
  int i;
  for(i=0;i<10;i++)
  {
  if (objects[obj_num].col[i]>=0)
	if(testPixel(x,y,i))
		return 1;
  }
  return 0;
  }
	
							
CvSeq* allCCs()
{

	int x, y,i;
	CvMemStorage* storage=cvCreateMemStorage(0);
	CvSeq* listOfCCs= cvCreateSeq(0, sizeof(CvSeq), sizeof(CvConnectedComp), storage); 
	CvScalar new_val= cvScalar(255,0,255,0);
	CvScalar low_diff= cvScalar(25,25,25,0);
	CvScalar up_diff= cvScalar(25,25,25,0);
	CvConnectedComp comp;
	CvPoint seedpoint =cvPoint(-1,-1);
	
	for( i=0; i<10; ++i)
	{
	 clearMask();
	 new_val=fill_colors[i];
	 if(object_nums[i]>=0)	
		for ( x=0 ; x<image->width ; ++x)
			for ( y=0 ; y<image->height ; ++y) 					
			   if( testPixel_Object(x,y,i))
					if(((uchar*)(mask->imageData + mask->widthStep*y))[x*1] == 0)
					{
						seedpoint.x=x;
						seedpoint.y=y;
						cvFloodFill( image, seedpoint, new_val,low_diff, up_diff, &comp, 8|CV_FLOODFILL_FIXED_RANGE, mask );
						if(comp.area>200)
						{
							cvSeqPush(listOfCCs, &comp);
							//printCC(comp);
						 }
					}
	}
	
	return listOfCCs;
	
  }					
			  	
				  

CvConnectedComp getDot()
{
int x, y,i;
found_dot=0;
	CvScalar new_val= cvScalar(255,0,255,0);
	CvScalar low_diff= cvScalar(25,25,25,0);
	CvScalar up_diff= cvScalar(25,25,25,0);
	CvConnectedComp comp;
	CvPoint seedpoint =cvPoint(-1,-1);
    clearMask();
	for ( x=0 ; x<image->width ; ++x)
		for ( y=0 ; y<image->height ; ++y) 					
			if( testPixel(x,y,10))
					if(((uchar*)(mask->imageData + mask->widthStep*y))[x*1] == 0)
					{
						seedpoint.x=x;
						seedpoint.y=y;
						cvFloodFill( image, seedpoint, new_val,low_diff, up_diff, &comp, 8|CV_FLOODFILL_FIXED_RANGE, mask );
						if(comp.area<100 && comp.area>10)
						{
						 printf("Dot is at %d %d\n", (comp.rect.x+comp.rect.width)/2, (comp.rect.y+comp.rect.height)/2);
						 found_dot=1;
						 return comp;
						 }
					}
	return comp;
	
  }					

			  
			  
			  
			  
			  

void on_mouse( int event, int x, int y, int flags, void* param )
{
    int i,j,h,s,v,r,g,b;
	
	if( !image )
        return;

    if( image->origin )
        y = image->height - y;
	
	//printf("In on_mouse");

    switch( event )
    {
	case CV_EVENT_MOUSEMOVE:
	    if (drawingRectangle) 
		{
		    printf("You are dragging a rectangle!\n");
			selection.x = MIN(x,origin.x);
			selection.y = MIN(y,origin.y);
			selection.width = selection.x + CV_IABS(x - origin.x);
			selection.height = selection.y + CV_IABS(y - origin.y);
			
			
			selection.x = MAX( selection.x, 0 );
			selection.y = MAX( selection.y, 0 );
			selection.width = MIN( selection.width, image->width );
			selection.height = MIN( selection.height, image->height );
			selection.width -= selection.x;
			selection.height -= selection.y;
			
		}
	    
	    break;
		
    case CV_EVENT_LBUTTONDOWN:
	    if (drawingRectangle == 0)
		{
			origin = cvPoint(x,y);
		    selection = cvRect(x,y,1,1);
		    drawingRectangle = 1;
		}
		else if (drawingRectangle == 1)
		{
		    hmin=smin=vmin=rmin=gmin=bmin=255;
			hmax=smax=vmax=rmax=gmax=bmax=0;	
			for ( i=selection.x ; i<=selection.x+selection.width ; ++i)
				for ( j=selection.y ; j<=selection.y+selection.height ; ++j) 
						{
						b = ((uchar*)(frame->imageData + frame->widthStep*j))[i*3];
						g = ((uchar*)(frame->imageData + frame->widthStep*j))[i*3+1];
						r = ((uchar*)(frame->imageData + frame->widthStep*j))[i*3+2];
						h = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3];
						s = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3+1];
						v = ((uchar*)(hsv->imageData + hsv->widthStep*j))[i*3+2];
						
						if(i==selection.x && j==selection.y)
							{
							printf("r is %d\n", r);
							printf("g is %d\n", g);
							printf("b is %d\n\n", b);
							
							}
							
						
						hmin=MIN(hmin, h);
						smin=MIN(smin, s);
						vmin=MIN(vmin, v);
						rmin=MIN(rmin, r);
						gmin=MIN(gmin, g);
						bmin=MIN(bmin, b);						
						hmax=MAX(hmax, h);
						smax=MAX(smax, s);
						vmax=MAX(vmax, v);
						rmax=MAX(rmax, r);
						gmax=MAX(gmax, g);
						bmax=MAX(bmax, b);
						}
			
			
			printf("rmin is %d\n", rmin);
			printf("rmax is %d\n", rmax);
			printf("gmin is %d\n", gmin);
			printf("gmax is %d\n", gmax);
			printf("bmin is %d\n", bmin);
			printf("bmax is %d\n\n", bmax);
			
			
			printf("hmin is %d\n", hmin);
			printf("hmax is %d\n", hmax);
			printf("smin is %d\n", smin);
			printf("smax is %d\n", smax);
			printf("vmin is %d\n", vmin);
			printf("vmax is %d\n", vmax);
			
			struct color col= {hmin, hmax, smin, smax, vmin, vmax, rmin, rmax, gmin, gmax, bmin, bmax};
			colors[current_color]=col;
			color_nums[current_color]=1;	
			drawingRectangle = 0;
		}
		        
        break;
		
    case CV_EVENT_LBUTTONUP:       
        break;
    }
}


CvScalar hsv2rgb( float hue )
{
    int rgb[3], p, sector;
    static const int sector_data[][3]=
        {{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
    hue *= 0.033333333333333333333333333333333f;
    sector = cvFloor(hue);
    p = cvRound(255*(hue - sector));
    p ^= sector & 1 ? 255 : 0;

    rgb[sector_data[sector][0]] = 255;
    rgb[sector_data[sector][1]] = 0;
    rgb[sector_data[sector][2]] = p;

    return cvScalar(rgb[2], rgb[1], rgb[0],0);
}

void printSeq( CvSeq* seq)
{
int i;
printf( "num comps: %d\n",seq->total);
/*
for( i = 0; i < seq->total; i++ )
{
    CvPoint* pt = (CvPoint*)cvGetSeqElem( seq, i );
    printf( "%d: (%d,%d)\n",i,pt->x, pt->y );
}
*/
}

void clearMask()
{
  int r,c;
  for (r=0 ; r<mask->height ; ++r)
	for (c=0 ; c<mask->width ; ++c)
		((uchar*)(mask->imageData + mask->widthStep*r))[c*1] = 0;
}

void clearColsObjs()
{
	int i;
	for(i=0;i<11;i++)
		color_nums[i]=-1;
	for(i=0;i<10;i++)
		object_nums[i]=-1;
		
}

int main( int argc, char** argv )
{
	int i,j;
	fill_colors[0]= cvScalar(255,0,255,0);
	fill_colors[1]=cvScalar(0, 255,255,0);
	fill_colors[2]=cvScalar(255,255,0,0);
	fill_colors[3]= cvScalar(255,0,0,0);
	fill_colors[4]= cvScalar(0,255,0,0);
	fill_colors[5]=cvScalar(0,0,255,0);
	
	for(i=0;i<6;++i)
		for(j=0;j<10;++j)
			objects[i].col[j]=-1;
	
	
	objects[0].col[0]=1;
	objects[1].col[1]=1;
	objects[2].col[2]=1;
	
	objects[3].col[0]=1;
	objects[3].col[1]=1;
	
	objects[4].col[0]=1;
	objects[4].col[2]=1;
	
	objects[5].col[1]=1;
	objects[5].col[2]=1;
	
	objects[6].col[0]=1;
	objects[6].col[1]=1;
	objects[6].col[2]=1;
	//objects[7]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
	
						    
	  
	  
	  pthread_t serverThread;   // the identifier for the thread
	  int portno;               // the server's port number
	  int rc;                   // return value on thread creation
	  
	CvCapture* capture = 0;
	  
	  
  int donetwork=1;
  if (donetwork)
  {
		portno = DEFAULT_PORT;  // if not specified, this is the port number
		  printf("Creating serverThread.\n");
  rc = pthread_create(&serverThread, NULL, runServerThread, (void *)portno);
  if (rc) error("ERROR in pthread_create.\n");
  }
    
    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
	{
		printf( "argc is : %d\n", argc );
		printf( "argv is : %s\n", argv[1]);
        capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
    }
	else if( argc == 2 )
    {    capture = cvCaptureFromAVI( argv[1] ); 
	}
    if( !capture )
    {
        fprintf(stderr,"Could not initialize capturing...\n");
        return -1;
    }

    cvNamedWindow( "CamShiftDemo", 1 );
	cvSetMouseCallback( "CamShiftDemo", on_mouse, 0 );


    while (!timeToQuitNow)
    {
        frame = 0;
        int i, c;
		

        frame = cvQueryFrame( capture );
        if( !frame )
            break;

        if( !image )
        {
		    
			CvSize cvs = cvGetSize(frame);
            /* allocate all the buffers */
            image = cvCreateImage( cvGetSize(frame), 8, 3 );
            image->origin = frame->origin;
            hsv = cvCreateImage( cvGetSize(frame), 8, 3 );
			mask = cvCreateImage( cvSize(cvs.width+2,cvs.height+2), 8, 1 );
        
        }

        cvCopy( frame, image, 0 );
        cvCvtColor( image, hsv, CV_BGR2HSV );

          
			if (ourmode)
			{
			  int x, y,b,r,g, h,s,v,i;
			  
			
			  if (ourmode==2)
			  {
			  CvPoint seed_point=cvPoint(xclick, yclick);
			  CvScalar new_val= cvScalar(255,0,255,0);
			  CvScalar low_diff= cvScalar(25,25,25,0);
			  CvScalar up_diff= cvScalar(25,25,25,0);
			  CvConnectedComp comp;
			  clearMask();
			  
			  
			  cvFloodFill( image, seed_point, new_val,low_diff, up_diff, &comp, 8|CV_FLOODFILL_FIXED_RANGE, mask );
			  cvRectangle(image, cvPoint(comp.rect.x, comp.rect.y), cvPoint(comp.rect.x+comp.rect.width, comp.rect.y+comp.rect.height), 
			  cvScalar(0,255,255,0),1,8,0);
			 	  
			  }
			  
			  else if (ourmode==3)
			  {
			  thecc.npixels=1;
			  thecc.xavg=0;
			  thecc.yavg=0;
			  struct color col= {hmin, hmax, smin, smax, vmin, vmax, rmin, rmax, gmin, gmax, bmin, bmax};
			  bfs(xclick, yclick,col);
			  print_CC(thecc);	
																																 			    	     
			  }
			  
			  else if(ourmode==4)
			  {
			   			
			  printSeq(allCCs());
			  }
			  
			  else if(ourmode==5)
			  {
			  CvConnectedComp comp= getDot();
			  
			  }

			  
			   
			  else
			  {  
			 		  
			    for ( x=0 ; x<image->width ; ++x)
			    for ( y=0 ; y<image->height ; ++y) 
				{
					b = ((uchar*)(image->imageData + image->widthStep*y))[x*3];
					g = ((uchar*)(image->imageData + image->widthStep*y))[x*3+1];
					r = ((uchar*)(image->imageData + image->widthStep*y))[x*3+2];
					h = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3];
					s = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3+1];
					v = ((uchar*)(hsv->imageData + hsv->widthStep*y))[x*3+2];

					
					if(r>=rmin && r<=rmax && g>=gmin && g<=gmax && b>=bmin && b<=bmax && h>=hmin && h<=hmax && s>=smin && s<=smax && v>=vmin && v<=vmax )
					{
					
					((uchar*)(image->imageData + image->widthStep*y))[x*3] = 255;
					((uchar*)(image->imageData + image->widthStep*y))[x*3+1] = 0;
					((uchar*)(image->imageData + image->widthStep*y))[x*3+2] = 255;
					}
				}
			 }
			}
            
        
        
      

        /*
		 * DRAW THE IMAGE!!
		 */
		if (drawingRectangle == 1)
		{
		  cvRectangle(image, cvPoint(selection.x,selection.y), cvPoint(selection.x+selection.width, selection.y+selection.height)
		  ,cvScalar(0,255,255,0),1,8,0);
		}
        cvShowImage( "CamShiftDemo", image );
        //cvShowImage( "Histogram", histimg );

        c = cvWaitKey(10);
        if( (char) c == 27 )
            break;
        switch( (char) c )
        {
		char h1[100], s1[100], v1[100], r1[100], g1[100], b1[100];
				
		case '0':
			current_color=0;
			break;
		case '1':
			current_color=1;
			break;
		case '2':
			current_color=2;
			break;
		case '3':
			current_color=3;
			break;
		case '4':
			current_color=4;
			break;
		case '5':
			current_color=5;
			break;
		case '6':
			current_color=6;
			break;
		case '7':
			current_color=7;
			break;
		case '8':
			current_color=8;
			break;
		case '9':
			current_color=9;
			break;
		case 'r':
			current_color=10;
			break;
		
			
		case ')':
			object_nums[0]=1;
			break;
		case '!':
			object_nums[1]=1;
			break;
		case '@':
			object_nums[2]=1;
			break;
		case '#':
			object_nums[3]=1;
			break;	
		case '$':
			object_nums[4]=1;
			break;
		case '%':
			object_nums[5]=1;
			break;
		case '^':
			object_nums[6]=1;
			break;
		case '&':
			object_nums[7]=1;
			break;
		case '*':
			object_nums[8]=1;
			break;
		case '(':
			object_nums[9]=1;
			break;
			
			
		case 'c':
		    clearColsObjs();
			break;
		
		case 'o':
			ourmode ^=4;
			break;	
			
		case 'm':
		{
		char mystr[30]="Vedika 25   36 78";
		char substr[30];
		int num1, num2, num3;
		sscanf(mystr, "%s %d%d%d", substr, &num1, &num2, &num3);
		printf("%s %d %d %d\n", substr, num1, num2, num3);
		}
		break;
		
			
		case 'd':
		ourmode ^=5;		
		break;
		
		
	
		case 'f':
			fp= fopen("./testfile.txt", "w");
			fprintf(fp, "%s %d %d\n", "h: ", hmin, hmax);
			fprintf(fp, "%s %d %d\n", "s: ", smin, smax);
			fprintf(fp, "%s %d %d\n", "v: ", vmin, vmax);
			fprintf(fp, "%s %d %d\n", "r: ", rmin, rmax);
			fprintf(fp, "%s %d %d\n", "g: ", gmin, gmax);
			fprintf(fp, "%s %d %d\n", "b: ", bmin, bmax);

			fclose(fp);
			break;
		case 'g':
			fp=fopen("./testfile.txt", "r");
			fscanf(fp, "%s %d %d\n", h1, &hmin, &hmax);
			fscanf(fp, "%s %d %d\n", s1, &smin, &smax);
			fscanf(fp, "%s %d %d\n", v1, &vmin, &vmax);
			fscanf(fp, "%s %d %d\n", r1, &rmin, &rmax);
			fscanf(fp, "%s %d %d\n", g1, &gmin, &gmax);
			fscanf(fp, "%s %d %d\n", b1, &bmin, &bmax);

			printf("%s %d %d\n", h1, hmin, hmax);
			printf("%s %d %d\n", s1, smin, smax);
			printf("%s %d %d\n", v1, vmin, vmax);
			printf("%s %d %d\n", r1, rmin, rmax);
			printf("%s %d %d\n", g1, gmin, gmax);
			printf("%s %d %d\n", b1, bmin, bmax);
			ourmode=1;
			
			fclose(fp);
			break;
		case 'v':
            ourmode ^= 1;
            break;

        default:
            ;
        }
    }
	
	
  timeToQuitNow = 1;    // signal for all other threads (serverThread) to quit
  
  printf("Main thread quitting...\n");
  sleep(1);             // give it a moment...

    cvReleaseCapture( &capture );
    cvDestroyWindow("CamShiftDemo");

    return 0;
}


