/* eLectrix - a pdf viewer
 * Copyright (C) 2010, 2011 Martin Linder <mali2297@users.sf.net>
 * 
 * This program 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 2 of the License, or (at your
 * option) any later version.
 * 
 * This program 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 this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
 */
#include "e6x-common.h"
#include "e6x-pref.h"
#include "e6x-scale-selector.h"

#define E6X_SCALE_SELECTOR_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), E6X_TYPE_SCALE_SELECTOR, E6xScaleSelectorPrivate))

struct _E6xScaleSelectorPrivate
{
  E6xDocument *doc;
  GtkWidget *prefix;
  GtkWidget *button;
  GtkObject *adj;
};

/* Standard GObject methods */
G_DEFINE_TYPE (E6xScaleSelector, e6x_scale_selector, GTK_TYPE_HBOX);
static void e6x_scale_selector_class_init (E6xScaleSelectorClass *klass);
static void e6x_scale_selector_init (E6xScaleSelector *selector);
static void e6x_scale_selector_finalize (GObject *object);
static void e6x_scale_selector_dispose (GObject *object);

/* Helpers */
static void e6x_scale_selector_reset (E6xScaleSelector *selector);

/* Callbacks */
static void e6x_scale_selector_doc_changed (E6xDocument *doc, 
                                            E6xScaleSelector *selector);
static void e6x_scale_selector_adj_value_changed (GtkAdjustment *adj,
                                                  E6xDocument *doc);


GtkWidget *
e6x_scale_selector_new ()
{
  return g_object_new (E6X_TYPE_SCALE_SELECTOR, NULL);
}


void 
e6x_scale_selector_set_document (E6xScaleSelector *selector, 
                                 E6xDocument *doc)
{
  E6xScaleSelectorPrivate *priv = E6X_SCALE_SELECTOR_GET_PRIVATE (selector);
  
  if (priv->doc)
  {
    g_signal_handlers_disconnect_by_func (GTK_ADJUSTMENT (priv->adj),
                                          e6x_scale_selector_adj_value_changed,
                                          priv->doc);
    g_signal_handlers_disconnect_by_func (priv->doc,
                                          e6x_scale_selector_doc_changed,
                                          selector);
    g_object_unref (priv->doc);
  }

  priv->doc = doc;
  
  if (priv->doc)
  {
    g_object_ref (priv->doc);

    g_signal_connect (priv->doc, "changed::reload",
                      G_CALLBACK (e6x_scale_selector_doc_changed), 
                      selector);
    g_signal_connect (priv->doc, "changed::scale",
                      G_CALLBACK (e6x_scale_selector_doc_changed), 
                      selector);
    g_signal_connect (priv->doc, "changed::multiple",
                      G_CALLBACK (e6x_scale_selector_doc_changed), 
                      selector);
    g_signal_connect (GTK_ADJUSTMENT (priv->adj), "value-changed",
                      G_CALLBACK (e6x_scale_selector_adj_value_changed), 
                      priv->doc);
  }
  
  e6x_scale_selector_reset (selector);
}


static void
e6x_scale_selector_class_init (E6xScaleSelectorClass *klass)
{
  g_type_class_add_private (klass, sizeof (E6xScaleSelectorPrivate));

  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->dispose = e6x_scale_selector_dispose;
  object_class->finalize = e6x_scale_selector_finalize;
}


static void
e6x_scale_selector_init (E6xScaleSelector *selector)
{
  E6xScaleSelectorPrivate *priv = E6X_SCALE_SELECTOR_GET_PRIVATE (selector);
  
  priv->adj = gtk_adjustment_new (0, 0, 0, 0, 0, 0);
  
  priv->prefix = gtk_label_new_with_mnemonic (_("_Scale"));

  priv->button = gtk_spin_button_new (GTK_ADJUSTMENT (priv->adj), 0.25, 2);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (priv->button), TRUE);
  gtk_label_set_mnemonic_widget (GTK_LABEL (priv->prefix), priv->button);
  
  gtk_box_pack_start (GTK_BOX (selector), priv->prefix, FALSE, FALSE, 0);
  gtk_box_pack_start (GTK_BOX (selector), priv->button, FALSE, FALSE, 5);
  
  gtk_widget_show_all (priv->prefix);
  gtk_widget_show_all (priv->button);
  
  selector->priv = priv;
  
  e6x_scale_selector_reset (selector);
}


static void 
e6x_scale_selector_finalize (GObject *object)
{
  G_OBJECT_CLASS (e6x_scale_selector_parent_class)->finalize (object);
}


static void 
e6x_scale_selector_dispose (GObject *object)
{
  E6xScaleSelectorPrivate *priv = E6X_SCALE_SELECTOR (object)->priv;
  
  priv->prefix = NULL;
  priv->button = NULL;
  priv->adj = NULL;
  e6x_scale_selector_set_document (E6X_SCALE_SELECTOR (object), NULL);
  
  G_OBJECT_CLASS (e6x_scale_selector_parent_class)->dispose (object);
}


static void
e6x_scale_selector_reset (E6xScaleSelector *selector)
{
  E6xScaleSelectorPrivate *priv = selector->priv;
  gdouble val = 1.0, min = 0.25, max = 4.0, step = 0.25;
  GKeyFile *keyfile = e6x_pref_get_keyfile ();

  min = g_key_file_get_double (keyfile, "Zoom", "Min", NULL);
  max = g_key_file_get_double (keyfile, "Zoom", "Max", NULL);
  step = g_key_file_get_double (keyfile, "Zoom", "Step", NULL);
  
  if (priv->doc != NULL)
    val = priv->doc->scale;
  
  if (priv->button != NULL)
    gtk_widget_set_sensitive (priv->button, priv->doc != NULL);

  if (priv->adj != NULL)
    gtk_adjustment_configure (GTK_ADJUSTMENT (priv->adj), 
                              val, min, max, step, 1.0, 0);
}


static void 
e6x_scale_selector_doc_changed (E6xDocument *doc, 
                                E6xScaleSelector *selector)
{
  e6x_scale_selector_reset (selector);
}


static void 
e6x_scale_selector_adj_value_changed (GtkAdjustment *adj, 
                                      E6xDocument *doc)
{
  e6x_document_set_scale (doc, gtk_adjustment_get_value (adj));
}

