/*
 * This file is part of GNAC - Gnome Audio Converter
 *
 * Copyright (C) 2007 - 2012 Gnac
 *    
 *    - DUPASQUIER  Benoit    <bdupasqu@src.gnome.org>
 *    - JOAQUIM     David     <djoaquim@src.gnome.org>
 *    - ROUX        Alexandre <alexroux@src.gnome.org>
 *
 * GNAC 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; either version 3 of the License, or
 * (at your option) any later version.
 *
 * GNAC 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNAC; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, 
 * Boston, MA  02110-1301  USA
 */

#include <glib/gstdio.h>

#include "../gnac-profiles-properties.h"
#include "gnac-profiles-lame.h"


typedef struct
{
  AudioProfileGeneric *generic;

  gchar   *target;
  gdouble  quality;
  gchar   *bitrate;
  gchar   *mono;
}
AudioProfileLame;

typedef enum {
  QUALITY,
  BITRATE,
} Target;

BasicFormatInfo lame_bfi = {
  PKGDATADIR "/profiles/gnac-profiles-lame.xml",
  NULL,
  PKGDATADIR "/profiles/mp3-lame.xml",
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL
};


static void
gnac_profiles_lame_vbr_on_changed(GtkComboBox *widget);

static AudioProfileLame *
gnac_profiles_lame_audio_profile_new(void);


void
gnac_profiles_lame_on_target_changed(GtkComboBox *widget,
                                            gpointer     user_data)
{
  gnac_profiles_lame_vbr_on_changed(widget);
  gnac_profiles_lame_generate_pipeline();
}


static const gchar *
gnac_profiles_lame_init(void)
{ 
  GtkWidget *widget;

  gnac_profiles_default_init(&lame_bfi);

  // Bitrate
  gnac_profiles_utils_init_widget(&lame_bfi, "combo-bitrate",
      "//variable[@id='bitrate']");
  
  // Quality
  gnac_profiles_utils_init_widget(&lame_bfi, "slider-vbr-quality",
      "//variable[@id='quality']");

  // Mode
  gnac_profiles_utils_init_widget(&lame_bfi, "combo-mono",
      "//variable[@id='mono']");
  
  // Target
  widget = gnac_profiles_utils_init_widget(&lame_bfi, "combo-target",
      "//variable[@id='target']");
 
  gnac_profiles_lame_vbr_on_changed(GTK_COMBO_BOX(widget));

  gnac_profiles_xml_engine_free_doc_xpath(lame_bfi.doc);
  lame_bfi.doc = NULL;

  return lame_bfi.format_id;
}


static void
gnac_profiles_lame_show_cbr_widgets(gboolean show)
{
  GtkWidget *cbr_widgets[] = {
    gnac_profiles_utils_get_widget(&lame_bfi, "label-cbr"),
    gnac_profiles_utils_get_widget(&lame_bfi, "hbox-bitrate"),
  };

  guint i;
  for (i = 0; i < G_N_ELEMENTS(cbr_widgets); i++) {
    if (show) gtk_widget_show_all(cbr_widgets[i]);
    else gtk_widget_hide(cbr_widgets[i]);
  }
}


static void
gnac_profiles_lame_show_vbr_widgets(gboolean show)
{
  GtkWidget *vbr_widgets[] = {
    gnac_profiles_utils_get_widget(&lame_bfi, "label-vbr"),
    gnac_profiles_utils_get_widget(&lame_bfi, "hbox-vbr"),
  };

  guint i;
  for (i = 0; i < G_N_ELEMENTS(vbr_widgets); i++) {
    if (show) gtk_widget_show_all(vbr_widgets[i]);
    else gtk_widget_hide(vbr_widgets[i]);
  }
}


static void
gnac_profiles_lame_vbr_on_changed(GtkComboBox *widget)
{
  Target target = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));

  gnac_profiles_lame_show_cbr_widgets(target == BITRATE);
  gnac_profiles_lame_show_vbr_widgets(target == QUALITY);
}


void
gnac_profiles_lame_generate_pipeline(void)
{
  gchar *pipeline = gnac_profiles_default_generate_pipeline(&lame_bfi);
  GtkWidget *widget = gnac_profiles_utils_get_widget(&lame_bfi,
      "combo-target");
  Target target = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));

  // Mode
  pipeline = gnac_profiles_utils_add_properties(pipeline, &lame_bfi,
      "combo-mono", NULL);
  
  switch (target)
  {
    case BITRATE:
      pipeline = gnac_profiles_utils_add_properties(pipeline, &lame_bfi,
          "combo-target", "combo-bitrate", NULL);
      break;

    case QUALITY:
      pipeline = gnac_profiles_utils_add_properties(pipeline, &lame_bfi,
          "combo-target", NULL);
      pipeline = gnac_profiles_utils_add_properties_slider(pipeline, &lame_bfi, 
          "%.0f", "slider-vbr-quality", NULL);
      break;

    default:
      break;
  }

  pipeline = gnac_profiles_utils_add_pipe(pipeline,
      lame_bfi.pipeline_multiplexers);
  gnac_profiles_properties_update_textbuffer(pipeline);

  g_free(lame_bfi.pipeline);

  lame_bfi.pipeline = pipeline;
}


static void
gnac_profiles_lame_reset_ui(void)
{
  gnac_profiles_default_reset_ui(&lame_bfi);
  gnac_profiles_utils_reset_values(&lame_bfi,
      "combo-mono", "combo-bitrate", "combo-target", "slider-vbr-quality",
      NULL);
}


static void
gnac_profiles_lame_set_fields(gpointer data)
{
  if (!data) {
    gnac_profiles_lame_reset_ui();
    return;
  }

  AudioProfileLame *profile = (AudioProfileLame *) data;
  gnac_profiles_default_init_fields(profile->generic, &lame_bfi);
  gnac_profiles_utils_set_values(&lame_bfi,
      "combo-target", profile->target,
      "combo-mono", profile->mono, NULL);

  if (profile->bitrate)
  {
    gnac_profiles_utils_set_values(&lame_bfi,
        "combo-bitrate", profile->bitrate, NULL);
  }
  else if (profile->quality != -1)
  {
    gnac_profiles_utils_set_values(&lame_bfi,
        "slider-vbr-quality", profile->quality, NULL);
  }
}


static gchar *
gnac_profiles_lame_get_combo_format_name(void)
{
  return gnac_profiles_default_get_combo_format_name(&lame_bfi);
}


static AudioProfileLame *
gnac_profiles_lame_audio_profile_new(void)
{
  AudioProfileLame *profile = g_malloc(sizeof(AudioProfileLame));
  
  profile->target = NULL;
  profile->mono = NULL;
  profile->bitrate = NULL;
  profile->quality = -1;

  return profile;
}


static void
gnac_profiles_lame_free_audio_profile(gpointer data)
{
  if (!data) return;

  AudioProfileLame *profile = (AudioProfileLame *) data;
  gnac_profiles_utils_free_audio_profile_generic(profile->generic); 
  g_free(profile->target);
  g_free(profile->mono);
  g_free(profile->bitrate);
  g_free(profile);
}


static gpointer
gnac_profiles_lame_generate_audio_profile(GError **error)
{
  AudioProfileGeneric *generic = gnac_profiles_default_generate_audio_profile(
      &lame_bfi);
  AudioProfileLame *profile = gnac_profiles_lame_audio_profile_new();
  profile->generic = generic;
  
  gnac_profiles_utils_get_values_and_set(&lame_bfi,
      "combo-target", &profile->target,
      "combo-mono", &profile->mono,
      NULL);

  GtkWidget *widget = gnac_profiles_utils_get_widget(&lame_bfi,
      "combo-target");

  switch (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)))
  {
    case BITRATE:
      gnac_profiles_utils_get_values_and_set(&lame_bfi,
          "combo-bitrate", &profile->bitrate, NULL);
      break;

    case QUALITY:
      gnac_profiles_utils_get_values_and_set(&lame_bfi,
          "slider-vbr-quality", &profile->quality, NULL);
      break;

    default:
      break;
  }

  return profile;
}


static GtkWidget *
gnac_profiles_lame_get_widget(void)
{
  return gnac_profiles_default_get_properties_alignment(&lame_bfi);
}


static void
gnac_profiles_lame_save_profile(gpointer data)
{
  if (!data) return;

  gchar *quality = NULL;
  AudioProfileLame *profile = (AudioProfileLame *) data;
  
  if (profile->quality != -1)
  {
    quality = gnac_profiles_utils_gdouble_to_gchararray(profile->quality);
  }

  XMLDoc *doc = gnac_profiles_default_save_profile(profile->generic, &lame_bfi);
  gnac_profiles_xml_engine_add_values(doc,
      "target", profile->target,
      "bitrate", profile->bitrate,
      "quality", quality,
      "mono", profile->mono,
      NULL);

  gnac_profiles_xml_engine_save_doc(doc, profile->generic->name);

  gnac_profiles_xml_engine_free_doc_xpath(doc);
  g_free(quality);
}


static gpointer
gnac_profiles_lame_load_specific_properties(XMLDoc              *doc,
                                            AudioProfileGeneric *generic)
{
  gchar *quality;
  
  AudioProfileLame *profile = gnac_profiles_lame_audio_profile_new();
  profile->generic = generic;
  gnac_profiles_utils_load_saved_profile(doc,
      "/audio-profile/format-specific/",
      "target", &profile->target,
      "bitrate",  &profile->bitrate,
      "quality",  &quality,
      "mono", &profile->mono,
      NULL);

  if (quality) {
    profile->quality = gnac_profiles_utils_gchararray_to_gdouble(quality);
    g_free(quality);
  }

  return profile;
}


static void
gnac_profiles_lame_clean_up(void)
{
  gnac_profiles_default_clean_up(&lame_bfi);
  gnac_profiles_utils_free_values(&lame_bfi,
      "combo-mono", "combo-bitrate", "combo-target", "slider-vbr-quality",
      NULL);
  gnac_profiles_utils_free_basic_format_info(&lame_bfi);
}


static const gchar *
gnac_profiles_lame_get_plugin_name(void)
{
  return lame_bfi.format_plugin_name;
}


static const gchar *
gnac_profiles_lame_get_description(void)
{
  return lame_bfi.description;
}


FormatModuleFuncs
gnac_profiles_lame_get_funcs(void)
{
  FormatModuleFuncs funcs = {
    gnac_profiles_lame_init,
    gnac_profiles_lame_get_description,
    gnac_profiles_lame_generate_pipeline,
    gnac_profiles_lame_generate_audio_profile,
    gnac_profiles_lame_free_audio_profile,
    gnac_profiles_lame_set_fields,
    gnac_profiles_lame_get_widget,
    gnac_profiles_lame_save_profile,
    gnac_profiles_lame_load_specific_properties,
    gnac_profiles_lame_clean_up,
    NULL,
    gnac_profiles_lame_get_combo_format_name,
    gnac_profiles_lame_get_plugin_name
  };

  return funcs;
}
