#ifndef _EFL_GFX_MAP_EO_H_
#define _EFL_GFX_MAP_EO_H_

#ifndef _EFL_GFX_MAP_EO_CLASS_TYPE
#define _EFL_GFX_MAP_EO_CLASS_TYPE

typedef Eo Efl_Gfx_Map;

#endif

#ifndef _EFL_GFX_MAP_EO_TYPES
#define _EFL_GFX_MAP_EO_TYPES


#endif
/**
 * @brief Texture UV mapping for all objects (rotation, perspective, 3d, ...).
 *
 * Evas allows different transformations to be applied to all kinds of objects.
 * These are applied by means of UV mapping.
 *
 * With UV mapping, one maps points in the source object to a 3D space
 * positioning at target. This allows rotation, perspective, scale and lots of
 * other effects, depending on the map that is used.
 *
 * Each map point may carry a multiplier color. If properly calculated, these
 * can do shading effects on the object, producing 3D effects.
 *
 * At the moment of writing, maps can only have 4 points (no more, no less).
 * Usually, it will be necessary to update the map points (start afresh with
 * @ref efl_gfx_map_populate) whenever the object geometry changes.
 *
 * @note For now this mixin is only compatible with @c Efl.Canvas.Object and
 * shouldn't be used anywhere else.
 *
 * @note There are a few differences with legacy @c Evas_Map: - A map is now a
 * property of an object, rather than a separate entity. -
 * @ref efl_gfx_map_move_sync_get is enabled by default -
 * @ref efl_gfx_map_populate will be called automatically if another map
 * function is called while the object has no map info.
 *
 * @ingroup Efl_Gfx_Map
 */
#define EFL_GFX_MAP_MIXIN efl_gfx_map_mixin_get()

EWAPI const Eo_Class *efl_gfx_map_mixin_get(void);

/**
 * @brief Whether map transformation is enabled on this object.
 *
 * The default map enable state is off ($false). The other properties and
 * methods in this class have no effect until this property is enabled.
 *
 * @return Enabled state.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_enable_get(const Eo *obj);

/**
 * @brief Whether map transformation is enabled on this object.
 *
 * The default map enable state is off ($false). The other properties and
 * methods in this class have no effect until this property is enabled.
 *
 * Enable or disable the use of map for this object. On enable, the object
 * geometry will be saved, and the new geometry will change (position and size)
 * to reflect the map geometry set.
 *
 * @param[in] enabled Enabled state.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_enable_set(Eo *obj, Eina_Bool enabled);

/**
 * @brief Clockwise state of a map (read-only).
 *
 * This determines if the output points (X and Y. Z is not used) are clockwise
 * or counter-clockwise. This can be used for "back-face culling". This is
 * where you hide objects that "face away" from you. In this case objects that
 * are not clockwise.
 *
 * @return @c true if CW, @c false if CCW.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_clockwise_get(const Eo *obj);

/**
 * @brief Smoothing state for map rendering.
 *
 * This sets smoothing for map rendering. If the object is a type that has its
 * own smoothing settings, then both the smooth settings for this object and
 * the map must be turned off. By default smooth maps are enabled.
 *
 * @param[in] smooth @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_smooth_set(Eo *obj, Eina_Bool smooth);

/**
 * @brief Smoothing state for map rendering.
 *
 * This sets smoothing for map rendering. If the object is a type that has its
 * own smoothing settings, then both the smooth settings for this object and
 * the map must be turned off. By default smooth maps are enabled.
 *
 * @return @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_smooth_get(const Eo *obj);

/**
 * @brief Alpha flag for map rendering.
 *
 * This sets alpha flag for map rendering. If the object is a type that has its
 * own alpha settings, then this will take precedence. Only image objects have
 * this currently ($Efl.Canvas.Image and its friends). Setting this off stops
 * alpha blending of the map area, and is useful if you know the object and/or
 * all sub-objects is 100% solid.
 *
 * @param[in] alpha @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_alpha_set(Eo *obj, Eina_Bool alpha);

/**
 * @brief Alpha flag for map rendering.
 *
 * This sets alpha flag for map rendering. If the object is a type that has its
 * own alpha settings, then this will take precedence. Only image objects have
 * this currently ($Efl.Canvas.Image and its friends). Setting this off stops
 * alpha blending of the map area, and is useful if you know the object and/or
 * all sub-objects is 100% solid.
 *
 * @return @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_alpha_get(const Eo *obj);

/**
 * @brief Map point's coordinate.
 *
 * This sets/gets the fixed point's coordinate in the map. Note that points
 * describe the outline of a quadrangle and are ordered either clockwise or
 * counter-clockwise. It is suggested to keep your quadrangles concave and
 * non-complex, though these polygon modes may work, they may not render a
 * desired set of output. The quadrangle will use points 0 and 1 , 1 and 2, 2
 * and 3, and 3 and 0 to describe the edges of the quadrangle.
 *
 * The X and Y and Z coordinates are in canvas units. Z is optional and may or
 * may not be honored in drawing. Z is a hint and does not affect the X and Y
 * rendered coordinates. It may be used for calculating fills with perspective
 * correct rendering.
 *
 * Remember all coordinates are canvas global ones like with move and resize in
 * the canvas.
 *
 * @param[in] idx ID of the point, from 0 to 3 (included).
 * @param[in] x Point X Coordinate.
 * @param[in] y Point Y Coordinate.
 * @param[in] z Point Z Coordinate hint (pre-perspective transform).
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_point_coord_set(Eo *obj, int idx, double x, double y, double z);

/**
 * @brief Map point's coordinate.
 *
 * This sets/gets the fixed point's coordinate in the map. Note that points
 * describe the outline of a quadrangle and are ordered either clockwise or
 * counter-clockwise. It is suggested to keep your quadrangles concave and
 * non-complex, though these polygon modes may work, they may not render a
 * desired set of output. The quadrangle will use points 0 and 1 , 1 and 2, 2
 * and 3, and 3 and 0 to describe the edges of the quadrangle.
 *
 * The X and Y and Z coordinates are in canvas units. Z is optional and may or
 * may not be honored in drawing. Z is a hint and does not affect the X and Y
 * rendered coordinates. It may be used for calculating fills with perspective
 * correct rendering.
 *
 * Remember all coordinates are canvas global ones like with move and resize in
 * the canvas.
 *
 * @param[in] idx ID of the point, from 0 to 3 (included).
 * @param[out] x Point X Coordinate.
 * @param[out] y Point Y Coordinate.
 * @param[out] z Point Z Coordinate hint (pre-perspective transform).
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_point_coord_get(const Eo *obj, int idx, double *x, double *y, double *z);

/**
 * @brief Map point's U and V texture source point.
 *
 * This sets/gets the U and V coordinates for the point. This determines which
 * coordinate in the source image is mapped to the given point, much like
 * OpenGL and textures. Notes that these points do select the pixel, but are
 * double floating point values to allow for accuracy and sub-pixel selection.
 *
 * @param[in] idx ID of the point, from 0 to 3 (included).
 * @param[in] u X coordinate within the image/texture source.
 * @param[in] v Y coordinate within the image/texture source.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_point_image_uv_set(Eo *obj, int idx, double u, double v);

/**
 * @brief Map point's U and V texture source point.
 *
 * This sets/gets the U and V coordinates for the point. This determines which
 * coordinate in the source image is mapped to the given point, much like
 * OpenGL and textures. Notes that these points do select the pixel, but are
 * double floating point values to allow for accuracy and sub-pixel selection.
 *
 * @param[in] idx ID of the point, from 0 to 3 (included).
 * @param[out] u X coordinate within the image/texture source.
 * @param[out] v Y coordinate within the image/texture source.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_point_image_uv_get(const Eo *obj, int idx, double *u, double *v);

/**
 * @brief Color of a vertex in the map.
 *
 * This sets the color of the vertex in the map. Colors will be linearly
 * interpolated between vertex points through the map. Color will multiply the
 * "texture" pixels (like GL_MODULATE in OpenGL). The default color of a vertex
 * in a map is white solid (255, 255, 255, 255) which means it will have no
 * affect on modifying the texture pixels.
 *
 * The color values must be premultiplied (ie. @c a >= {$r, @c g, @c b}).
 *
 * @param[in] idx ID of the point, from 0 to 3 (included). -1 can be used to
 * set the color for all points, but it is invalid for get().
 * @param[in] r Red (0 - 255)
 * @param[in] g Green (0 - 255)
 * @param[in] b Blue (0 - 255)
 * @param[in] a Alpha (0 - 255)
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_color_set(Eo *obj, int idx, int r, int g, int b, int a);

/**
 * @brief Color of a vertex in the map.
 *
 * This sets the color of the vertex in the map. Colors will be linearly
 * interpolated between vertex points through the map. Color will multiply the
 * "texture" pixels (like GL_MODULATE in OpenGL). The default color of a vertex
 * in a map is white solid (255, 255, 255, 255) which means it will have no
 * affect on modifying the texture pixels.
 *
 * The color values must be premultiplied (ie. @c a >= {$r, @c g, @c b}).
 *
 * @param[in] idx ID of the point, from 0 to 3 (included). -1 can be used to
 * set the color for all points, but it is invalid for get().
 * @param[out] r Red (0 - 255)
 * @param[out] g Green (0 - 255)
 * @param[out] b Blue (0 - 255)
 * @param[out] a Alpha (0 - 255)
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_color_get(const Eo *obj, int idx, int *r, int *g, int *b, int *a);

/**
 * @brief Status of object move synchronization for map rendering.
 *
 * If the flag is set as enabled, the map will be moved as the object is moved.
 *
 * @param[in] enable @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI void efl_gfx_map_move_sync_set(Eo *obj, Eina_Bool enable);

/**
 * @brief Status of object move synchronization for map rendering.
 *
 * If the flag is set as enabled, the map will be moved as the object is moved.
 *
 * @return @c true by default.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_move_sync_get(const Eo *obj);

/**
 * @brief Value of Z coordinate of point @c idx.
 *
 * Useful to call @ref efl_gfx_map_populate without changing Z.
 *
 * @param[in] idx
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI double efl_gfx_map_point_z_get(const Eo *obj, int idx);

/**
 * @brief Populate source and destination map points to match this object.
 *
 * @param[in] z Point Z coordinate (pre-perpective transform), used for all 4
 * points. 0 by default.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_populate(Eo *obj, double z);

/**
 * @brief Populate source and destination map points to match given geometry.
 *
 * Similar to @ref efl_gfx_map_populate, this call takes raw values instead of
 * querying this object's unmapped geometry. The given size will be used to
 * calculate destination points (@Efl.Gfx.Map.map_point_coord) and set the
 * image uv (@Efl.Gfx.Map.map_point_image_uv).
 *
 * @param[in] x
 * @param[in] y
 * @param[in] w
 * @param[in] h
 * @param[in] z Point Z coordinate (pre-perpective transform), used for all 4
 * points. 0 by default.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_populate_manual(Eo *obj, double x, double y, double w, double h, double z);

/**
 * @brief Change the map to apply the given rotation.
 *
 * This rotates the indicated map's coordinates around the center coordinate
 * given by @c cx and @c cy as the rotation center. The points will have their
 * X and Y coordinates rotated clockwise by @c degrees degrees (360.0 is a full
 * rotation). Negative values for degrees will rotate counter-clockwise by that
 * amount. All coordinates are canvas global coordinates.
 *
 * @param[in] degrees CCW rotation in degrees.
 * @param[in] cx X coordinate of the rotation center.
 * @param[in] cy Y coordinate of the rotation center.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_rotate(Eo *obj, double degrees, double cx, double cy);

/**
 * @brief Change the map to apply the given zooming.
 *
 * Like evas_map_util_rotate(), this zooms the points of the map from a center
 * point. That center is defined by @c cx and @c cy. The @c zoomx and @c zoomy
 * parameters specify how much to zoom in the X and Y direction respectively. A
 * value of 1.0 means "don't zoom". 2.0 means "double the size". 0.5 is "half
 * the size" etc. All coordinates are canvas global coordinates.
 *
 * @param[in] zoomx
 * @param[in] zoomy
 * @param[in] cx X coordinate of the center point.
 * @param[in] cy Y coordinate of the center point.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_zoom(Eo *obj, double zoomx, double zoomy, double cx, double cy);

/**
 * @brief Rotate the map around 3 axes in 3D
 *
 * This will rotate not just around the "Z" axis as in evas_map_util_rotate()
 * (which is a convenience call for those only wanting 2D). This will rotate
 * around the X, Y and Z axes. The Z axis points "into" the screen with low
 * values at the screen and higher values further away. The X axis runs from
 * left to right on the screen and the Y axis from top to bottom. Like with
 * evas_map_util_rotate() you provide a center point to rotate around (in 3D).
 *
 * @param[in] dx Rotation in degrees around X axis (0 to 360).
 * @param[in] dy Rotation in degrees around Y axis (0 to 360).
 * @param[in] dz Rotation in degrees around Z axis (0 to 360).
 * @param[in] cx Rotation's center X position.
 * @param[in] cy Rotation's center Y position.
 * @param[in] cz Rotation's center Z position.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_rotate_3d(Eo *obj, double dx, double dy, double dz, double cx, double cy, double cz);

/**
 * @brief Rotate the map in 3D using a unit quaternion.
 *
 * This will rotate in 3D using a unit quaternion. Like with
 * evas_map_util_3d_rotate() you provide a center point to rotate around (in
 * 3D).
 *
 * @param[in] qx the x component of the imaginary part of the quaternion.
 * @param[in] qy the y component of the imaginary part of the quaternion.
 * @param[in] qz the z component of the imaginary part of the quaternion.
 * @param[in] qw the w component of the real part of the quaternion.
 * @param[in] cx rotation's center x.
 * @param[in] cy rotation's center y.
 * @param[in] cz rotation's center z.
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_quat_rotate(Eo *obj, double qx, double qy, double qz, double qw, double cx, double cy, double cz);

/**
 * @brief Perform lighting calculations on the given Map
 *
 * This is used to apply lighting calculations (from a single light source) to
 * a given map. The R, G and B values of each vertex will be modified to
 * reflect the lighting based on the light point coordinates, the light color
 * and the ambient color, and at what angle the map is facing the light source.
 * A surface should have its points be declared in a clockwise fashion if the
 * face is "facing" towards you (as opposed to away from you) as faces have a
 * "logical" side for lighting.
 *
 * @param[in] lx X coordinate in space of light point.
 * @param[in] ly Y coordinate in space of light point.
 * @param[in] lz Z coordinate in space of light point.
 * @param[in] lr light red value (0 - 255).
 * @param[in] lg light green value (0 - 255).
 * @param[in] lb light blue value (0 - 255).
 * @param[in] ar ambient color red value (0 - 255).
 * @param[in] ag ambient color green value (0 - 255).
 * @param[in] ab ambient color blue value (0 - 255).
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_lightning_3d(Eo *obj, double lx, double ly, double lz, int lr, int lg, int lb, int ar, int ag, int ab);

/**
 * @brief Apply a perspective transform to the map
 *
 * This applies a given perspective (3D) to the map coordinates. X, Y and Z
 * values are used. The px and py points specify the "infinite distance" point
 * in the 3D conversion (where all lines converge to like when artists draw 3D
 * by hand). The @c z0 value specifies the z value at which there is a 1:1
 * mapping between spatial coordinates and screen coordinates. Any points on
 * this z value will not have their X and Y values modified in the transform.
 * Those further away (Z value higher) will shrink into the distance, and those
 * less than this value will expand and become bigger. The @c foc value
 * determines the "focal length" of the camera. This is in reality the distance
 * between the camera lens plane itself (at or closer than this rendering
 * results are undefined) and the "z0" z value. This allows for some "depth"
 * control and @c foc must be greater than 0.
 *
 * @param[in] px The perspective distance X coordinate
 * @param[in] py The perspective distance Y coordinate
 * @param[in] z0 The "0" z plane value
 * @param[in] foc The focal distance
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_perspective_3d(Eo *obj, double px, double py, double z0, double foc);

/**
 * @brief Duplicate the map information from another object.
 *
 * @param[in] other
 *
 * @return @c false in case of error.
 *
 * @ingroup Efl_Gfx_Map
 */
EOAPI Eina_Bool efl_gfx_map_dup(Eo *obj, const Efl_Gfx_Map *other);


#endif
