/* 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 ();

    xref->fetch (ref->num, ref->gen, &annotObj);
  } else if (link->hasAnnotTitle ()) {
    Object annots;
    GooString *title = link->getAnnotTitle ();
    int i;

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

      if (p->getAnnots (&annots)->isArray ()) {
        int j;
	GBool found = gFalse;

	for (j = 0; j < annots.arrayGetLength () && !found; ++j) {
          if (annots.arrayGet(j, &annotObj)->isDict()) {
	    Object obj1;

	    if (!annotObj.dictLookup ("Subtype", &obj1)->isName ("Movie")) {
	      obj1.free ();
	      continue;
	    }
	    obj1.free ();

	    if (annotObj.dictLookup ("T", &obj1)->isString()) {
	      GooString *t = obj1.getString ();

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

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

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

  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_new0 (PopplerActionLayer, 1);

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