/* Copyright (C) 2007 The cluttermm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <cluttermm/group.h>
#include <cluttermm/color.h>
#include <clutter/clutter.h> // For ClutterPerspective

_DEFS(cluttermm,clutter)
_PINCLUDE(cluttermm/private/group_p.h)

namespace Clutter
{

_WRAP_ENUM(PickMode, ClutterPickMode)

typedef ClutterFog Fog;

class Perspective
{
  _CLASS_BOXEDTYPE_STATIC(Perspective, ClutterPerspective)
public:
  Perspective(Cogl::Fixed fovy, Cogl::Fixed aspect, Cogl::Fixed z_near, Cogl::Fixed z_far);

  _MEMBER_GET(fovy, fovy, Cogl::Fixed, CoglFixed)
  _MEMBER_SET(fovy, fovy, Cogl::Fixed, CoglFixed)
  _MEMBER_GET(aspect, aspect, Cogl::Fixed, CoglFixed)
  _MEMBER_SET(aspect, aspect, Cogl::Fixed, CoglFixed)
  _MEMBER_GET(z_near, z_near, Cogl::Fixed, CoglFixed)
  _MEMBER_SET(z_near, z_near, Cogl::Fixed, CoglFixed)
  _MEMBER_GET(z_far, z_far, Cogl::Fixed, CoglFixed)
  _MEMBER_SET(z_far, z_far, Cogl::Fixed, CoglFixed)
};

//TODO: Wrap clutter_feature_available(), as mentioned in the class comment.

/** This is a top level 'window' on which child actors are placed and manipulated.
 *
 * Clutter creates a default stage upon initialization, which can be retrieved using Stage::get_default(). Clutter always
 * provides the default stage, unless the backend is unable to create one. The stage returned by Stage::get_default() is
 * guaranteed to always be the same.
 *
 * Backends might provide support for multiple stages. The support for this feature can be checked at run-time using the
 * clutter_feature_available() function and the CLUTTER_FEATURE_STAGE_MULTIPLE flag. If the backend used supports multiple
 * stages, new Clutter::Stage instances can be created.
 *
 * Clutter::Stage is a proxy actor, wrapping the backend-specific implementation of the windowing system. It is possible
 * to subclass ClutterStage, as long as every overridden virtual function calls the implementation in the base class.
 */
class Stage :
  public Group
{
  _CLASS_GOBJECT(Stage, ClutterStage, CLUTTER_STAGE, Group, ClutterGroup)

protected:
  _CTOR_DEFAULT()

public:
#m4 _CONVERSION(`ClutterActor*',`Glib::RefPtr<Stage>',`Glib::wrap((ClutterStage*)$3)')
  _WRAP_METHOD(static Glib::RefPtr<Stage> get_default(), clutter_stage_get_default, refreturn)
  _WRAP_METHOD(void set_color(const Color& color), clutter_stage_set_color)
  _WRAP_METHOD_DOCS_ONLY(clutter_stage_get_color)
  Color get_color() const;

#m4 _CONVERSION(`const Perspective&', `ClutterPerspective*',`const_cast<$2>(($3).gobj())')
#m4 _CONVERSION(`Perspective&', `ClutterPerspective*',`const_cast<$2>(($3).gobj())')

  _WRAP_METHOD(void set_perspective(const Perspective& prespective), clutter_stage_set_perspective)
  _WRAP_METHOD(void get_perspective(Perspective& prespective), clutter_stage_get_perspective)
  _WRAP_METHOD(void set_fullscreen(bool fullscreen = true), clutter_stage_set_fullscreen)
  _WRAP_METHOD(bool get_fullscreen() const, clutter_stage_get_fullscreen)
  _WRAP_METHOD(void show_cursor(), clutter_stage_show_cursor)
  _WRAP_METHOD(void hide_cursor(), clutter_stage_hide_cursor)
  _WRAP_METHOD(Glib::ustring get_title() const, clutter_stage_get_title)
  _WRAP_METHOD(void set_title(const Glib::ustring& title), clutter_stage_set_title)
  _WRAP_METHOD(void set_user_resizable(bool value), clutter_stage_set_user_resizable)
  _WRAP_METHOD(bool get_user_resizable() const, clutter_stage_get_user_resizable)

  _WRAP_METHOD(Glib::RefPtr<Actor> get_actor_at_pos(PickMode pick_mode, int x, int y), clutter_stage_get_actor_at_pos, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Actor> get_actor_at_pos(PickMode pick_mode, int x, int y) const, clutter_stage_get_actor_at_pos, refreturn, constversion)

  _WRAP_METHOD(Glib::RefPtr<Actor> get_key_focus(), clutter_stage_get_key_focus, refreturn)
  _WRAP_METHOD(Glib::RefPtr<const Actor> get_key_focus() const, clutter_stage_get_key_focus,  refreturn, constversion)

  _WRAP_METHOD(void set_key_focus(const Glib::RefPtr<Actor>& actor), clutter_stage_set_key_focus)
  void set_key_focus();

  // TODO: Should we rather wrap this as std::string, or
  // as std::vector<unsigned char>, or Glib::ArrayHandle<guchar>?
  _WRAP_METHOD(guchar* read_pixels(int x, int y, int width, int height) const, clutter_stage_read_pixels)
  _WRAP_METHOD(bool get_use_fog() const, clutter_stage_get_use_fog)
  _WRAP_METHOD(void set_use_fog(bool fog = true), clutter_stage_set_use_fog)
#m4 _CONVERSION(`const Fog&',`ClutterFog*',`const_cast<ClutterFog*>(&($3))')
  _WRAP_METHOD(void set_fog(const Fog& fog), clutter_stage_set_fog)
  _WRAP_METHOD(void get_fog(Fog& fog) const, clutter_stage_get_fog)

  _WRAP_METHOD(void stage_event(Event* event), clutter_stage_event)
  _WRAP_METHOD(bool is_default() const, clutter_stage_is_default)
  _WRAP_METHOD(void ensure_current(), clutter_stage_ensure_current)
  _WRAP_METHOD(void ensure_viewport(), clutter_stage_ensure_viewport)

  _WRAP_METHOD(void ensure_redraw(), clutter_stage_ensure_redraw)

  _WRAP_METHOD(void set_throttle_motion_events(bool throttle = true), clutter_stage_set_throttle_motion_events)
  _WRAP_METHOD(bool get_throttle_motion_events() const, clutter_stage_get_throttle_motion_events)

  _WRAP_METHOD(void set_use_alpha(bool use_alpha = true), clutter_stage_set_use_alpha)
  _WRAP_METHOD(bool get_use_alpha() const, clutter_stage_get_use_alpha)

  _WRAP_METHOD(void set_minimum_size(guint width, guint height), clutter_stage_set_minimum_size)
  _WRAP_METHOD(void get_minimum_size(guint& width, guint& height), clutter_stage_get_minimum_size)

  _WRAP_SIGNAL(void fullscreen(), "fullscreen")
  _WRAP_SIGNAL(void unfullscreen(), "unfullscreen")
  _WRAP_SIGNAL(void activate(), "activate")
  _WRAP_SIGNAL(void deactivate(), "deactivate")
  _WRAP_SIGNAL(bool delete_event(ClutterEvent *event), "delete-event")

  _WRAP_PROPERTY("color", Color)
  _WRAP_PROPERTY("cursor-visible", bool)
  _WRAP_PROPERTY("fullscreen", bool)
  _WRAP_PROPERTY("offscreen", bool)
  _WRAP_PROPERTY("title", Glib::ustring)
  _WRAP_PROPERTY("use-fog", bool)
  _WRAP_PROPERTY("user-resizable", bool)

protected:
  // From the Clutter Docs:
  // Applications should call clutter_actor_queue_redraw and not this function.
  //_WRAP_METHOD(void queue_redraw(), clutter_stage_queue_redraw)
  _IGNORE(clutter_stage_queue_redraw)
};

} // namespace Clutter

//vim: ts=2,sw=2
