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

POPPLER_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_foreach (action_layer->layers, (GFunc)g_object_unref, NULL);
		g_list_free (action_layer->layers);
		action_layer->layers = NULL;
	}

	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);
	g_list_foreach (action_layer->layers, (GFunc)g_object_ref, NULL);

	return retval;
}

POPPLER_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 == NULL)
		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_foreach (action->ocg_state.state_list, (GFunc)poppler_action_layer_free, NULL);
			g_list_free (action->ocg_state.state_list);
		}
		break;
	case POPPLER_ACTION_JAVASCRIPT:
		if (action->javascript.script)
			g_free (action->javascript.script);
		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 != NULL, NULL);

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

	if (action->any.title != NULL)
		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 = NULL;

			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;
	default:
		break;
	}
	    
	return new_action;
}

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

	dest = g_slice_new0 (PopplerDest);

	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 ();
	
	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 (GooString *named_dest)
{
	PopplerDest *dest;

	dest = g_slice_new0 (PopplerDest);

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

	dest->type = POPPLER_DEST_NAMED;
	dest->named_dest = g_strdup (named_dest->getCString ());

	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 = dest_new_goto (NULL, NULL);
		return;
	}
	
	link_dest = link->getDest ();
	named_dest = link->getNamedDest ();

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

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

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

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

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

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,
	     LinkNamed     *link)
{
	gchar *name;

	name = link->getName ()->getCString ();
	if (name != NULL)
		action->named.named_dest = g_strdup (name);
}

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

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

    annotObj = xref->fetch (ref->num, ref->gen);
  } else if (link->hasAnnotTitle ()) {
    GooString *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;
	GBool found = gFalse;

	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()) {
	      GooString *t = obj1.getString ();

	      if (title->cmp(t) == 0)
	        found = gTrue;
	    }
	  }
	  if (!found)
	    annotObj.setToNull ();
	}
	if (found) {
	  break;
	} else {
          annotObj.setToNull ();
	}
      }
    }
  }

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

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

  return annot;
}

static void
build_movie (PopplerDocument *document,
	     PopplerAction   *action,
	     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,
		  LinkJavaScript *link)
{
	GooString *script;

	script = link->getScript();
	if (script)
		action->javascript.script = _poppler_goo_string_to_utf8 (script);

}

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

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

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

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

			if (ref->num == ocgRef.num && ref->gen == ocgRef.gen) {
				GList *rb_group = NULL;

				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 NULL;
}

static void
build_ocg_state (PopplerDocument *document,
		 PopplerAction   *action,
		 LinkOCGState    *ocg_state)
{
	GooList *st_list = ocg_state->getStateList();
	GBool    preserve_rb = ocg_state->getPreserveRB();
	gint     i, j;
	GList   *layer_state = NULL;

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

	for (i = 0; i < st_list->getLength(); ++i) {
		LinkOCGState::StateList *list = (LinkOCGState::StateList *)st_list->get(i);
		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 (j = 0; j < list->list->getLength(); ++j) {
			Ref *ref = (Ref *)list->list->get(j);
			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,
		     LinkAction      *link,
		     const gchar     *title)
{
	PopplerAction *action;

	action = g_slice_new0 (PopplerAction);

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

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

	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, dynamic_cast <LinkLaunch *> (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, dynamic_cast <LinkNamed *> (link));
		break;
	case actionMovie:
		action->type = POPPLER_ACTION_MOVIE;
		build_movie (document, action, dynamic_cast<LinkMovie*> (link));
		break;
	case actionRendition:
		action->type = POPPLER_ACTION_RENDITION;
		build_rendition (action, dynamic_cast<LinkRendition*> (link));
		break;
	case actionOCGState:
		action->type = POPPLER_ACTION_OCG_STATE;
		build_ocg_state (document, action, dynamic_cast<LinkOCGState*> (link));
		break;
	case actionJavaScript:
		action->type = POPPLER_ACTION_JAVASCRIPT;
		build_javascript (action, dynamic_cast<LinkJavaScript*> (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);
}
