#ifndef __WItem__H
#define __WItem__H

#include "WimpLib:std.h"
#include <stdbool.h>
#include "WimpLib:Coords.h"

#ifdef __cplusplus
extern "C" {
#endif

// Item flags for redraw
#define EWItem_Hover      0x00000001 // Pointer is over item
#define EWItem_Active     0x00000002 // User is acting on item
#define EWItem_HasFocus   0x00000004 // Item has focus for keyboard
#define EWItem_Selected   0x00000008 // Item is selected
#define EWItem_Marked     0x00000010 // Item is marked (as in menus)
#define EWItem_ProtAction 0x00000020 // Item cannot be acted upon
#define EWItem_ProtFocus  0x00000040 // Item cannot receive the focus
#define EWItem_ProtSelect 0x00000080 // Item cannot be selected
#define EWItem_SetMask    0x000000FA // flags a normal user can set
// Internal helpers
#define EWItem_Redraw     0x40000000 // Mark item as to be redrawn
#define EWItem_Deleted    0x80000000 // Used for state of inexisting items

// Item plot parameters.
typedef struct WPlotItem
{
	CWindCvt        m_cvtinfo;
	int             m_index;
	CRect           m_box;
	unsigned int    m_flags;
	const int*      m_psizes;
	const int*      m_pmaxsizes;
} WPlotItem;

/**
 * Function used to plot the background pf a container on screen.
 *
 * @param  pOwner     A pointer to the container.
 * @param  pCvtInfo   A pointer to the window's plot parameters.
 * @param  pRect      A pointer to the window's rectangle to fill.
 */

typedef void (*FWOwner_PlotBackGround)(const void* pOwner, const CWindCvt* pCvtInfo, const CRect* pRect);

void WOwner_PlotBackGround_White(const void* pOwner, const CWindCvt* pCvtInfo, const CRect* pRect);

/**
 * Function used to plot the object on screen.
 *
 * @param  pObject    A pointer to the object.
 * @param  pOwner     A pointer to the object's container.
 * @param  pItem      A pointer to the plot parameters.
 */
typedef void (*FWItem_Plot)(const void* pObject, const void* pOwner, const WPlotItem* pItem);

/**
 * Function used to fill in an array with the dimensions of the object's components.
 * An example could by the width and height of an image and the width of its text caption.
 *
 * @param  pObject    A pointer to the object.
 * @param  pOwner     A pointer to the object's container.
 * @param  pSizes     A pointer to the object's dimensions to fill in.
 */
typedef void (*FWItem_GetSizes)(const void* pObject, const void* pOwner, int* pSizes);

/**
 * Function used to determine the size of an item given the object's dimensions
 * and the maximal values of each dimension from the whole collection of objects in the container.
 *
 * @param  pObject    A pointer to the object.
 * @param  pOwner     A pointer to the object's container.
 * @param  pSizes     A pointer to the object's dimensions.
 * @param  pMaxSizes  A pointer to each dimension maximal value.
 *
 * return the size of the object.
 */
typedef CSize (*FWItem_GetBox)(const void* pObject, const void* pOwner, const int* pSizes, const int* pMaxSizes);

// Item mouse reaction areas
// Outside area: part of the item considered outside the displayed object (see objects in filers).
#define EWItemArea_Outside  0x00000000
// Select area: part of the item which can used to selection and dragging.
#define EWItemArea_Select   0x00000001
// Inactive area: part of the item which doesn't respond to the mouse.
#define EWItemArea_Inactive 0x00000002
// User area: This value and the above ones are free for object specific actions.
#define EWItemArea_User     0x00000003

typedef struct
{
	unsigned int      id;
	CRect             rect;
} WItemArea;

/**
 * Function used to determine an object's area type and position.
 * Calculates the area type if a mouse pointer is given, else uses the area type given on entry.
 *
 * @param  pObject    A pointer to the object.
 * @param  pOwner     A pointer to the object's container.
 * @param  pItem      A pointer to the plot parameters.
 * @param  pMouse     A pointer to the mouse's parameters.
 * @param  pArea      A pointer to a structure to fill in on exit.
 *
 * Returns the area type number and screen position from the mouse pointer or the area type.
 */
typedef void (*FWItem_GetArea)(const void* pObjet, const void* pOwner, const WPlotItem* pItem, const Mouse* pMouse, WItemArea* pArea);

/**
 * Function used to determine if an object's area is touched by a given rect.
 *
 * @param  pObject    A pointer to the object.
 * @param  pOwner     A pointer to the object's container.
 * @param  pItem      A pointer to the plot parameters.
 * @param  AreaID     The ID of an area.
 * @param  pRect      A pointer to a rectangle.
 *
 * Returns true if the rectange touches the given area.
 */
typedef bool (*FWItem_TouchArea)(const void* pObjet, const void* pOwner, const WPlotItem* pItem, unsigned int AreaID, const CRect* pRect);

// Gereric item VTable
typedef struct
{
	FWItem_Plot       FPlot;
	FWItem_GetSizes   FGetSizes;
	FWItem_GetBox     FGetBox;
	FWItem_GetArea    FGetArea;
	FWItem_TouchArea  FTouchArea;
} WItem_VTable;

#ifdef __cplusplus
}
#endif

#endif
