// image processing
#ifndef __PROCESS
#define __PROCESS

#include <wx/wx.h>
#include <wx/panel.h>
#include <wx/config.h>   // wxconfig
#include <cv.h>          // opencv
#include <highgui.h>     // opencv
#include <BlobResult.h>  // blobs
#include <Blob.h>        // blobs
#include <math.h>        // sqrt

#define FIRE_RADIUS 2
#define ID_PROCESS         100
#define SLD_WHITE_LEVEL    ID_PROCESS+0 
#define SLD_MIN_SIZE       ID_PROCESS+1
#define SLD_MAX_SIZE       ID_PROCESS+2
//#define CMD_PROCESS        ID_PROCESS+3
#define TXT_FIRE_X         ID_PROCESS+4
#define TXT_FIRE_Y         ID_PROCESS+5
#define CMD_FIRE_X_ADD     ID_PROCESS+6
#define CMD_FIRE_X_SUB     ID_PROCESS+7
#define CMD_FIRE_Y_ADD     ID_PROCESS+8
#define CMD_FIRE_Y_SUB     ID_PROCESS+9
#define CMD_TIMER_ONCE     ID_PROCESS+10
#define LBL_MOVING         ID_PROCESS+11

struct st_target {
	int center_x;
	int center_y;
	int min_x;
	int min_y;
	int max_x;
	int max_y;
};

class clsProcess:public wxPanel {
	public:
		clsProcess(wxPanel*);
		wxPanel*  m_panel;
		void Done(); // clean up functions, run at end of every frame
//		void cmdProcess(wxCommandEvent&);
		void Process(IplImage*);    // process one frame
		void ProcessImage();
		void FireIfTarget();        // fire if there's targets in the center
		void FindNearest();         // move to the nearest target
		int  GetFireX();            // gets the x value where we're shooting
		int  GetFireY();
		int  GetNearestX();         // x,y and distance to the nearest target
		int  GetNearestY();
		bool IsMoving();            // camera has stopped moving
		void FindFirePixelLimits(); // find the image movement limits

		// automatic control
		bool        IsAuto();       // are we in automatic mode?
		wxCheckBox* chk_auto_on;    // enable automatic control
		bool        timer_once;     // fire the timer one time
		wxButton*   btn_timer_once; // trigger the timer once 
		void cmdTimerOnce(wxCommandEvent&);  // trigger the timer once

		void MoveServos(); // moves the servos if appropriate
	private:
		wxConfigBase* config;
		IplImage*     img_main;     // main image to process on
		wxButton*     btn_process;
		wxStaticText* lbl_moving;   // text to display "moving" when moving

		wxSlider*   sld_white_level; // slider for white_level
		wxSlider*   sld_min_size;    // slider for min_size
		wxSlider*   sld_max_size;    // slider for max_size
		void        sldWhiteLevel(wxScrollEvent&); // slider for the white_level
		void        sldMinSize(wxScrollEvent&);    // slider for the min_size
		void        sldMaxSize(wxScrollEvent&);    // slider for the max_size

		CBlobResult blobs;     // raw list, has many non-targets
		std::vector<st_target> vec_targets;
		std::vector<st_target> vec_last_targets;
		double nearest_dist;   // nearest target
		int nearest_x;
		int nearest_y;
		bool is_moving;         // is the image moving?
		int force_moving_count; // number of timer()s to force is_moving to true
		int no_targets_count;   // number of timer()s there's been zero targets
		// set the firing position
		wxTextCtrl* txt_fire_x;       // x position where the gun is *actually* firing
		wxTextCtrl* txt_fire_y;       // 
		void txtFireX(wxCommandEvent&);  // text changes
		void txtFireY(wxCommandEvent&);  // text changes
		wxButton*   btn_fire_x_add; void cmdFireXAdd(wxCommandEvent&); // fire_x++
		wxButton*   btn_fire_x_sub; void cmdFireXSub(wxCommandEvent&); // fire_x--
		wxButton*   btn_fire_y_add; void cmdFireYAdd(wxCommandEvent&); // fire_y++
		wxButton*   btn_fire_y_sub; void cmdFireYSub(wxCommandEvent&); // fire_y--
		void        DrawImageGUI();
		int         min_fire_x; // pixel position of the firable area	
		int         max_fire_x; // pixel position of the firable area	
		int         min_fire_y; // pixel position of the firable area	
		int         max_fire_y; // pixel position of the firable area	
};

#endif
