#ifndef _CardRecognition_h_
#define _CardRecognition_h_

#include "DualCoding/DualCoding.h"
#include "Events/EventBase.h"
#include "Sound/SoundManager.h"
#include "Motion/MotionManager.h"
#include "Motion/MotionSequenceMC.h"
#include "Motion/HeadPointerMC.h"
#include "Motion/TailWagMC.h"

using namespace DualCoding;


class CardRecognition : public VisualRoutinesStateNode{
public:
	int cardValue;
  CardRecognition(): VisualRoutinesStateNode("CardRecognition"),cardValue(0), head_id(MotionManager::invalid_MC_ID), tail_id(MotionManager::invalid_MC_ID){}


  void DoStart(){
    VisualRoutinesStateNode::DoStart();
    erouter->addTimer(this, 999, 500, false);

    

  }
  
  void DoStop(){
    cout << "Card Recognition Stopped\n";
    motman->removeMotion(head_id);
    VisualRoutinesStateNode::DoStop();
  }

  void processEvent(const EventBase & event)
  {
    if(event.getSourceID() == 999){
		 NEW_SKETCH(rawY, uchar, sketchFromRawY());
		 int threshold = 150; 
		 NEW_SKETCH(thresh, bool, rawY < threshold);
		 NEW_SKETCH(colorFrame, uchar, sketchFromSeg());
		 NEW_SKETCH(orange_stuff, bool, visops::colormask(colorFrame,"orange"));
		 NEW_SKETCH(pink_stuff, bool, visops::colormask(colorFrame,"pink"));
		 NEW_SKETCH(yellow_stuff, bool, visops::colormask(colorFrame,"yellow"));
		 NEW_SHAPEVEC(red_blobs, BlobData, BlobData::extractBlobs(pink_stuff, 50));
		 NEW_SHAPEVEC(noise1, BlobData, BlobData::extractBlobs(yellow_stuff,5));
		 NEW_SHAPEVEC(noise2, BlobData, BlobData::extractBlobs(orange_stuff,5));
		 
		 cout << "Orange blobs =  " << noise1.size() + noise2.size() << "\n";
		 if(noise1.size() + noise2.size() > 10){
			 cout << "Face card\n";
			 cardValue = 10;
			 sayNumber(cardValue);
			 return;
		 }

	
	vector<Shape<BlobData> > blobs;
	if(red_blobs.size() < 1)
	  {
	    cout << "Card is black\n";
	    NEW_SHAPEVEC(black_blobs, BlobData, BlobData::extractBlobs(thresh,70))
	      blobs = black_blobs;
	  }
	else
	  blobs=red_blobs;
	
	
    
	
	
	coordinate_t x(0);
	coordinate_t y(0);    
	int count = 0;
	
	SHAPEVEC_ITERATE(blobs, BlobData, b)
	  {
	    if(b->getArea() < 500)
	      {
		x += (b->getCentroid()).coordX();
		y += (b->getCentroid()).coordY();
		count++;
	      }
	    
	  }
	END_ITERATE;
	
	
	if(count == 0)
	  {
	    cout << "NO CARD is found\n";
	    postCompletionEvent();
	    return;
	  }
	
	Point centre(x/count, y/count);
	cout << "Centre is " << centre.coordX() << ", " << centre.coordY() << "\n";
   
	
	count = 0;
	SHAPEVEC_ITERATE(blobs, BlobData, b)
	  {
	    if(b->getArea() < 500 && centre.xyDistanceFrom(b->getCentroid()) < 80)
	      {
		cout << b->getArea() << " and " << centre.xyDistanceFrom(b->getCentroid()) << " GOOD\n";
		count++;
	      }
	    
	    else
	      {
		cout << b->getArea()<< " and "  << centre.xyDistanceFrom(b->getCentroid()) <<" BAD\n";
	      }
	    
	  }
	END_ITERATE;
	cardValue = count;
	cout << "card is " << count << "\n";	
	sayNumber(count);
      }
    else if(event.getSourceID() == 9999)
      {
	motman->removeMotion(tail_id);
	tail_id = MotionManager::invalid_MC_ID;
	postCompletionEvent();
      }
  }

  virtual void sayNumber(int number)
  {
    
    SharedObject<TailWagMC> tail_mc;
    tail_id = motman->addPersistentMotion(tail_mc);
    tail_mc->setPeriod(1000);
    tail_mc->setMagnitude(3.1415926536/2);
    tail_mc->setActive(true);
    erouter->addTimer(this, 9999, number*500, false);
    
  }


private:

  MotionManager::MC_ID head_id;
  MotionManager::MC_ID tail_id;
  CardRecognition(const CardRecognition&); // satisfy compiler
  CardRecognition& operator=(const CardRecognition&); 

};
#endif


