#ifndef _EFL_GFX_IMAGE_EO_H_
#define _EFL_GFX_IMAGE_EO_H_

#ifndef _EFL_GFX_IMAGE_EO_CLASS_TYPE
#define _EFL_GFX_IMAGE_EO_CLASS_TYPE

typedef Eo Efl_Gfx_Image;

#endif

#ifndef _EFL_GFX_IMAGE_EO_TYPES
#define _EFL_GFX_IMAGE_EO_TYPES

#ifdef EFL_BETA_API_SUPPORT
/** How an image's data is to be treated by EFL, for optimization.
 *
 * @ingroup Efl_Gfx
 */
typedef enum
{
  EFL_GFX_IMAGE_CONTENT_HINT_NONE = 0, /**< No hint on the content (default). */
  EFL_GFX_IMAGE_CONTENT_HINT_DYNAMIC = 1, /**< The content will change over
                                           * time. */
  EFL_GFX_IMAGE_CONTENT_HINT_STATIC = 2 /**< The content won't change over time.
                                         */
} Efl_Gfx_Image_Content_Hint;
#endif /* EFL_BETA_API_SUPPORT */

#ifdef EFL_BETA_API_SUPPORT
/** How an image's data is to be treated by EFL, with regard to scaling cache.
 *
 * @ingroup Efl_Gfx
 */
typedef enum
{
  EFL_GFX_IMAGE_SCALE_HINT_NONE = 0, /**< No hint on the scaling (default). */
  EFL_GFX_IMAGE_SCALE_HINT_DYNAMIC = 1, /**< Image will be re-scaled over time,
                                         * thus turning scaling cache OFF for
                                         * its data. */
  EFL_GFX_IMAGE_SCALE_HINT_STATIC = 2 /**< Image will not be re-scaled over
                                       * time, thus turning scaling cache ON
                                       * for its data. */
} Efl_Gfx_Image_Scale_Hint;
#endif /* EFL_BETA_API_SUPPORT */

#ifdef EFL_BETA_API_SUPPORT
/** Enumeration that defines scale types of an image.
 *
 * @ingroup Efl_Gfx
 */
typedef enum
{
  EFL_GFX_IMAGE_SCALE_TYPE_FILL = 0, /**< Scale the image so that it matches the
                                      * object's area exactly. The image's
                                      * aspect ratio might be changed. */
  EFL_GFX_IMAGE_SCALE_TYPE_FIT_INSIDE, /**< Scale the image so that it fits
                                        * inside the object's area while
                                        * maintaining the aspect ratio. At
                                        * least one of the dimensions of the
                                        * image should be equal to the
                                        * corresponding dimension of the
                                        * object. */
  EFL_GFX_IMAGE_SCALE_TYPE_FIT_OUTSIDE, /**< Scale the image so that it covers
                                         * the entire object area while
                                         * maintaining the aspect ratio. At
                                         * least one of the dimensions of the
                                         * image should be equal to the
                                         * corresponding dimension of the
                                         * object. */
  EFL_GFX_IMAGE_SCALE_TYPE_TILE, /**< Tile image at its original size. */
  EFL_GFX_IMAGE_SCALE_TYPE_NONE /**< Not scale the image */
} Efl_Gfx_Image_Scale_Type;
#endif /* EFL_BETA_API_SUPPORT */


#endif
#ifdef EFL_BETA_API_SUPPORT
/** Common APIs for all 2D images that can be rendered on the canvas.
 *
 * @ingroup Efl_Gfx_Image
 */
#define EFL_GFX_IMAGE_INTERFACE efl_gfx_image_interface_get()

EWAPI const Efl_Class *efl_gfx_image_interface_get(void);

/**
 * @brief Whether to use high-quality image scaling algorithm for this image.
 *
 * When enabled, a higher quality image scaling algorithm is used when scaling
 * images to sizes other than the source image's original one. This gives
 * better results but is more computationally expensive.
 *
 * @c true by default
 *
 * @param[in] obj The object.
 * @param[in] smooth_scale Whether to use smooth scale or not.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_smooth_scale_set(Eo *obj, Eina_Bool smooth_scale);

/**
 * @brief Whether to use high-quality image scaling algorithm for this image.
 *
 * When enabled, a higher quality image scaling algorithm is used when scaling
 * images to sizes other than the source image's original one. This gives
 * better results but is more computationally expensive.
 *
 * @c true by default
 *
 * @param[in] obj The object.
 *
 * @return Whether to use smooth scale or not.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Eina_Bool efl_gfx_image_smooth_scale_get(const Eo *obj);

/**
 * @brief Control how the image is scaled.
 *
 * @param[in] obj The object.
 * @param[in] scale_type Image scale type
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_scale_type_set(Eo *obj, Efl_Gfx_Image_Scale_Type scale_type);

/**
 * @brief Control how the image is scaled.
 *
 * @param[in] obj The object.
 *
 * @return Image scale type
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Efl_Gfx_Image_Scale_Type efl_gfx_image_scale_type_get(const Eo *obj);

/**
 * @brief The native width/height ratio of the image.
 *
 * Returns 1.0 if not applicable (eg. height = 0).
 *
 * @param[in] obj The object.
 *
 * @return The image's ratio.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI double efl_gfx_image_ratio_get(const Eo *obj);

/**
 * @brief Dimensions of this image's border, a region that does not scale with
 * the center area.
 *
 * When EFL renders an image, its source may be scaled to fit the size of the
 * object. This function sets an area from the borders of the image inwards
 * which is not to be scaled. This function is useful for making frames and for
 * widget theming, where, for example, buttons may be of varying sizes, but
 * their border size must remain constant.
 *
 * The units used for @c l, @c r, @c t and @c b are canvas units (pixels).
 *
 * @note The border region itself may be scaled by the
 * @ref efl_gfx_image_border_scale_set function.
 *
 * @note By default, image objects have no borders set, i.e. @c l, @c r, @c t
 * and @c b start as 0.
 *
 * @note Similar to the concepts of 9-patch images or cap insets.
 *
 * @param[in] obj The object.
 * @param[in] l The border's left width.
 * @param[in] r The border's right width.
 * @param[in] t The border's top height.
 * @param[in] b The border's bottom height.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_border_set(Eo *obj, int l, int r, int t, int b);

/**
 * @brief Dimensions of this image's border, a region that does not scale with
 * the center area.
 *
 * When EFL renders an image, its source may be scaled to fit the size of the
 * object. This function sets an area from the borders of the image inwards
 * which is not to be scaled. This function is useful for making frames and for
 * widget theming, where, for example, buttons may be of varying sizes, but
 * their border size must remain constant.
 *
 * The units used for @c l, @c r, @c t and @c b are canvas units (pixels).
 *
 * @note The border region itself may be scaled by the
 * @ref efl_gfx_image_border_scale_set function.
 *
 * @note By default, image objects have no borders set, i.e. @c l, @c r, @c t
 * and @c b start as 0.
 *
 * @note Similar to the concepts of 9-patch images or cap insets.
 *
 * @param[in] obj The object.
 * @param[out] l The border's left width.
 * @param[out] r The border's right width.
 * @param[out] t The border's top height.
 * @param[out] b The border's bottom height.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_border_get(const Eo *obj, int *l, int *r, int *t, int *b);

/**
 * @brief Scaling factor applied to the image borders.
 *
 * This value multiplies the size of the @ref efl_gfx_image_border_get when
 * scaling an object.
 *
 * Default value is 1.0 (no scaling).
 *
 * @param[in] obj The object.
 * @param[in] scale The scale factor.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_border_scale_set(Eo *obj, double scale);

/**
 * @brief Scaling factor applied to the image borders.
 *
 * This value multiplies the size of the @ref efl_gfx_image_border_get when
 * scaling an object.
 *
 * Default value is 1.0 (no scaling).
 *
 * @param[in] obj The object.
 *
 * @return The scale factor.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI double efl_gfx_image_border_scale_get(const Eo *obj);

/**
 * @brief Specifies how the center part of the object (not the borders) should
 * be drawn when EFL is rendering it.
 *
 * This function sets how the center part of the image object's source image is
 * to be drawn, which must be one of the values in
 * @ref Efl_Gfx_Border_Fill_Mode. By center we mean the complementary part of
 * that defined by @ref efl_gfx_image_border_set. This is very useful for
 * making frames and decorations. You would most probably also be using a
 * filled image (as in @ref efl_gfx_fill_auto_get) to use as a frame.
 *
 * The default value is @ref EFL_GFX_BORDER_FILL_MODE_DEFAULT, ie. render and
 * scale the center area, respecting its transparency.
 *
 * @param[in] obj The object.
 * @param[in] fill Fill mode of the center region.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_border_center_fill_set(Eo *obj, Efl_Gfx_Border_Fill_Mode fill);

/**
 * @brief Specifies how the center part of the object (not the borders) should
 * be drawn when EFL is rendering it.
 *
 * This function sets how the center part of the image object's source image is
 * to be drawn, which must be one of the values in
 * @ref Efl_Gfx_Border_Fill_Mode. By center we mean the complementary part of
 * that defined by @ref efl_gfx_image_border_set. This is very useful for
 * making frames and decorations. You would most probably also be using a
 * filled image (as in @ref efl_gfx_fill_auto_get) to use as a frame.
 *
 * The default value is @ref EFL_GFX_BORDER_FILL_MODE_DEFAULT, ie. render and
 * scale the center area, respecting its transparency.
 *
 * @param[in] obj The object.
 *
 * @return Fill mode of the center region.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Efl_Gfx_Border_Fill_Mode efl_gfx_image_border_center_fill_get(const Eo *obj);

/**
 * @brief This represents the size of the original image in pixels.
 *
 * This may be different from the actual geometry on screen or even the size of
 * the loaded pixel buffer. This is the size of the image as stored in the
 * original file.
 *
 * This is a read-only property, and may return 0x0.
 *
 * @param[in] obj The object.
 *
 * @return The size in pixels.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Eina_Size2D efl_gfx_image_size_get(const Eo *obj);

/**
 * @brief Set the content hint setting of a given image object of the canvas.
 *
 * This function sets the content hint value of the given image of the canvas.
 * For example, if you're on the GL engine and your driver implementation
 * supports it, setting this hint to #EVAS_IMAGE_CONTENT_HINT_DYNAMIC will make
 * it need zero copies at texture upload time, which is an "expensive"
 * operation.
 *
 * @param[in] obj The object.
 * @param[in] hint Dynamic or static content hint, see
 * @ref Efl_Gfx_Image_Content_Hint
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_content_hint_set(Eo *obj, Efl_Gfx_Image_Content_Hint hint);

/**
 * @brief Get the content hint setting of a given image object of the canvas.
 *
 * This returns #EVAS_IMAGE_CONTENT_HINT_NONE on error.
 *
 * @param[in] obj The object.
 *
 * @return Dynamic or static content hint, see @ref Efl_Gfx_Image_Content_Hint
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Efl_Gfx_Image_Content_Hint efl_gfx_image_content_hint_get(const Eo *obj);

/**
 * @brief Set the scale hint of a given image of the canvas.
 *
 * This function sets the scale hint value of the given image object in the
 * canvas, which will affect how Evas is to cache scaled versions of its
 * original source image.
 *
 * @param[in] obj The object.
 * @param[in] hint Scalable or static size hint, see
 * @ref Efl_Gfx_Image_Scale_Hint
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI void efl_gfx_image_scale_hint_set(Eo *obj, Efl_Gfx_Image_Scale_Hint hint);

/**
 * @brief Get the scale hint of a given image of the canvas.
 *
 * This function returns the scale hint value of the given image object of the
 * canvas.
 *
 * @param[in] obj The object.
 *
 * @return Scalable or static size hint, see @ref Efl_Gfx_Image_Scale_Hint
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Efl_Gfx_Image_Scale_Hint efl_gfx_image_scale_hint_get(const Eo *obj);

/**
 * @brief Gets the (last) file loading error for a given object.
 *
 * @param[in] obj The object.
 *
 * @return The load error code.
 *
 * @ingroup Efl_Gfx_Image
 */
EOAPI Eina_Error efl_gfx_image_load_error_get(const Eo *obj);

EWAPI extern const Efl_Event_Description _EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD;

/** Image data has been preloaded.
 *
 * @ingroup Efl_Gfx_Image
 */
#define EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD (&(_EFL_GFX_IMAGE_EVENT_IMAGE_PRELOAD))

EWAPI extern const Efl_Event_Description _EFL_GFX_IMAGE_EVENT_IMAGE_RESIZE;

/** Image was resized (its pixel data).
 *
 * @ingroup Efl_Gfx_Image
 */
#define EFL_GFX_IMAGE_EVENT_IMAGE_RESIZE (&(_EFL_GFX_IMAGE_EVENT_IMAGE_RESIZE))

EWAPI extern const Efl_Event_Description _EFL_GFX_IMAGE_EVENT_IMAGE_UNLOAD;

/** Image data has been unloaded (by some mechanism in EFL that threw out the
 * original image data).
 *
 * @ingroup Efl_Gfx_Image
 */
#define EFL_GFX_IMAGE_EVENT_IMAGE_UNLOAD (&(_EFL_GFX_IMAGE_EVENT_IMAGE_UNLOAD))
#endif /* EFL_BETA_API_SUPPORT */

#endif
