/*
 * GStreamer
 * Copyright (C) 2008 Julien Isorce <julien.isorce@gmail.com>
 * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#define GLIB_DISABLE_DEPRECATION_WARNINGS

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst.h>
#include <locale.h>

#include "gstglwindow_x11.h"
#include "gstgldisplay_x11.h"
/* for XkbKeycodeToKeysym */
#include <X11/XKBlib.h>

#define GST_GL_WINDOW_X11_GET_PRIVATE(o)  \
  (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_WINDOW_X11, GstGLWindowX11Private))

#define GST_CAT_DEFAULT gst_gl_window_debug

#define gst_gl_window_x11_parent_class parent_class
G_DEFINE_TYPE (GstGLWindowX11, gst_gl_window_x11, GST_TYPE_GL_WINDOW);

gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11,
    xcb_generic_event_t * event);

/* X error trap */
static int TrappedErrorCode = 0;
static int (*old_error_handler) (Display *, XErrorEvent *);

enum
{
  ARG_0,
  ARG_DISPLAY
};

struct _GstGLWindowX11Private
{
  gboolean activate;
  gboolean activate_result;

  gint preferred_width;
  gint preferred_height;

  gboolean handle_events;
};

guintptr gst_gl_window_x11_get_display (GstGLWindow * window);
guintptr gst_gl_window_x11_get_gl_context (GstGLWindow * window);
gboolean gst_gl_window_x11_activate (GstGLWindow * window, gboolean activate);
void gst_gl_window_x11_set_window_handle (GstGLWindow * window,
    guintptr handle);
guintptr gst_gl_window_x11_get_window_handle (GstGLWindow * window);
static void gst_gl_window_x11_set_preferred_size (GstGLWindow * window,
    gint width, gint height);
void gst_gl_window_x11_show (GstGLWindow * window);
void gst_gl_window_x11_draw (GstGLWindow * window);
gboolean gst_gl_window_x11_create_context (GstGLWindow * window,
    GstGLAPI gl_api, guintptr external_gl_context, GError ** error);
gboolean gst_gl_window_x11_open (GstGLWindow * window, GError ** error);
void gst_gl_window_x11_close (GstGLWindow * window);
void gst_gl_window_x11_handle_events (GstGLWindow * window,
    gboolean handle_events);

static void
gst_gl_window_x11_finalize (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_gl_window_x11_class_init (GstGLWindowX11Class * klass)
{
  GObjectClass *obj_class = G_OBJECT_CLASS (klass);
  GstGLWindowClass *window_class = (GstGLWindowClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGLWindowX11Private));

  obj_class->finalize = gst_gl_window_x11_finalize;

  window_class->get_display = GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_display);
  window_class->set_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_x11_set_window_handle);
  window_class->get_window_handle =
      GST_DEBUG_FUNCPTR (gst_gl_window_x11_get_window_handle);
  window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_window_x11_draw);
  window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_x11_open);
  window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_x11_close);
  window_class->handle_events =
      GST_DEBUG_FUNCPTR (gst_gl_window_x11_handle_events);
  window_class->set_preferred_size =
      GST_DEBUG_FUNCPTR (gst_gl_window_x11_set_preferred_size);
  window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_x11_show);
}

static void
gst_gl_window_x11_init (GstGLWindowX11 * window)
{
  window->priv = GST_GL_WINDOW_X11_GET_PRIVATE (window);
}

/* Must be called in the gl thread */
GstGLWindowX11 *
gst_gl_window_x11_new (GstGLDisplay * display)
{
  if ((gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_X11)
      == GST_GL_DISPLAY_TYPE_NONE) {
    GST_INFO ("Wrong display type %u for this window type %u", display->type,
        GST_GL_DISPLAY_TYPE_X11);
    return NULL;
  }

  return g_object_new (GST_TYPE_GL_WINDOW_X11, NULL);
}

gboolean
gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
{
  GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
  GstGLDisplayX11 *display_x11 = (GstGLDisplayX11 *) window->display;

  window_x11->device = display_x11->display;
//  window_x11->device = XOpenDisplay (display_x11->name);
  if (window_x11->device == NULL) {
    g_set_error (error, GST_GL_WINDOW_ERROR,
        GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
        "Failed to connect to X display server");
    goto failure;
  }

  GST_LOG ("gl device id: %ld", (gulong) window_x11->device);

  window_x11->screen = DefaultScreenOfDisplay (window_x11->device);
  window_x11->screen_num = DefaultScreen (window_x11->device);
  window_x11->visual =
      DefaultVisual (window_x11->device, window_x11->screen_num);
  window_x11->root = DefaultRootWindow (window_x11->device);
  window_x11->white = XWhitePixel (window_x11->device, window_x11->screen_num);
  window_x11->black = XBlackPixel (window_x11->device, window_x11->screen_num);
  window_x11->depth = DefaultDepthOfScreen (window_x11->screen);

  GST_LOG ("gl root id: %lud", (gulong) window_x11->root);

  window_x11->device_width =
      DisplayWidth (window_x11->device, window_x11->screen_num);
  window_x11->device_height =
      DisplayHeight (window_x11->device, window_x11->screen_num);

  window_x11->allow_extra_expose_events = TRUE;

  return GST_GL_WINDOW_CLASS (parent_class)->open (window, error);

failure:
  return FALSE;
}

gboolean
gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11)
{
  XSetWindowAttributes win_attr;
  XTextProperty text_property;
  XWMHints wm_hints;
  unsigned long mask;
  const gchar *title = "OpenGL renderer";
  Atom wm_atoms[1];
  gint x = 0, y = 0, width = 1, height = 1;

  if (window_x11->visual_info->visual != window_x11->visual)
    GST_LOG ("selected visual is different from the default");

  GST_LOG ("visual XID:%d, screen:%d, visualid:%d, depth:%d, class:%d, "
      "red_mask:%ld, green_mask:%ld, blue_mask:%ld bpp:%d",
      (gint) XVisualIDFromVisual (window_x11->visual_info->visual),
      window_x11->visual_info->screen, (gint) window_x11->visual_info->visualid,
      window_x11->visual_info->depth, window_x11->visual_info->class,
      window_x11->visual_info->red_mask, window_x11->visual_info->green_mask,
      window_x11->visual_info->blue_mask,
      window_x11->visual_info->bits_per_rgb);

  win_attr.event_mask =
      StructureNotifyMask | ExposureMask | VisibilityChangeMask;
  win_attr.do_not_propagate_mask = NoEventMask;

  win_attr.background_pixmap = None;
  win_attr.background_pixel = 0;
  win_attr.border_pixel = 0;

  win_attr.colormap =
      XCreateColormap (window_x11->device, window_x11->root,
      window_x11->visual_info->visual, AllocNone);

  mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;

  window_x11->internal_win_id =
      XCreateWindow (window_x11->device,
      window_x11->parent_win ? window_x11->parent_win : window_x11->root,
      x, y, width, height, 0,
      window_x11->visual_info->depth, InputOutput,
      window_x11->visual_info->visual, mask, &win_attr);

  gst_gl_window_x11_handle_events (GST_GL_WINDOW (window_x11),
      window_x11->priv->handle_events);

  XSync (window_x11->device, FALSE);

  XSetWindowBackgroundPixmap (window_x11->device,
      window_x11->internal_win_id, None);

  GST_LOG ("gl window id: %lud", (gulong) window_x11->internal_win_id);
  GST_LOG ("gl window props: x:%d y:%d", x, y);

  wm_atoms[0] = XInternAtom (window_x11->device, "WM_DELETE_WINDOW", True);
  if (wm_atoms[0] == None)
    GST_DEBUG ("Cannot create WM_DELETE_WINDOW");

  XSetWMProtocols (window_x11->device, window_x11->internal_win_id,
      wm_atoms, 1);

  wm_hints.flags = StateHint;
  wm_hints.initial_state = NormalState;
  wm_hints.input = False;

  XStringListToTextProperty ((char **) &title, 1, &text_property);

  XSetWMProperties (window_x11->device, window_x11->internal_win_id,
      &text_property, &text_property, 0, 0, NULL, &wm_hints, NULL);

  XFree (text_property.value);

  return TRUE;
}

void
gst_gl_window_x11_close (GstGLWindow * window)
{
  GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);

  if (window_x11->device) {
    if (window_x11->internal_win_id) {
      XUnmapWindow (window_x11->device, window_x11->internal_win_id);

      XDestroyWindow (window_x11->device, window_x11->internal_win_id);
    }
    XFree (window_x11->visual_info);

    GST_DEBUG ("display receiver closed");
  }

  window_x11->running = FALSE;

  GST_GL_WINDOW_CLASS (parent_class)->close (window);
}

/* called by the gl thread */
void
gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
{
  GstGLWindowX11 *window_x11;
  gint width, height;

  window_x11 = GST_GL_WINDOW_X11 (window);

  window_x11->parent_win = (Window) id;

  if (window_x11->parent_win) {
    XWindowAttributes attr;

    XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr);
    width = attr.width;
    height = attr.height;
  } else {
    width = window_x11->priv->preferred_width;
    height = window_x11->priv->preferred_height;
  }

  XResizeWindow (window_x11->device, window_x11->internal_win_id,
      width, height);

  XReparentWindow (window_x11->device, window_x11->internal_win_id,
      window_x11->parent_win, 0, 0);

  XSync (window_x11->device, FALSE);
}

guintptr
gst_gl_window_x11_get_window_handle (GstGLWindow * window)
{
  GstGLWindowX11 *window_x11;

  window_x11 = GST_GL_WINDOW_X11 (window);

  return window_x11->internal_win_id;
}

static void
gst_gl_window_x11_set_preferred_size (GstGLWindow * window, gint width,
    gint height)
{
  GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);

  window_x11->priv->preferred_width = width;
  window_x11->priv->preferred_height = height;
}

static void
_show_window (GstGLWindow * window)
{
  GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
  guint width = window_x11->priv->preferred_width;
  guint height = window_x11->priv->preferred_height;

  if (!window_x11->visible) {
    if (!window_x11->parent_win) {
      XResizeWindow (window_x11->device, window_x11->internal_win_id,
          width, height);
    }

    XMapWindow (window_x11->device, window_x11->internal_win_id);
    XSync (window_x11->device, FALSE);
    window_x11->visible = TRUE;
  }
}

void
gst_gl_window_x11_show (GstGLWindow * window)
{
  gst_gl_window_send_message (window, (GstGLWindowCB) _show_window, window);
}

static void
_context_draw (GstGLContext * context, GstGLWindow * window)
{
  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);

  window->draw (window->draw_data);
  context_class->swap_buffers (context);

  gst_object_unref (context);
}

static void
draw_cb (gpointer data)
{
  GstGLWindowX11 *window_x11 = data;
  GstGLWindow *window = GST_GL_WINDOW (window_x11);
  guint width, height;
  XWindowAttributes attr;

  if (window_x11->internal_win_id) {
    XGetWindowAttributes (window_x11->device, window_x11->internal_win_id,
        &attr);
    GST_TRACE_OBJECT (window, "window size %ux%u", attr.width, attr.height);

    if (window_x11->parent_win) {
      XWindowAttributes attr_parent;
      XGetWindowAttributes (window_x11->device, window_x11->parent_win,
          &attr_parent);
      GST_TRACE_OBJECT (window, "parent window size %ux%u", attr_parent.width,
          attr_parent.height);

      if (attr.width != attr_parent.width || attr.height != attr_parent.height) {
        XMoveResizeWindow (window_x11->device, window_x11->internal_win_id,
            0, 0, attr_parent.width, attr_parent.height);
        XSync (window_x11->device, FALSE);

        attr.width = attr_parent.width;
        attr.height = attr_parent.height;

        GST_LOG ("parent resize:  %d, %d",
            attr_parent.width, attr_parent.height);
      }
    }

    gst_gl_window_get_surface_dimensions (window, &width, &height);
    if (attr.width != width || attr.height != height) {
      width = attr.width;
      height = attr.height;
      gst_gl_window_queue_resize (window);
    }

    if (window_x11->allow_extra_expose_events) {
      if (window->queue_resize)
        gst_gl_window_resize (window, width, height);

      if (window->draw) {
        GstGLContext *context = gst_gl_window_get_context (window);

        _context_draw (context, window);
      }
    }
  }
}

/* Not called by the gl thread */
void
gst_gl_window_x11_draw (GstGLWindow * window)
{
  gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window);
}

void
gst_gl_window_x11_handle_events (GstGLWindow * window, gboolean handle_events)
{
  GstGLWindowX11 *window_x11;

  g_return_if_fail (window != NULL);

  window_x11 = GST_GL_WINDOW_X11 (window);

  window_x11->priv->handle_events = handle_events;

  if (window_x11->internal_win_id) {
    if (handle_events) {
      XSelectInput (window_x11->device, window_x11->internal_win_id,
          StructureNotifyMask | ExposureMask | VisibilityChangeMask |
          PointerMotionMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
          ButtonReleaseMask);
    } else {
      XSelectInput (window_x11->device, window_x11->internal_win_id,
          StructureNotifyMask | ExposureMask | VisibilityChangeMask);
    }
  }
}

gboolean
gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11,
    xcb_generic_event_t * event)
{
  GstGLWindow *window = GST_GL_WINDOW (window_x11);
  GstGLDisplayX11 *display_x11 = GST_GL_DISPLAY_X11 (window->display);
  xcb_connection_t *connection = display_x11->xcb_connection;
  uint8_t event_code = event->response_type & 0x7f;

  switch (event_code) {
    case XCB_CLIENT_MESSAGE:{
      xcb_client_message_event_t *client_event;
      xcb_intern_atom_cookie_t cookie;
      xcb_intern_atom_reply_t *reply;

      client_event = (xcb_client_message_event_t *) event;
      cookie = xcb_intern_atom (connection, 0, 16, "WM_DELETE_WINDOW");
      reply = xcb_intern_atom_reply (connection, cookie, 0);

      if (client_event->data.data32[0] == reply->atom) {
        GST_INFO_OBJECT (window_x11, "Close requested");

        if (window->close)
          window->close (window->close_data);

        gst_gl_display_remove_window (GST_GL_DISPLAY (display_x11),
            GST_GL_WINDOW (window_x11));
      }

      g_free (reply);
      break;
    }
    case XCB_CONFIGURE_NOTIFY:{
      xcb_configure_notify_event_t *configure_event;

      configure_event = (xcb_configure_notify_event_t *) event;

      gst_gl_window_resize (window, configure_event->width,
          configure_event->height);

      gst_gl_window_draw (window);
      break;
    }
    case XCB_EXPOSE:{
      xcb_expose_event_t *expose_event = (xcb_expose_event_t *) event;
      /* non-zero means that other Expose follows
       * so just wait for the last one
       * in theory we should not receive non-zero because
       * we have no sub areas here but just in case */
      if (expose_event->count != 0)
        break;

      gst_gl_window_draw (window);
      break;
    }
    case XCB_KEY_PRESS:
    case XCB_KEY_RELEASE:{
      xcb_key_press_event_t *kp = (xcb_key_press_event_t *) event;
      const gchar *event_type_str;
      gchar *key_str;
      KeySym keysym;

      keysym = XkbKeycodeToKeysym (window_x11->device, kp->detail, 0, 0);
      key_str = XKeysymToString (keysym);

      if (event_code == XCB_KEY_PRESS)
        event_type_str = "key-press";
      else
        event_type_str = "key-release";

      gst_gl_window_send_key_event (window, event_type_str, key_str);
      break;
    }
    case XCB_BUTTON_PRESS:
    case XCB_BUTTON_RELEASE:{
      xcb_button_press_event_t *bp = (xcb_button_press_event_t *) event;
      const gchar *event_type_str;

      if (event_code == XCB_BUTTON_PRESS)
        event_type_str = "mouse-button-press";
      else
        event_type_str = "mouse-button-release";

      gst_gl_window_send_mouse_event (window, event_type_str, bp->detail,
          (double) bp->event_x, (double) bp->event_y);
      break;
    }
    case XCB_MOTION_NOTIFY:{
      xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *) event;

      gst_gl_window_send_mouse_event (window, "mouse-move", 0,
          (double) motion->event_x, (double) motion->event_y);
      break;
    }
    default:
      GST_TRACE ("unhandled XCB event: %u", event_code);
      break;
  }

  return TRUE;
}

static int
error_handler (Display * xdpy, XErrorEvent * error)
{
  TrappedErrorCode = error->error_code;
  return 0;
}

/**
 * gst_gl_window_x11_trap_x_errors:
 *
 * Traps every X error until gst_gl_window_x11_untrap_x_errors() is called.
 */
void
gst_gl_window_x11_trap_x_errors (void)
{
  TrappedErrorCode = 0;
  old_error_handler = XSetErrorHandler (error_handler);
}

/**
 * gst_gl_window_x11_untrap_x_errors:
 *
 * Removes the X error trap and returns the current status.
 *
 * Return value: the trapped error code, or 0 for success
 */
gint
gst_gl_window_x11_untrap_x_errors (void)
{
  XSetErrorHandler (old_error_handler);

  return TrappedErrorCode;
}

guintptr
gst_gl_window_x11_get_display (GstGLWindow * window)
{
  GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);

  return (guintptr) window_x11->device;
}
