/* 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"

/**
 * SECTION:poppler-layer
 * @short_description: Layers
 * @title: PopplerLayer
 */

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 = nullptr;
    }

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

    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;
    const GooString *layer_name;

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

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

    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) : nullptr;

    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
 *
 * Since: 0.12
 **/
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
 *
 * Since: 0.12
 **/
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
 *
 * Since: 0.12
 **/
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
 *
 * Since: 0.12
 **/
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
 *
 * Since: 0.12
 **/
gboolean poppler_layer_is_parent(PopplerLayer *poppler_layer)
{
    g_return_val_if_fail(POPPLER_IS_LAYER(poppler_layer), FALSE);

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

/**
 * 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
 *
 * Since: 0.12
 **/
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);
}
