/* poppler-action.cc: glib wrapper for poppler	      -*- c-basic-offset: 8 -*-
 * Copyright (C) 2005, Red Hat, Inc.
 *
 * 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.h"
#include "poppler-private.h"

/**
 * SECTION:poppler-action
 * @short_description: Action links
 * @title: PopplerAction
 */

G_DEFINE_BOXED_TYPE(PopplerDest, poppler_dest, poppler_dest_copy, poppler_dest_free)

/**
 * poppler_dest_copy:
 * @dest: a #PopplerDest
 *
 * Copies @dest, creating an identical #PopplerDest.
 *
 * Return value: a new destination identical to @dest
 **/
PopplerDest *poppler_dest_copy(PopplerDest *dest)
{
    PopplerDest *new_dest;

    new_dest = g_slice_dup(PopplerDest, dest);

    if (dest->named_dest) {
        new_dest->named_dest = g_strdup(dest->named_dest);
    }

    return new_dest;
}

/**
 * poppler_dest_free:
 * @dest: a #PopplerDest
 *
 * Frees @dest
 **/
void poppler_dest_free(PopplerDest *dest)
{
    if (!dest) {
        return;
    }

    if (dest->named_dest) {
        g_free(dest->named_dest);
    }

    g_slice_free(PopplerDest, dest);
}

static void poppler_action_layer_free(PopplerActionLayer *action_layer)
{
    if (!action_layer) {
        return;
    }

    if (action_layer->layers) {
        g_list_free_full(action_layer->layers, g_object_unref);
        action_layer->layers = nullptr;
    }

    g_slice_free(PopplerActionLayer, action_layer);
}

static PopplerActionLayer *poppler_action_layer_copy(PopplerActionLayer *action_layer)
{
    PopplerActionLayer *retval = g_slice_dup(PopplerActionLayer, action_layer);

    retval->layers = g_list_copy(action_layer->layers);
    for (GList *l = retval->layers; l != nullptr; l = l->next) {
        g_object_ref(l->data);
    }

    return retval;
}

G_DEFINE_BOXED_TYPE(PopplerAction, poppler_action, poppler_action_copy, poppler_action_free)

/**
 * poppler_action_free:
 * @action: a #PopplerAction
 *
 * Frees @action
 **/
void poppler_action_free(PopplerAction *action)
{
    if (action == nullptr) {
        return;
    }

    /* Action specific stuff */
    switch (action->type) {
    case POPPLER_ACTION_GOTO_DEST:
        poppler_dest_free(action->goto_dest.dest);
        break;
    case POPPLER_ACTION_GOTO_REMOTE:
        poppler_dest_free(action->goto_remote.dest);
        g_free(action->goto_remote.file_name);
        break;
    case POPPLER_ACTION_URI:
        g_free(action->uri.uri);
        break;
    case POPPLER_ACTION_LAUNCH:
        g_free(action->launch.file_name);
        g_free(action->launch.params);
        break;
    case POPPLER_ACTION_NAMED:
        g_free(action->named.named_dest);
        break;
    case POPPLER_ACTION_MOVIE:
        if (action->movie.movie) {
            g_object_unref(action->movie.movie);
        }
        break;
    case POPPLER_ACTION_RENDITION:
        if (action->rendition.media) {
            g_object_unref(action->rendition.media);
        }
        break;
    case POPPLER_ACTION_OCG_STATE:
        if (action->ocg_state.state_list) {
            g_list_free_full(action->ocg_state.state_list, (GDestroyNotify)poppler_action_layer_free);
        }
        break;
    case POPPLER_ACTION_JAVASCRIPT:
        if (action->javascript.script) {
            g_free(action->javascript.script);
        }
        break;
    case POPPLER_ACTION_RESET_FORM:
        if (action->reset_form.fields) {
            g_list_free_full(action->reset_form.fields, g_free);
        }
        break;
    default:
        break;
    }

    g_free(action->any.title);
    g_slice_free(PopplerAction, action);
}

/**
 * poppler_action_copy:
 * @action: a #PopplerAction
 *
 * Copies @action, creating an identical #PopplerAction.
 *
 * Return value: a new action identical to @action
 **/
PopplerAction *poppler_action_copy(PopplerAction *action)
{
    PopplerAction *new_action;

    g_return_val_if_fail(action != nullptr, NULL);

    /* Do a straight copy of the memory */
    new_action = g_slice_dup(PopplerAction, action);

    if (action->any.title != nullptr) {
        new_action->any.title = g_strdup(action->any.title);
    }

    switch (action->type) {
    case POPPLER_ACTION_GOTO_DEST:
        new_action->goto_dest.dest = poppler_dest_copy(action->goto_dest.dest);
        break;
    case POPPLER_ACTION_GOTO_REMOTE:
        new_action->goto_remote.dest = poppler_dest_copy(action->goto_remote.dest);
        if (action->goto_remote.file_name) {
            new_action->goto_remote.file_name = g_strdup(action->goto_remote.file_name);
        }
        break;
    case POPPLER_ACTION_URI:
        if (action->uri.uri) {
            new_action->uri.uri = g_strdup(action->uri.uri);
        }
        break;
    case POPPLER_ACTION_LAUNCH:
        if (action->launch.file_name) {
            new_action->launch.file_name = g_strdup(action->launch.file_name);
        }
        if (action->launch.params) {
            new_action->launch.params = g_strdup(action->launch.params);
        }
        break;
    case POPPLER_ACTION_NAMED:
        if (action->named.named_dest) {
            new_action->named.named_dest = g_strdup(action->named.named_dest);
        }
        break;
    case POPPLER_ACTION_MOVIE:
        if (action->movie.movie) {
            new_action->movie.movie = (PopplerMovie *)g_object_ref(action->movie.movie);
        }
        break;
    case POPPLER_ACTION_RENDITION:
        if (action->rendition.media) {
            new_action->rendition.media = (PopplerMedia *)g_object_ref(action->rendition.media);
        }
        break;
    case POPPLER_ACTION_OCG_STATE:
        if (action->ocg_state.state_list) {
            GList *l;
            GList *new_list = nullptr;

            for (l = action->ocg_state.state_list; l; l = g_list_next(l)) {
                PopplerActionLayer *alayer = (PopplerActionLayer *)l->data;
                new_list = g_list_prepend(new_list, poppler_action_layer_copy(alayer));
            }

            new_action->ocg_state.state_list = g_list_reverse(new_list);
        }

        break;
    case POPPLER_ACTION_JAVASCRIPT:
        if (action->javascript.script) {
            new_action->javascript.script = g_strdup(action->javascript.script);
        }
        break;
    case POPPLER_ACTION_RESET_FORM:
        if (action->reset_form.fields) {
            GList *iter;

            new_action->reset_form.fields = nullptr;
            for (iter = action->reset_form.fields; iter != nullptr; iter = iter->next) {
                new_action->reset_form.fields = g_list_append(new_action->reset_form.fields, g_strdup((char *)iter->data));
            }
        }
        break;
    default:
        break;
    }

    return new_action;
}

static PopplerDest *dest_new_goto(PopplerDocument *document, const LinkDest *link_dest)
{
    PopplerDest *dest;

    dest = g_slice_new0(PopplerDest);

    if (link_dest == nullptr) {
        dest->type = POPPLER_DEST_UNKNOWN;
        return dest;
    }

    switch (link_dest->getKind()) {
    case destXYZ:
        dest->type = POPPLER_DEST_XYZ;
        break;
    case destFit:
        dest->type = POPPLER_DEST_FIT;
        break;
    case destFitH:
        dest->type = POPPLER_DEST_FITH;
        break;
    case destFitV:
        dest->type = POPPLER_DEST_FITV;
        break;
    case destFitR:
        dest->type = POPPLER_DEST_FITR;
        break;
    case destFitB:
        dest->type = POPPLER_DEST_FITB;
        break;
    case destFitBH:
        dest->type = POPPLER_DEST_FITBH;
        break;
    case destFitBV:
        dest->type = POPPLER_DEST_FITBV;
        break;
    default:
        dest->type = POPPLER_DEST_UNKNOWN;
    }

    if (link_dest->isPageRef()) {
        if (document) {
            const Ref page_ref = link_dest->getPageRef();
            dest->page_num = document->doc->findPage(page_ref);
        } else {
            /* FIXME: We don't keep areound the page_ref for the
             * remote doc, so we can't look this up.  Guess that
             * it's 0*/
            dest->page_num = 0;
        }
    } else {
        dest->page_num = link_dest->getPageNum();
    }

    dest->left = link_dest->getLeft();
    dest->bottom = link_dest->getBottom();
    dest->right = link_dest->getRight();
    dest->top = link_dest->getTop();
    dest->zoom = link_dest->getZoom();
    dest->change_left = link_dest->getChangeLeft();
    dest->change_top = link_dest->getChangeTop();
    dest->change_zoom = link_dest->getChangeZoom();

    if (document && dest->page_num > 0) {
        PopplerPage *page;

        page = poppler_document_get_page(document, dest->page_num - 1);

        if (page) {
            dest->left -= page->page->getCropBox()->x1;
            dest->bottom -= page->page->getCropBox()->x1;
            dest->right -= page->page->getCropBox()->y1;
            dest->top -= page->page->getCropBox()->y1;

            g_object_unref(page);
        } else {
            g_warning("Invalid page %d in Link Destination\n", dest->page_num);
            dest->page_num = 0;
        }
    }

    return dest;
}

static PopplerDest *dest_new_named(const GooString *named_dest)
{
    PopplerDest *dest;

    dest = g_slice_new0(PopplerDest);

    if (named_dest == nullptr) {
        dest->type = POPPLER_DEST_UNKNOWN;
        return dest;
    }

    const std::string &str = named_dest->toStr();

    dest->type = POPPLER_DEST_NAMED;
    dest->named_dest = poppler_named_dest_from_bytestring((const guint8 *)str.data(), str.size());

    return dest;
}

static void build_goto_dest(PopplerDocument *document, PopplerAction *action, const LinkGoTo *link)
{
    const LinkDest *link_dest;
    const GooString *named_dest;

    /* Return if it isn't OK */
    if (!link->isOk()) {
        action->goto_dest.dest = dest_new_goto(nullptr, nullptr);
        return;
    }

    link_dest = link->getDest();
    named_dest = link->getNamedDest();

    if (link_dest != nullptr) {
        action->goto_dest.dest = dest_new_goto(document, link_dest);
    } else if (named_dest != nullptr) {
        action->goto_dest.dest = dest_new_named(named_dest);
    } else {
        action->goto_dest.dest = dest_new_goto(document, nullptr);
    }
}

static void build_goto_remote(PopplerAction *action, const LinkGoToR *link)
{
    const LinkDest *link_dest;
    const GooString *named_dest;

    /* Return if it isn't OK */
    if (!link->isOk()) {
        action->goto_remote.dest = dest_new_goto(nullptr, nullptr);
        return;
    }

    action->goto_remote.file_name = _poppler_goo_string_to_utf8(link->getFileName());

    link_dest = link->getDest();
    named_dest = link->getNamedDest();

    if (link_dest != nullptr) {
        action->goto_remote.dest = dest_new_goto(nullptr, link_dest);
    } else if (named_dest != nullptr) {
        action->goto_remote.dest = dest_new_named(named_dest);
    } else {
        action->goto_remote.dest = dest_new_goto(nullptr, nullptr);
    }
}

static void build_launch(PopplerAction *action, const LinkLaunch *link)
{
    if (link->getFileName()) {
        action->launch.file_name = g_strdup(link->getFileName()->c_str());
    }
    if (link->getParams()) {
        action->launch.params = g_strdup(link->getParams()->c_str());
    }
}

static void build_uri(PopplerAction *action, const LinkURI *link)
{
    const gchar *uri = link->getURI().c_str();
    if (uri != nullptr) {
        action->uri.uri = g_strdup(uri);
    }
}

static void build_named(PopplerAction *action, const LinkNamed *link)
{
    const gchar *name = link->getName().c_str();
    if (name != nullptr) {
        action->named.named_dest = g_strdup(name);
    }
}

static AnnotMovie *find_annot_movie_for_action(PopplerDocument *document, const LinkMovie *link)
{
    AnnotMovie *annot = nullptr;
    XRef *xref = document->doc->getXRef();
    Object annotObj;

    if (link->hasAnnotRef()) {
        const Ref *ref = link->getAnnotRef();

        annotObj = xref->fetch(*ref);
    } else if (link->hasAnnotTitle()) {
        const std::string &title = link->getAnnotTitle();
        int i;

        for (i = 1; i <= document->doc->getNumPages(); ++i) {
            Page *p = document->doc->getPage(i);
            if (!p) {
                continue;
            }

            Object annots = p->getAnnotsObject();
            if (annots.isArray()) {
                int j;
                bool found = false;

                for (j = 0; j < annots.arrayGetLength() && !found; ++j) {
                    annotObj = annots.arrayGet(j);
                    if (annotObj.isDict()) {
                        Object obj1 = annotObj.dictLookup("Subtype");
                        if (!obj1.isName("Movie")) {
                            continue;
                        }

                        obj1 = annotObj.dictLookup("T");
                        if (obj1.isString() && obj1.getString()->toStr() == title) {
                            found = true;
                        }
                    }
                    if (!found) {
                        annotObj.setToNull();
                    }
                }
                if (found) {
                    break;
                } else {
                    annotObj.setToNull();
                }
            }
        }
    }

    if (annotObj.isDict()) {
        Object tmp;

        annot = new AnnotMovie(document->doc, std::move(annotObj), &tmp);
        if (!annot->isOk()) {
            delete annot;
            annot = nullptr;
        }
    }

    return annot;
}

static void build_movie(PopplerDocument *document, PopplerAction *action, const LinkMovie *link)
{
    AnnotMovie *annot;

    switch (link->getOperation()) {
    case LinkMovie::operationTypePause:
        action->movie.operation = POPPLER_ACTION_MOVIE_PAUSE;
        break;
    case LinkMovie::operationTypeResume:
        action->movie.operation = POPPLER_ACTION_MOVIE_RESUME;
        break;
    case LinkMovie::operationTypeStop:
        action->movie.operation = POPPLER_ACTION_MOVIE_STOP;
        break;
    default:
    case LinkMovie::operationTypePlay:
        action->movie.operation = POPPLER_ACTION_MOVIE_PLAY;
        break;
    }

    annot = find_annot_movie_for_action(document, link);
    if (annot) {
        action->movie.movie = _poppler_movie_new(annot->getMovie());
        delete annot;
    }
}

static void build_javascript(PopplerAction *action, const LinkJavaScript *link)
{
    if (link->isOk()) {
        const GooString script(link->getScript());
        action->javascript.script = _poppler_goo_string_to_utf8(&script);
    }
}

static void build_reset_form(PopplerAction *action, const LinkResetForm *link)
{
    const std::vector<std::string> &fields = link->getFields();

    if (action->reset_form.fields != nullptr) {
        g_list_free_full(action->reset_form.fields, g_free);
    }

    action->reset_form.fields = nullptr;
    for (const auto &field : fields) {
        action->reset_form.fields = g_list_append(action->reset_form.fields, g_strdup(field.c_str()));
    }

    action->reset_form.exclude = link->getExclude();
}

static void build_rendition(PopplerAction *action, const LinkRendition *link)
{
    action->rendition.op = link->getOperation();
    if (link->getMedia()) {
        action->rendition.media = _poppler_media_new(link->getMedia());
    }
    // TODO: annotation reference
}

static PopplerLayer *get_layer_for_ref(PopplerDocument *document, GList *layers, const Ref ref, gboolean preserve_rb)
{
    GList *l;

    for (l = layers; l; l = g_list_next(l)) {
        Layer *layer = (Layer *)l->data;

        if (layer->oc) {
            const Ref ocgRef = layer->oc->getRef();

            if (ref == ocgRef) {
                GList *rb_group = nullptr;

                if (preserve_rb) {
                    rb_group = _poppler_document_get_layer_rbgroup(document, layer);
                }
                return _poppler_layer_new(document, layer, rb_group);
            }
        }

        if (layer->kids) {
            PopplerLayer *retval = get_layer_for_ref(document, layer->kids, ref, preserve_rb);
            if (retval) {
                return retval;
            }
        }
    }

    return nullptr;
}

static void build_ocg_state(PopplerDocument *document, PopplerAction *action, const LinkOCGState *ocg_state)
{
    const std::vector<LinkOCGState::StateList> &st_list = ocg_state->getStateList();
    bool preserve_rb = ocg_state->getPreserveRB();
    GList *layer_state = nullptr;

    if (!document->layers) {
        if (!_poppler_document_get_layers(document)) {
            return;
        }
    }

    for (const LinkOCGState::StateList &list : st_list) {
        PopplerActionLayer *action_layer = g_slice_new0(PopplerActionLayer);

        switch (list.st) {
        case LinkOCGState::On:
            action_layer->action = POPPLER_ACTION_LAYER_ON;
            break;
        case LinkOCGState::Off:
            action_layer->action = POPPLER_ACTION_LAYER_OFF;
            break;
        case LinkOCGState::Toggle:
            action_layer->action = POPPLER_ACTION_LAYER_TOGGLE;
            break;
        }

        for (const Ref &ref : list.list) {
            PopplerLayer *layer = get_layer_for_ref(document, document->layers, ref, preserve_rb);

            action_layer->layers = g_list_prepend(action_layer->layers, layer);
        }

        layer_state = g_list_prepend(layer_state, action_layer);
    }

    action->ocg_state.state_list = g_list_reverse(layer_state);
}

PopplerAction *_poppler_action_new(PopplerDocument *document, const LinkAction *link, const gchar *title)
{
    PopplerAction *action;

    action = g_slice_new0(PopplerAction);

    if (title) {
        action->any.title = g_strdup(title);
    }

    if (link == nullptr) {
        action->type = POPPLER_ACTION_NONE;
        return action;
    }

    switch (link->getKind()) {
    case actionGoTo:
        action->type = POPPLER_ACTION_GOTO_DEST;
        build_goto_dest(document, action, static_cast<const LinkGoTo *>(link));
        break;
    case actionGoToR:
        action->type = POPPLER_ACTION_GOTO_REMOTE;
        build_goto_remote(action, static_cast<const LinkGoToR *>(link));
        break;
    case actionLaunch:
        action->type = POPPLER_ACTION_LAUNCH;
        build_launch(action, static_cast<const LinkLaunch *>(link));
        break;
    case actionURI:
        action->type = POPPLER_ACTION_URI;
        build_uri(action, static_cast<const LinkURI *>(link));
        break;
    case actionNamed:
        action->type = POPPLER_ACTION_NAMED;
        build_named(action, static_cast<const LinkNamed *>(link));
        break;
    case actionMovie:
        action->type = POPPLER_ACTION_MOVIE;
        build_movie(document, action, static_cast<const LinkMovie *>(link));
        break;
    case actionRendition:
        action->type = POPPLER_ACTION_RENDITION;
        build_rendition(action, static_cast<const LinkRendition *>(link));
        break;
    case actionOCGState:
        action->type = POPPLER_ACTION_OCG_STATE;
        build_ocg_state(document, action, static_cast<const LinkOCGState *>(link));
        break;
    case actionJavaScript:
        action->type = POPPLER_ACTION_JAVASCRIPT;
        build_javascript(action, static_cast<const LinkJavaScript *>(link));
        break;
    case actionResetForm:
        action->type = POPPLER_ACTION_RESET_FORM;
        build_reset_form(action, dynamic_cast<const LinkResetForm *>(link));
        break;
    case actionUnknown:
    default:
        action->type = POPPLER_ACTION_UNKNOWN;
        break;
    }

    return action;
}

PopplerDest *_poppler_dest_new_goto(PopplerDocument *document, LinkDest *link_dest)
{
    return dest_new_goto(document, link_dest);
}
