/* poppler-layer.cc: glib interface to poppler
 *
 * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
 *
 * 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, 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "poppler-layer.h"
#include "poppler-private.h"

typedef struct _PopplerLayerClass PopplerLayerClass;
struct _PopplerLayerClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerLayer, poppler_layer, G_TYPE_OBJECT)

static void
poppler_layer_finalize (GObject *object)
{
  PopplerLayer *poppler_layer = POPPLER_LAYER (object);

  if (poppler_layer->document)
    {
      g_object_unref (poppler_layer->document);
      poppler_layer->document = NULL;
    }

  if (poppler_layer->title)
    {
      g_free (poppler_layer->title);
      poppler_layer->title = NULL;
    }
  poppler_layer->layer = NULL;
  poppler_layer->rbgroup = NULL;

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

static void
poppler_layer_init (PopplerLayer *layer)
{
}

static void
poppler_layer_class_init (PopplerLayerClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_layer_finalize;
}

PopplerLayer *
_poppler_layer_new (PopplerDocument *document,
		    Layer           *layer,
		    GList           *rbgroup)
{
  PopplerLayer *poppler_layer;
  GooString    *layer_name;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
  g_return_val_if_fail (layer != NULL, NULL);

  poppler_layer = POPPLER_LAYER (g_object_new (POPPLER_TYPE_LAYER, NULL));

  poppler_layer->document = (PopplerDocument *)g_object_ref (document);
  poppler_layer->layer = layer;
  poppler_layer->rbgroup = rbgroup;
  layer_name = layer->oc->getName ();
  poppler_layer->title = layer_name ? _poppler_goo_string_to_utf8 (layer_name) : NULL;
  
  return poppler_layer;
}

/**
 * poppler_layer_get_title
 * @layer: a #PopplerLayer
 *
 * Returns the name of the layer suitable for
 * presentation as a title in a viewer's GUI
 *
 * Return value: a string containing the title of the layer
 **/
const gchar *
poppler_layer_get_title (PopplerLayer *poppler_layer)
{
  g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), NULL);

  return poppler_layer->title;
}

/**
 * poppler_layer_is_visible
 * @layer: a #PopplerLayer
 *
 * Returns whether @layer is visible
 *
 * Return value: %TRUE if @layer is visible
 **/
gboolean
poppler_layer_is_visible (PopplerLayer *poppler_layer)
{
  g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);

  return poppler_layer->layer->oc->getState () == OptionalContentGroup::On;
}

/**
 * poppler_layer_show
 * @layer: a #PopplerLayer
 *
 * Shows @layer
 **/
void
poppler_layer_show (PopplerLayer *poppler_layer)
{
  GList *l;
  Layer *layer;
  
  g_return_if_fail (POPPLER_IS_LAYER (poppler_layer));

  layer = poppler_layer->layer;

  if (layer->oc->getState () == OptionalContentGroup::On)
    return;
  
  layer->oc->setState (OptionalContentGroup::On);
  
  for (l = poppler_layer->rbgroup; l && l->data; l = g_list_next (l)) {
    OptionalContentGroup *oc = (OptionalContentGroup *)l->data;

    if (oc != layer->oc)
      oc->setState (OptionalContentGroup::Off);
  }
}

/**
 * poppler_layer_hide
 * @layer: a #PopplerLayer
 *
 * Hides @layer. If @layer is the parent of other nested layers,
 * such layers will be also hidden and will be blocked until @layer
 * is shown again
 **/
void
poppler_layer_hide (PopplerLayer *poppler_layer)
{
  Layer *layer;
  
  g_return_if_fail (POPPLER_IS_LAYER (poppler_layer));

  layer = poppler_layer->layer;
  
  if (layer->oc->getState () == OptionalContentGroup::Off)
    return;
  
  layer->oc->setState (OptionalContentGroup::Off);
}


/**
 * poppler_layer_is_parent
 * @layer: a #PopplerLayer
 *
 * Returns whether @layer is parent of other nested layers.
 *
 * Return value: %TRUE if @layer is a parent layer
 **/
gboolean
poppler_layer_is_parent (PopplerLayer *poppler_layer)
{
  g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);

  return poppler_layer->layer->kids != NULL;
}

/**
 * poppler_layer_get_radio_button_group_id
 * @layer: a #PopplerLayer
 *
 * Returns the numeric ID the radio button group associated with @layer.
 *
 * Return value: the ID of the radio button group associated with @layer,
 * or 0 if the layer is not associated to any radio button group
 **/
gint 
poppler_layer_get_radio_button_group_id (PopplerLayer *poppler_layer)
{
  g_return_val_if_fail (POPPLER_IS_LAYER (poppler_layer), FALSE);

  return GPOINTER_TO_INT (poppler_layer->rbgroup);
}
