/*
 * --- GSMP-COPYRIGHT-NOTE-BEGIN ---
 * 
 * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
 * Please add additional copyright information _after_ the line containing
 * the GSMP-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
 * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
 * 
 * GSMP: gfx/include/EvasHelper.hh
 * General Sound Manipulation Program is Copyright (C) 2000 - 2008
 *   Valentin Ziegler and Renebe
 * 
 * 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; version 2. A copy of the GNU General
 * Public License can be found in the file LICENSE.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT-
 * ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * 
 * --- GSMP-COPYRIGHT-NOTE-END ---
 */

#ifndef __EVASHELPER__
#define __EVASHELPER__

#include <Evas.h>
#include <inttypes.h>

#include <string>

class EvasCanvas {
 public:
  
  EvasCanvas ();
  ~EvasCanvas ();
  
  bool OutputMethod (const std::string& method);
  
  Evas_Engine_Info* EngineInfo ();
  
  void EngineInfo (Evas_Engine_Info* info) {
    evas_engine_info_set (ob, info);
  };
  
  void OutputSize (int w, int h) {
    evas_output_size_set (ob, w, h);
  }
  
  int OutputWidth () {
    int w, h;
    evas_output_size_get (ob, &w, &h);
    return w;
  }

  int OutputHeight () {
    int w, h;
    evas_output_size_get (ob, &w, &h);
    return h;
  }
  
  void OutputViewport (int x, int y, int w, int h) {
    evas_output_viewport_set (ob, x, y, w, h);
  }
  
  void ImageCacheFlush () {
    evas_image_cache_flush (ob);
  }
  
  void ImageCacheReload () {
    evas_image_cache_reload (ob);
  }

  void ImageCache (int size = 1024) {
    evas_image_cache_set (ob, size);
  }
  
  void FontPathClear () {
    evas_font_path_clear (ob);
  }

  void FontPathAppend (const std::string& path) {
    evas_font_path_append (ob, path.c_str () );
  }
  
  void FontPathPrepend (const std::string& path) {
    evas_font_path_prepend (ob, path.c_str () );
  }

  void FontCacheFlush () {
    evas_font_cache_flush (ob);
  }
  
  void FontCache (int size = 1024) {
    evas_font_cache_set (ob, size);
  }

  // -- Re-(*)draw handling --
  
  void DamageRectangleAdd (int x, int y, int w, int h) {
    evas_damage_rectangle_add (ob, x, y, w, h);
  }
  
  void ObscuredRectangleAdd (int x, int y, int w, int h) {
    evas_obscured_rectangle_add (ob, x, y, w, h);
  }
  
  void Render () {
    evas_render (ob);
  }
  
  // -- Event stuff --
  /*
  void EventFeedMouseDown      (int b, Evas_Button_Flags flags) {
    evas_event_feed_mouse_down (ob, b, flags, NULL);
  };
  void EventFeedMouseUp        (int b, Evas_Button_Flags flags) {
    evas_event_feed_mouse_up (ob, b, flags, NULL);
  };
  void EventFeedMouseMove      (int x, int y) {
    evas_event_feed_mouse_move (ob, x, y, NULL);
  };
  void EventFeedmouseIn        () {
    evas_event_feed_mouse_in (ob, NULL);
  };
  */
  
  /*
  
  void EventFeedKeyDown        (const char *keyname, const char *keysymbol, const char *key_compose) {
    evas_event_feed_key_down (ob, keyname, keysymbol, key_compose, NULL, NULL);
  };
  void EventFeedKeyUp          (const char *keyname, const char *keysymbol, const char *key_compose) {
    evas_event_feed_key_up (ob, keyname, keysymbol, key_compose, NULL, NULL);
  };
  */
  
  Evas* c_obj () {
      return ob;
  }
  
 private:
  Evas* ob;
};

class EvasBase {
 
 public:
  
  void Move (Evas_Coord x, Evas_Coord y) {
    evas_object_move (ob, x, y);
  }
  
  void Resize (Evas_Coord w, Evas_Coord h) {
    evas_object_resize (ob, w, h);
  }

  Evas_Coord X () {
    Evas_Coord x, y, w, h;
    evas_object_geometry_get (ob, &x, &y, &w, &h);
    return x;
  }

  Evas_Coord Y () {
    Evas_Coord x, y, w, h;
    evas_object_geometry_get (ob, &x, &y, &w, &h);
    return y;
  }

  Evas_Coord Width () {
    Evas_Coord x, y, w, h;
    evas_object_geometry_get (ob, &x, &y, &w, &h);
    return w;
  }

  Evas_Coord Height () {
    Evas_Coord x, y, w, h;
    evas_object_geometry_get (ob, &x, &y, &w, &h);
    return h;
  }
  
  void Color (int r, int g, int b, int a) {
#ifdef WITHEVAS_COLOR_PREMUL
    evas_color_argb_premul (a, &r, &g, &b);
#endif
    evas_object_color_set (ob, r, g, b, a);
  }

  void GetColor (int* r, int* g, int* b, int* a) {
    evas_object_color_get (ob, r, g, b, a);
  }
  
  void Layer (int l) {
    evas_object_layer_set (ob, l);
  }
  
  int  Layer () {
    return evas_object_layer_get (ob);
  }
  
  void Raise  () {
    evas_object_raise (ob);
  }
  
  void Lower  () {
    evas_object_lower (ob);
  }

  void Show () {
    evas_object_show (ob);
  }
  
  void Hide () {
    evas_object_hide (ob);
  }
  
  bool IsVisible () {
    return evas_object_visible_get (ob);
  }

  Evas_Object* c_obj () {
      return ob;
  }
  
 protected:
  EvasBase (bool i_owner);
  virtual ~EvasBase ();
  
  Evas_Object* ob;
  bool owner;
};
  
class EvasImage : public EvasBase {
  
 public:
  
  EvasImage (EvasCanvas& evas);
  EvasImage (Evas_Object* i_ob);
  virtual ~EvasImage ();

  void ImageSize (int w, int h) {
    evas_object_image_size_set (ob, w, h);
  }
    
  int ImageWidth () {
    int w, h;
    evas_object_image_size_get (ob, &w, &h);
    return w;
  }
  
  int ImageHeight () {
    int w, h;
    evas_object_image_size_get (ob, &w, &h);
    return h;
  }

  void Alpha (bool alpha) {
    evas_object_image_alpha_set (ob, alpha);
  }

  bool IsAlpha () {
    return evas_object_image_alpha_get (ob);
  }
  
  void ImageFill (Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) {
    evas_object_image_fill_set (ob, x, y, w, h);
  }

  Evas_Coord ImageFillX () {
    Evas_Coord x, y, w, h;
    evas_object_image_fill_get (ob, &x, &y, &w, &h);
    return w;
  }
  
  Evas_Coord ImageFillY () {
    Evas_Coord x, y, w, h;
    evas_object_image_fill_get (ob, &x, &y, &w, &h);
    return h;
  }
    
  Evas_Coord ImageFillWidth () {
    Evas_Coord x, y, w, h;
    evas_object_image_fill_get (ob, &x, &y, &w, &h);
    return w;
  }
  
  Evas_Coord ImageFillHeight () {
    Evas_Coord x, y, w, h;
    evas_object_image_fill_get (ob, &x, &y, &w, &h);
    return h;
  }
  
  
  void SmoothScale (bool smooth) {
    evas_object_image_smooth_scale_set (ob, smooth);
  }
  bool SmoothScale () {
    return evas_object_image_smooth_scale_get (ob);
  }

  unsigned char* Data () {
    return (unsigned char*) evas_object_image_data_get (ob, 1); }

  void DataUpdateAdd (int x, int y, int w, int h) {
    evas_object_image_data_update_add (ob,x,y,w,h); }

  void SetData (unsigned char* data) {
#ifdef WITHEVAS_COLOR_PREMUL
    if (IsAlpha() && data)
      evas_data_argb_premul ((unsigned int*)data, ImageWidth() * ImageHeight());
#endif
    evas_object_image_data_set (ob, data);
  }
  
  // our helper
  bool SmartLoad (const std::string& fname);
  void ApplyAlpha (uint8_t alpha);

 protected:
  
  int cached_w, cached_h;
};

class EvasText : public EvasBase {
  
 public:
  
  EvasText (EvasCanvas& evas);
  EvasText (Evas_Object* i_ob);
  virtual ~EvasText ();
  
  void Font (const std::string& font, int height = 10) {
    evas_object_text_font_set (ob, font.c_str (), height);
  }
  void Text (const std::string& text) {
    evas_object_text_text_set (ob, text.c_str () );
  }
  
  std::string GetText () {
    return std::string (evas_object_text_text_get (ob));
  }
  
  // TODO: set height and font family ...
  
 protected:
};

class EvasRectangle : public EvasBase {
  
public:
  
  EvasRectangle (EvasCanvas& evas);
  EvasRectangle (Evas_Object* i_ob);
  virtual ~EvasRectangle ();
  
protected:
};

#endif // __EVASHELPER__
