/********************************************************************/
/** @file Previewer.h 
 * Description: Prototypes for Camera image canvas.		    *
 ********************************************************************/
#ifndef _PREVIEWER_H
#define _PREVIEWER_H

#include <vector>

#include <wx/panel.h>
#include <wx/image.h>

#include "../library/Shape.h"
#include "../library/images/raster.h"
#include "../library/CameraTools.h"


/** Decides what it is on, ie, either graph illustration
 *  or raw picture or thresholded picture.    */
    enum VISION_STATES {   
         GRAPH = 0,      ///< Indicates graph with target and video circle
         RAW_PIC,        ///< Indicates raw picture from webcam
         THRESHOLDED_PIC,///< Indicates thresholded picture (which is used for detecting the ball position)
	 RAW_COLOR,
	 EXTERN_COLOR
    };


/** The CameraPreview class which draws a contents of a camera.
*  This class takes the data needed for plotting the ball's position and taking the new 
*  target position in the model. 
*  The graph is resized when the window is resized, maximized when the window is maximized and 
*  restored. */
class CameraPreview: public wxPanel //wxScrolledWindow
{
public:        
    CameraPreview(wxWindow *parent, CameraTool *NewCT);
    ~CameraPreview();
    
    void OnPaint(wxPaintEvent& event);           ///< Paints the graphs.
    void SetBackground(const wxColour &color);   ///< Sets background appearance.
        
    void SetTCircleColor(const wxColour &color); ///< Sets the target circle appearance.    
    void SetVCircleColor(const wxColour &color); ///< Sets the video circle appearance.
    
    void SetGridLine(const wxPen &pen);          ///< Sets grid line appearence.
    void OnEraseBackground(wxEraseEvent& event); ///< When the size is changed, it is called and then it refreshs the screen and sets the layouts
    void Reset();	///< Resets the position of the target circle and values.
    
        
    void OnPreviewImageTimer(wxTimerEvent& event);  ///< Periodical timer for controll    
    void OnCameraChange(wxCommandEvent & event);///< Camera change notification event.

    bool CaptureImage(bool DeleteIMSample);	         ///< Captures image
    void SetImage(const wxImage& image); ///< Sets the image for preview
    void SetImage(Raster2DAbstract * pRas); ///< Sets the image for preview
    //void AssignImage(Raster2DAbstract *newImage);

    unsigned char *GetImageData()	{return (ImageBuf==NULL)?NULL:(unsigned char *)(ImageBuf->GetRow(0));}
    Raster2DAbstract *GetImageBuf()	{return ImageBuf;}

    /** Sets which image will be shown either preview or thresholded    
    *  @param[in] NewStatus The status of preview */
    void SetPreviewStatus(const VISION_STATES NewStatus) {ViewMode=NewStatus;};
    VISION_STATES GetPreviewStatus(void) {return(ViewMode);};

    Transform2D Tx;		     ///< Transformation between physical and real coordinates.
    CircRTShape *videoCircle;	     ///< The pointer holds video circle.
    CircRTShape *targetCircle;	     ///< The pointer holds target circle
    VGrid GrX;			     ///< Vertical grid.
    HGrid GrY;			     ///< Horizontal grid.

    CameraTool *CT;
    void HookFrame(wxFrame *pFrame2Hook);
    int getFrameCounter(void);

protected:        
    void OnMouseMove(wxMouseEvent& event); ///< Handles the mouse events and draws the desired target position.
    DECLARE_EVENT_TABLE()

private:
    bool ImageChanged;
    wxBitmap *bit;			///< Holds preview image
    Raster2DAbstract *ImageBuf;		///< buffer for image data.
    Raster2DAbstract *FilterBuf;	///< buffer for filtered image data.

public:
    VISION_STATES ViewMode;           ///< Denotes how to display a plate.
    int filter;
    int vflip;
    int hflip;
    int rectangle;

    void FlushFilter()	{FilterBuf->Erase();}
        
    void DrawGraphLines(wxDC & dc);   ///< Auxiliary function to draw the model plate rectangle.
    
    
    /** The window identifiers and GUI Parameters */
    enum 
    {
        SHIFT_PLATE_POS = 1,   ///< Border length
        GRID_LINE_NUMBER = 10,  ///< Grid line number inside the panel
        ID_TIMER_PREVIEW = 300 ///< Identifier number for the timer
    };
        
    wxPoint topLeft;      ///< Stores the top left position for the plate        
    wxPoint bottomRight;  ///< Stores the bottom right position for the plate
    
    double DIVISOR_RATIO; ///< Radius divisor for the ball on the plate.

    void SetRange(double &x, double &y, double &radius);

    void ChangeRange(double &val, const double &upperRange, const double &lowerRange); ///< Changes the range.
        
    wxPoint   dragStartPos; ///< The beginning of the mouse dragging point
    
    /** Dragging modes */
    enum { 
        TEST_DRAG_NONE,     
        TEST_DRAG_START,    
        TEST_DRAG_DRAGGING 
        };    
    short   m_dragMode;	///< Holds the drag type such as start, dragging and so on.
        

    //////////////////////// Screen Properties ///////////////////
    
    const wxColour DEFAULT_BGROUND;           ///< Default background colour value
    
    /** The color of the background. The color of background is 
    *  used for painting the background of the panel's rectangle. */
    wxColor backgroundColor;    
    void SetBackGColorProp(wxDC &devContext); ///< Sets the background of the panel.
    const wxColour DEFAULT_TCIRCLE_COLOR;     ///< Default target circle colour value.        
    const wxColour DEFAULT_VCIRCLE_COLOR;     ///< Default target circle colour value        
    const wxPen DEFAULT_GRID_LINE;	      ///< Default grid lines value  
};


#endif