/* poppler-action.cc: glib wrapper for poppler
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */


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


static PopplerDest *
poppler_dest_copy (PopplerDest *dest)
{
	PopplerDest *new_dest;

	new_dest = g_new0 (PopplerDest, 1);
	memcpy (new_dest, dest, sizeof (PopplerDest));

	return new_dest;
}

static void
poppler_dest_free (PopplerDest *dest)
{
	g_free (dest);
}

GType
poppler_action_get_type (void)
{
  static GType our_type = 0;

  if (our_type == 0)
    our_type = g_boxed_type_register_static ("PopplerAction",
					     (GBoxedCopyFunc) poppler_action_copy,
					     (GBoxedFreeFunc) poppler_action_free);

  return our_type;
}

void
poppler_action_free (PopplerAction *action)
{
	if (action == NULL)
		return;

	/* Action specific stuff */
	if (action->type == POPPLER_ACTION_GOTO_DEST) {
		poppler_dest_free (action->goto_dest.dest);
	} else if (action->type == POPPLER_ACTION_GOTO_REMOTE) {
		poppler_dest_free (action->goto_remote.dest);
		g_free (action->goto_remote.file_name);
	} else if (action->type == POPPLER_ACTION_URI) {
		g_free (action->uri.uri);
	}

	g_free (action->any.title);
	g_free (action);
}

PopplerAction *
poppler_action_copy (PopplerAction *action)
{
	PopplerAction *new_action;

	g_return_val_if_fail (action != NULL, NULL);

	/* Do a straight copy of the memory */
	new_action = g_new0 (PopplerAction, 1);
	memcpy (new_action, action, sizeof (PopplerAction));

	if (action->any.title != NULL)
		new_action->any.title = g_strdup (action->any.title);

	if (action->type == POPPLER_ACTION_GOTO_DEST) {
		new_action->goto_dest.dest = poppler_dest_copy (action->goto_dest.dest);
	} else if (action->type == POPPLER_ACTION_GOTO_REMOTE) {
		new_action->goto_remote.dest = poppler_dest_copy (action->goto_remote.dest);
	}
	    
	return new_action;
}

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

	dest = g_new0 (PopplerDest, 1);

	if (link_dest == NULL) {
		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) {
			Ref page_ref = link_dest->getPageRef ();
			dest->page_num = document->doc->findPage (page_ref.num, page_ref.gen);
		} 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 ();

	return dest;
}

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

	/* Return if it isn't OK */
	if (! link->isOk ()) {
		action->goto_dest.dest = build_dest (NULL, NULL);
		return;
	}
	
	link_dest = link->getDest ();
	named_dest = link->getNamedDest ();

	if (link_dest != NULL) {
		action->goto_dest.dest = build_dest (document, link_dest);
	} else if (named_dest != NULL) {
		link_dest = document->doc->findDest (named_dest);
		action->goto_dest.dest = build_dest (document, link_dest);
		delete link_dest;
	} else {
		action->goto_dest.dest = build_dest (document, NULL);
	}
}

static void
build_goto_remote (PopplerAction *action,
		   LinkGoToR     *link)
{
	/* Return if it isn't OK */
	if (! link->isOk ()) {
		action->goto_remote.dest = build_dest (NULL, NULL);
		return;
	}

	if (link->getFileName()->getCString ())
		action->goto_remote.file_name = g_strdup (link->getFileName()->getCString ());

	/* FIXME, we don't handle named dest yet. */
	action->goto_dest.dest = build_dest (NULL, link->getDest ());
}

static void
build_launch (PopplerAction *action,
	      LinkAction    *link)
{
	/* FIXME: Write */
}

static void
build_uri (PopplerAction *action,
	   LinkURI       *link)
{
	gchar *uri;

	uri = link->getURI()->getCString ();
	if (uri != NULL)
		action->uri.uri = g_strdup (uri);
}

static void
build_named (PopplerAction *action,
	     LinkAction    *link)
{
	/* FIXME: Write */
}

static void
build_movie (PopplerAction *action,
	     LinkAction    *link)
{
	/* FIXME: Write */
}

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

	action = g_new0 (PopplerAction, 1);

	switch (link->getKind ()) {
	case actionGoTo:
		action->type = POPPLER_ACTION_GOTO_DEST;
		build_goto_dest (document, action, dynamic_cast <LinkGoTo *> (link));
		break;
	case actionGoToR:
		action->type = POPPLER_ACTION_GOTO_REMOTE;
		build_goto_remote (action, dynamic_cast <LinkGoToR *> (link));
		break;
	case actionLaunch:
		action->type = POPPLER_ACTION_LAUNCH;
		build_launch (action, link);
		break;
	case actionURI:
		action->type = POPPLER_ACTION_URI;
		build_uri (action, dynamic_cast <LinkURI *> (link));
		break;
	case actionNamed:
		action->type = POPPLER_ACTION_NAMED;
		build_named (action, link);
		break;
	case actionMovie:
		action->type = POPPLER_ACTION_MOVIE;
		build_movie (action, link);
		break;
	case actionUnknown:
	default:
		action->type = POPPLER_ACTION_UNKNOWN;
		break;
	}

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