/////////////////////////////////////////////////////////////////////////////
// Name:        wxroicontrols.h
// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
// Modified by: 
// Created:     
// Copyright:   (C) 2008-11 Cesar Mauri Loba - CREA Software Systems
// 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////
#ifndef WXROICONTROLS_H
#define WXROICONTROLS_H

#include "mod_camera/roitype.h"
#include <wx/gdicmn.h>
#include <wx/thread.h>
#include <boost/function.hpp>
#include <vector>

typedef struct _IplImage IplImage;
class wxMouseEvent;

namespace mod_camera {

class WXRoiControls
{
public:
	// Functor typedef to install a callback when one ROI is updated
	typedef boost::function1<void, SmartPtr<const CTypeROI> > ROIModifiedNotification;

	WXRoiControls(ROIModifiedNotification rmn= NULL);
	virtual ~WXRoiControls();
	
	// Update a root ROI given its id.
	void UpdateRootROI (const CTypeROI& roi);

	// Clear all "registered" root ROIs
	void ClearRootROIs ();

	void Paint (IplImage& img, const wxWindow& win);
	bool MouseEvent (wxMouseEvent& event);

private:
	
	//
	// types to store where is the pointer after an event.
	//
	enum MouseHoverLoc {
		OVER_NONE= 0, OVER_LEFT_LINE, OVER_BOTTOM_LINE, 
		OVER_RIGHT_LINE, OVER_UPPER_LINE, 
		OVER_UL_CORNER, OVER_BR_CORNER, OVER_ARROW
	};
	struct MouseHoverInfo {
		MouseHoverLoc loc;		// Where is the cursor
		const CTypeROI* roi;	// ROI pointer (for comparison purposes only)
	};

	//
	// Attributes
	//
	struct MouseHoverInfo m_mouseHoverInfo;
	wxCriticalSection m_csROIAccess;
	wxPoint m_prevCursorLocation;
	std::vector <SmartPtr<CTypeROI> > m_rootROIs;
	ROIModifiedNotification m_roiModifiedNotification;

	SmartPtr<CTypeROI> m_temporaryROI;

	//
	// private operations
	//
	static void GetArrowSegment (const CTypeROI& roi, const wxSize& winSize, wxPoint& p1, wxPoint& p2);

	static void UpdateMouseHoverInfoRec (
		const CTypeROI& roi, const wxSize& winSize, 
		const wxPoint& location, MouseHoverInfo& info);

	static bool ModifyROIRec (
		CTypeROI& roi, const wxSize& winSize, const wxPoint& location, 
		const wxPoint& location_prev, const MouseHoverInfo& info);

	static void PaintRec (const CTypeROI& roi, IplImage& img, const wxSize& winSize, const MouseHoverInfo& info);
};

}

#endif