/*
 * GStreamer
 *
 * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
 * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2008 Victor Lin <bornstub@gmail.com>
 * Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * Copyright (C) 2013 Juan Manuel Borges Caño <juanmabcmail@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.
 */

 /**
 * SECTION:element-openalsrc
 * @see_also: openalsink
 * @short_description: capture raw audio samples through OpenAL
 *
 * This element captures raw audio samples through OpenAL.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v openalsrc ! audioconvert ! wavenc ! filesink location=stream.wav
 * ]| * will capture sound through OpenAL and encode it to a wav file.
 * |[
 * gst-launch-1.0 openalsrc ! "audio/x-raw,format=S16LE,rate=44100" ! audioconvert ! volume volume=0.25 ! openalsink
 * ]| will capture and play audio through OpenAL.
 * </refsect2>
 */

/*
 * DEV:
 * To get better timing/delay information you may also be interested in this:
 *  http://kcat.strangesoft.net/openal-extensions/SOFT_source_latency.txt
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

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

GST_DEBUG_CATEGORY_EXTERN (openal_debug);
#define GST_CAT_DEFAULT openal_debug

#include "gstopenalsrc.h"

static void gst_openal_src_dispose (GObject * object);
static void gst_openal_src_finalize (GObject * object);
static void gst_openal_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_openal_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstCaps *gst_openal_src_getcaps (GstBaseSrc * basesrc, GstCaps * filter);
static gboolean gst_openal_src_open (GstAudioSrc * audiosrc);
static gboolean gst_openal_src_prepare (GstAudioSrc * audiosrc,
    GstAudioRingBufferSpec * spec);
static gboolean gst_openal_src_unprepare (GstAudioSrc * audiosrc);
static gboolean gst_openal_src_close (GstAudioSrc * audiosrc);
static guint gst_openal_src_read (GstAudioSrc * audiosrc, gpointer data,
    guint length, GstClockTime * timestamp);
static guint gst_openal_src_delay (GstAudioSrc * audiosrc);
static void gst_openal_src_reset (GstAudioSrc * audiosrc);

#define OPENAL_DEFAULT_DEVICE_NAME NULL
#define OPENAL_DEFAULT_DEVICE NULL

#define OPENAL_MIN_RATE 8000
#define OPENAL_MAX_RATE 192000

enum
{
  PROP_0,
  PROP_DEVICE,
  PROP_DEVICE_NAME
};

static GstStaticPadTemplate openalsrc_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (
        /* These caps do not work on my card */
        // "audio/x-adpcm, " "layout = (string) ima, "
        // "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; "
        // "audio/x-alaw, " "rate = (int) [ 1, MAX ], "
        // "channels = (int) 1; "
        // "audio/x-mulaw, " "rate = (int) [ 1, MAX ], "
        // "channels = (int) 1; "
        // "audio/x-raw, " "format = (string) " GST_AUDIO_NE (F64) ", "
        // "rate = (int) [ 1, MAX ], " "channels = (int) 1; "
        // "audio/x-raw, " "format = (string) " GST_AUDIO_NE (F32) ", "
        // "rate = (int) [ 1, MAX ], " "channels = (int) 1; "
        "audio/x-raw, " "format = (string) " GST_AUDIO_NE (S16) ", "
        "rate = (int) [ 1, MAX ], " "channels = (int) 1; "
        /* These caps work wrongly on my card */
        // "audio/x-raw, " "format = (string) " GST_AUDIO_NE (U16) ", "
        // "rate = (int) [ 1, MAX ], " "channels = (int) 1; "
        // "audio/x-raw, " "format = (string) " G_STRINGIFY (S8) ", "
        // "rate = (int) [ 1, MAX ], " "channels = (int) 1"));
        "audio/x-raw, " "format = (string) " G_STRINGIFY (U8) ", "
        "rate = (int) [ 1, MAX ], " "channels = (int) 1")
    );

G_DEFINE_TYPE (GstOpenalSrc, gst_openal_src, GST_TYPE_AUDIO_SRC);

static void
gst_openal_src_dispose (GObject * object)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (object);

  if (openalsrc->probed_caps)
    gst_caps_unref (openalsrc->probed_caps);
  openalsrc->probed_caps = NULL;

  G_OBJECT_CLASS (gst_openal_src_parent_class)->dispose (object);
}

static void
gst_openal_src_class_init (GstOpenalSrcClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
  GstAudioSrcClass *gstaudiosrc_class = (GstAudioSrcClass *) (klass);

  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_openal_src_dispose);
  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_openal_src_finalize);
  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_openal_src_set_property);
  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_openal_src_get_property);

  gst_openal_src_parent_class = g_type_class_peek_parent (klass);

  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_openal_src_getcaps);

  gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_openal_src_open);
  gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_openal_src_prepare);
  gstaudiosrc_class->unprepare = GST_DEBUG_FUNCPTR (gst_openal_src_unprepare);
  gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_openal_src_close);
  gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_openal_src_read);
  gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_openal_src_delay);
  gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_openal_src_reset);

  g_object_class_install_property (gobject_class, PROP_DEVICE,
      g_param_spec_string ("device", "ALCdevice",
          "User device, default device if NULL", OPENAL_DEFAULT_DEVICE,
          G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class, PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "Device name",
          "Human-readable name of the device", OPENAL_DEFAULT_DEVICE_NAME,
          G_PARAM_READABLE));

  gst_element_class_set_static_metadata (gstelement_class,
      "OpenAL Audio Source", "Source/Audio", "Input audio through OpenAL",
      "Juan Manuel Borges Caño <juanmabcmail@gmail.com>");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&openalsrc_factory));
}

static void
gst_openal_src_init (GstOpenalSrc * openalsrc)
{
  GST_DEBUG_OBJECT (openalsrc, "initializing");

  openalsrc->default_device_name = g_strdup (OPENAL_DEFAULT_DEVICE_NAME);
  openalsrc->default_device = OPENAL_DEFAULT_DEVICE;
  openalsrc->device = NULL;

  openalsrc->buffer_length = 0;

  openalsrc->probed_caps = NULL;
}

static void
gst_openal_src_finalize (GObject * object)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (object);

  g_free (openalsrc->default_device_name);
  g_free (openalsrc->default_device);

  G_OBJECT_CLASS (gst_openal_src_parent_class)->finalize (object);
}

static void
gst_openal_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (object);

  switch (prop_id) {
    case PROP_DEVICE:
      openalsrc->default_device = g_value_dup_string (value);
      break;
    case PROP_DEVICE_NAME:
      openalsrc->default_device_name = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_openal_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (object);

  switch (prop_id) {
    case PROP_DEVICE:
      g_value_set_string (value, openalsrc->default_device);
      break;
    case PROP_DEVICE_NAME:
      g_value_set_string (value, openalsrc->default_device_name);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstCaps *
gst_openal_helper_probe_caps (ALCcontext * context)
{
  GstStructure *structure;
  GstCaps *caps;
//  ALCcontext *old;

//  old = pushContext(context);

  caps = gst_caps_new_empty ();

  if (alIsExtensionPresent ("AL_EXT_DOUBLE")) {
    structure =
        gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
        GST_AUDIO_NE (F64), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
        OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_FLOAT32")) {
    structure =
        gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
        GST_AUDIO_NE (F32), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
        OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
    gst_caps_append_structure (caps, structure);
  }

  structure =
      gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
      GST_AUDIO_NE (S16), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
      OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
  gst_caps_append_structure (caps, structure);

  structure =
      gst_structure_new ("audio/x-raw", "format", G_TYPE_STRING,
      G_STRINGIFY (U8), "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE,
      OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
  gst_caps_append_structure (caps, structure);

  if (alIsExtensionPresent ("AL_EXT_IMA4")) {
    structure =
        gst_structure_new ("audio/x-adpcm", "layout", G_TYPE_STRING, "ima",
        "rate", GST_TYPE_INT_RANGE, OPENAL_MIN_RATE, OPENAL_MAX_RATE,
        "channels", G_TYPE_INT, 1, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_ALAW")) {
    structure =
        gst_structure_new ("audio/x-alaw", "rate", GST_TYPE_INT_RANGE,
        OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
    gst_caps_append_structure (caps, structure);
  }

  if (alIsExtensionPresent ("AL_EXT_MULAW")) {
    structure =
        gst_structure_new ("audio/x-mulaw", "rate", GST_TYPE_INT_RANGE,
        OPENAL_MIN_RATE, OPENAL_MAX_RATE, "channels", G_TYPE_INT, 1, NULL);
    gst_caps_append_structure (caps, structure);
  }
//  popContext(old, context);

  return caps;
}

static GstCaps *
gst_openal_src_getcaps (GstBaseSrc * basesrc, GstCaps * filter)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (basesrc);
  GstCaps *caps;
  ALCdevice *device;

  device = alcOpenDevice (NULL);

  if (device == NULL) {
    GstPad *pad = GST_BASE_SRC_PAD (basesrc);
    GstCaps *tcaps = gst_pad_get_pad_template_caps (pad);

    GST_ELEMENT_WARNING (openalsrc, RESOURCE, OPEN_WRITE,
        ("Could not open temporary device."), GST_ALC_ERROR (device));
    caps = gst_caps_copy (tcaps);
    gst_caps_unref (tcaps);
  } else if (openalsrc->probed_caps)
    caps = gst_caps_copy (openalsrc->probed_caps);
  else {
    ALCcontext *context = alcCreateContext (device, NULL);
    if (context) {
      caps = gst_openal_helper_probe_caps (context);
      alcDestroyContext (context);
    } else {
      GST_ELEMENT_WARNING (openalsrc, RESOURCE, FAILED,
          ("Could not create temporary context."), GST_ALC_ERROR (device));
      caps = NULL;
    }

    if (caps && !gst_caps_is_empty (caps))
      openalsrc->probed_caps = gst_caps_copy (caps);
  }

  if (device != NULL) {
    if (alcCloseDevice (device) == ALC_FALSE) {
      GST_ELEMENT_WARNING (openalsrc, RESOURCE, CLOSE,
          ("Could not close temporary device."), GST_ALC_ERROR (device));
    }
  }

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    return intersection;
  } else {
    return caps;
  }
}


static gboolean
gst_openal_src_open (GstAudioSrc * audiosrc)
{
  return TRUE;
}

static void
gst_openal_src_parse_spec (GstOpenalSrc * openalsrc,
    const GstAudioRingBufferSpec * spec)
{
  ALuint format = AL_NONE;

  GST_DEBUG_OBJECT (openalsrc,
      "looking up format for type %d, gst-format %d, and %d channels",
      spec->type, GST_AUDIO_INFO_FORMAT (&spec->info),
      GST_AUDIO_INFO_CHANNELS (&spec->info));

  switch (spec->type) {
    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_RAW:
      switch (GST_AUDIO_INFO_FORMAT (&spec->info)) {
        case GST_AUDIO_FORMAT_U8:
          switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
            case 1:
              format = AL_FORMAT_MONO8;
              break;
            default:
              break;
          }
          break;

        case GST_AUDIO_FORMAT_U16:
        case GST_AUDIO_FORMAT_S16:
          switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
            case 1:
              format = AL_FORMAT_MONO16;
              break;
            default:
              break;
          }
          break;

        case GST_AUDIO_FORMAT_F32:
          switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
            case 1:
              format = AL_FORMAT_MONO_FLOAT32;
              break;
            default:
              break;
          }
          break;

        case GST_AUDIO_FORMAT_F64:
          switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
            case 1:
              format = AL_FORMAT_MONO_DOUBLE_EXT;
              break;
            default:
              break;
          }
          break;

        default:
          break;
      }
      break;

    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_IMA_ADPCM:
      switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
        case 1:
          format = AL_FORMAT_MONO_IMA4;
          break;
        default:
          break;
      }
      break;

    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW:
      switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
        case 1:
          format = AL_FORMAT_MONO_ALAW_EXT;
          break;
        default:
          break;
      }
      break;

    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW:
      switch (GST_AUDIO_INFO_CHANNELS (&spec->info)) {
        case 1:
          format = AL_FORMAT_MONO_MULAW;
          break;
        default:
          break;
      }
      break;

    default:
      break;
  }

  openalsrc->bytes_per_sample = GST_AUDIO_INFO_BPS (&spec->info);
  openalsrc->rate = GST_AUDIO_INFO_RATE (&spec->info);
  openalsrc->buffer_length = spec->segsize;
  openalsrc->format = format;
}

static gboolean
gst_openal_src_prepare (GstAudioSrc * audiosrc, GstAudioRingBufferSpec * spec)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc);

  gst_openal_src_parse_spec (openalsrc, spec);
  if (openalsrc->format == AL_NONE) {
    GST_ELEMENT_ERROR (openalsrc, RESOURCE, SETTINGS, (NULL),
        ("Unable to get type %d, format %d, and %d channels", spec->type,
            GST_AUDIO_INFO_FORMAT (&spec->info),
            GST_AUDIO_INFO_CHANNELS (&spec->info)));
    return FALSE;
  }

  openalsrc->device =
      alcCaptureOpenDevice (openalsrc->default_device, openalsrc->rate,
      openalsrc->format, openalsrc->buffer_length);

  if (!openalsrc->device) {
    GST_ELEMENT_ERROR (openalsrc, RESOURCE, OPEN_READ,
        ("Could not open device."), GST_ALC_ERROR (openalsrc->device));
    return FALSE;
  }

  openalsrc->default_device_name =
      g_strdup (alcGetString (openalsrc->device, ALC_DEVICE_SPECIFIER));

  alcCaptureStart (openalsrc->device);

  return TRUE;
}

static gboolean
gst_openal_src_unprepare (GstAudioSrc * audiosrc)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc);

  if (openalsrc->device) {
    alcCaptureStop (openalsrc->device);

    if (alcCaptureCloseDevice (openalsrc->device) == ALC_FALSE) {
      GST_ELEMENT_ERROR (openalsrc, RESOURCE, CLOSE,
          ("Could not close device."), GST_ALC_ERROR (openalsrc->device));
      return FALSE;
    }
  }

  return TRUE;
}

static gboolean
gst_openal_src_close (GstAudioSrc * audiosrc)
{
  return TRUE;
}

static guint
gst_openal_src_read (GstAudioSrc * audiosrc, gpointer data, guint length,
    GstClockTime * timestamp)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc);
  gint samples;

  alcGetIntegerv (openalsrc->device, ALC_CAPTURE_SAMPLES, sizeof (samples),
      &samples);

  if (samples * openalsrc->bytes_per_sample > length) {
    samples = length / openalsrc->bytes_per_sample;
  }

  if (samples) {
    GST_DEBUG_OBJECT (openalsrc, "read samples : %d", samples);
    alcCaptureSamples (openalsrc->device, data, samples);
  }

  return samples * openalsrc->bytes_per_sample;
}

static guint
gst_openal_src_delay (GstAudioSrc * audiosrc)
{
  GstOpenalSrc *openalsrc = GST_OPENAL_SRC (audiosrc);
  ALint samples;

  alcGetIntegerv (openalsrc->device, ALC_CAPTURE_SAMPLES, sizeof (samples),
      &samples);

  if (G_UNLIKELY (samples < 0)) {
    /* make sure we never return a negative delay */
    GST_WARNING_OBJECT (openal_debug, "negative delay");
    samples = 0;
  }

  return samples;
}

static void
gst_openal_src_reset (GstAudioSrc * audiosrc)
{
}
