/*
 * 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_static_pad_template (gstelement_class,
      &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)
{
}
