/* OGMRip - A library for DVD ripping and encoding
 * Copyright (C) 2004-2012 Olivier Rolland <billl@users.sourceforge.net>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

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

#include <glib/gi18n.h>
#include <glade/glade.h>

#include "ogmrip-helper.h"
#include "ogmrip-lavc.h"
#include "ogmrip-lavc-mpeg4.h"
#include "ogmrip-options-plugin.h"
#include "ogmrip-plugin.h"
#include "ogmrip-settings.h"

#define OGMRIP_GLADE_FILE "ogmrip/ogmrip-lavc.glade"
#define OGMRIP_GLADE_ROOT "root"

#define OGMRIP_TYPE_LAVC_DIALOG          (ogmrip_lavc_dialog_get_type ())
#define OGMRIP_LAVC_DIALOG(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), OGMRIP_TYPE_LAVC_DIALOG, OGMRipLavcDialog))
#define OGMRIP_LAVC_DIALOG_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), OGMRIP_TYPE_LAVC_DIALOG, OGMRipLavcDialogClass))
#define OGMRIP_IS_LAVC_DIALOG(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OGMRIP_TYPE_LAVC_DIALOG))
#define OGMRIP_IS_LAVC_DIALOG_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), OGMRIP_TYPE_LAVC_DIALOG))

#define OGMRIP_LAVC_KEY_CMP         OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_CMP
#define OGMRIP_LAVC_KEY_PRECMP      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_PRECMP
#define OGMRIP_LAVC_KEY_SUBCMP      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_SUBCMP
#define OGMRIP_LAVC_KEY_DIA         OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_DIA
#define OGMRIP_LAVC_KEY_PREDIA      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_PREDIA
#define OGMRIP_LAVC_KEY_KEYINT      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_KEYINT
#define OGMRIP_LAVC_KEY_BUF_SIZE    OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_BUF_SIZE
#define OGMRIP_LAVC_KEY_MIN_RATE    OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_MIN_RATE
#define OGMRIP_LAVC_KEY_MAX_RATE    OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_MAX_RATE
#define OGMRIP_LAVC_KEY_STRICT      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_STRICT
#define OGMRIP_LAVC_KEY_DC          OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_DC
#define OGMRIP_LAVC_KEY_MBD         OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_MBD
#define OGMRIP_LAVC_KEY_QNS         OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_QNS
#define OGMRIP_LAVC_KEY_VB_STRATEGY OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_VB_STRATEGY
#define OGMRIP_LAVC_KEY_LAST_PRED   OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_LAST_PRED
#define OGMRIP_LAVC_KEY_PREME       OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_PREME
#define OGMRIP_LAVC_KEY_VQCOMP      OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_VQCOMP
#define OGMRIP_LAVC_KEY_MV0         OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_MV0
#define OGMRIP_LAVC_KEY_V4MV        OGMRIP_LAVC_SECTION "/" OGMRIP_LAVC_PROP_V4MV

typedef struct _OGMRipLavcDialog      OGMRipLavcDialog;
typedef struct _OGMRipLavcDialogClass OGMRipLavcDialogClass;

struct _OGMRipLavcDialog
{
  OGMRipPluginDialog parent_instance;

  GtkWidget *mv0_check;
  GtkWidget *v4mv_check;

  GtkWidget *mbd_combo;
  GtkWidget *strict_combo;
  GtkWidget *vb_strategy_combo;
  GtkWidget *qns_combo;
  GtkWidget *keyint_spin;
  GtkWidget *last_pred_spin;
  GtkWidget *vqcomp_spin;
  GtkWidget *dc_spin;

  GtkWidget *preme_combo;
  GtkWidget *cmp_spin;
  GtkWidget *precmp_spin;
  GtkWidget *subcmp_spin;
  GtkWidget *dia_spin;
  GtkWidget *predia_spin;

  GtkWidget *buf_size_spin;
  GtkWidget *min_rate_spin;
  GtkWidget *max_rate_spin;
};

struct _OGMRipLavcDialogClass
{
  OGMRipPluginDialogClass parent_class;
};

static void ogmrip_lavc_dialog_set_section (OGMRipPluginDialog *dialog,
                                            const gchar        *section);

G_DEFINE_TYPE (OGMRipLavcDialog, ogmrip_lavc_dialog, OGMRIP_TYPE_PLUGIN_DIALOG)

static void
ogmrip_lavc_dialog_class_init (OGMRipLavcDialogClass *klass)
{
  OGMRipPluginDialogClass *dialog_class;

  dialog_class = (OGMRipPluginDialogClass *) klass;
  dialog_class->set_section = ogmrip_lavc_dialog_set_section;
}

static void
ogmrip_lavc_dialog_init (OGMRipLavcDialog *dialog)
{
  GtkWidget *area, *widget;
  GladeXML *xml;

  xml = glade_xml_new (OGMRIP_DATA_DIR "/" OGMRIP_GLADE_FILE, OGMRIP_GLADE_ROOT, NULL);
  if (!xml)
  {
    g_warning ("Could not find " OGMRIP_GLADE_FILE);
    return;
  }

  gtk_dialog_add_buttons (GTK_DIALOG (dialog),
      GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
      NULL);
  gtk_window_set_title (GTK_WINDOW (dialog), _("Lavc Options"));
  gtk_window_set_icon_from_stock (GTK_WINDOW (dialog), GTK_STOCK_PREFERENCES);

  area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

  widget = glade_xml_get_widget (xml, OGMRIP_GLADE_ROOT);
  gtk_container_add (GTK_CONTAINER (area), widget);
  gtk_widget_show (widget);

  dialog->mv0_check = glade_xml_get_widget (xml, "mv0-check");
  dialog->v4mv_check = glade_xml_get_widget (xml, "v4mv-check");

  dialog->mbd_combo = glade_xml_get_widget (xml, "mbd-combo");
  dialog->strict_combo = glade_xml_get_widget (xml, "strict-combo");
  dialog->vb_strategy_combo = glade_xml_get_widget (xml, "vb_strategy-combo");
  dialog->qns_combo = glade_xml_get_widget (xml, "qns-combo");
  dialog->keyint_spin = glade_xml_get_widget (xml, "keyint-spin");
  dialog->last_pred_spin = glade_xml_get_widget (xml, "last_pred-spin");
  dialog->vqcomp_spin = glade_xml_get_widget (xml, "vqcomp-spin");
  dialog->dc_spin = glade_xml_get_widget (xml, "dc-spin");

  dialog->preme_combo = glade_xml_get_widget (xml, "preme-combo");
  dialog->cmp_spin = glade_xml_get_widget (xml, "cmp-spin");
  dialog->precmp_spin = glade_xml_get_widget (xml, "precmp-spin");
  dialog->subcmp_spin = glade_xml_get_widget (xml, "subcmp-spin");
  dialog->dia_spin = glade_xml_get_widget (xml, "dia-spin");
  dialog->predia_spin = glade_xml_get_widget (xml, "predia-spin");

  dialog->buf_size_spin = glade_xml_get_widget (xml, "buf_size-spin");
  dialog->min_rate_spin = glade_xml_get_widget (xml, "min_rate-spin");
  dialog->max_rate_spin = glade_xml_get_widget (xml, "max_rate-spin");

  g_object_unref (xml);
}

static void
ogmrip_lavc_dialog_set_section (OGMRipPluginDialog *plugin_dialog, const gchar *section)
{
  OGMRipSettings *settings;

  settings = ogmrip_settings_get_default ();
  if (settings)
  {
    OGMRipLavcDialog *dialog;

    dialog = OGMRIP_LAVC_DIALOG (plugin_dialog);

    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_MV0, G_OBJECT (dialog->mv0_check), "active");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_V4MV, G_OBJECT (dialog->v4mv_check), "active");

    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_MBD, G_OBJECT (dialog->mbd_combo), "active");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_STRICT, G_OBJECT (dialog->strict_combo), "active");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_VB_STRATEGY, G_OBJECT (dialog->vb_strategy_combo), "active");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_QNS, G_OBJECT (dialog->qns_combo), "active");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_PREME, G_OBJECT (dialog->preme_combo), "active");

    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_KEYINT, G_OBJECT (dialog->keyint_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_DC, G_OBJECT (dialog->dc_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_LAST_PRED, G_OBJECT (dialog->last_pred_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_VQCOMP, G_OBJECT (dialog->vqcomp_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_CMP, G_OBJECT (dialog->cmp_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_PRECMP, G_OBJECT (dialog->precmp_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_SUBCMP, G_OBJECT (dialog->subcmp_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_DIA, G_OBJECT (dialog->dia_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_PREDIA, G_OBJECT (dialog->predia_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_BUF_SIZE, G_OBJECT (dialog->buf_size_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_MIN_RATE, G_OBJECT (dialog->min_rate_spin), "value");
    ogmrip_settings_bind (settings, section,
        OGMRIP_LAVC_KEY_MAX_RATE, G_OBJECT (dialog->max_rate_spin), "value");
  }
}

static OGMRipVideoOptionsPlugin lavc_options_plugin =
{
  NULL,
  G_TYPE_NONE,
  G_TYPE_NONE
};

OGMRipVideoOptionsPlugin *
ogmrip_init_options_plugin (void)
{
  lavc_options_plugin.type = OGMRIP_TYPE_LAVC;
  lavc_options_plugin.dialog = OGMRIP_TYPE_LAVC_DIALOG;

  return &lavc_options_plugin;
}

