//========================================================================
//
// Link.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006, 2008 Pino Toscano <pino@kde.org>
// Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
// Copyright (C) 2010, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2012 Tobias Koening <tobias.koenig@kdab.com>
// Copyright (C) 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Intevation GmbH <intevation@intevation.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef LINK_H
#define LINK_H

#include "Object.h"
#include <memory>
#include <set>

class GooString;
class GooList;
class Array;
class Dict;
class Sound;
class MediaRendition;
class AnnotLink;
class Annots;

//------------------------------------------------------------------------
// LinkAction
//------------------------------------------------------------------------

enum LinkActionKind {
  actionGoTo,			// go to destination
  actionGoToR,			// go to destination in new file
  actionLaunch,			// launch app (or open document)
  actionURI,			// URI
  actionNamed,			// named action
  actionMovie,			// movie action
  actionRendition,		// rendition action
  actionSound,			// sound action
  actionJavaScript,		// JavaScript action
  actionOCGState,               // Set-OCG-State action
  actionHide,			// Hide action
  actionUnknown			// anything else
};

class LinkAction {
public:

  LinkAction();
  LinkAction(const LinkAction &) = delete;
  LinkAction& operator=(const LinkAction &other) = delete;

  // Destructor.
  virtual ~LinkAction();

  // Was the LinkAction created successfully?
  virtual GBool isOk() const = 0;

  // Check link action type.
  virtual LinkActionKind getKind() const = 0;

  // Parse a destination (old-style action) name, string, or array.
  static LinkAction *parseDest(const Object *obj);

  // Parse an action dictionary.
  static LinkAction *parseAction(const Object *obj, const GooString *baseURI = nullptr);

  // A List of the next actions to execute in order.
  // The list contains pointer to LinkAction objects.
  const GooList *nextActions() const;

  // Sets the next action list. Takes ownership of the actions.
  void setNextActions(GooList *actions);

private:
  static LinkAction *parseAction(const Object *obj, const GooString *baseURI, std::set<int> *seenNextActions);

  GooList *nextActionList;
};

//------------------------------------------------------------------------
// LinkDest
//------------------------------------------------------------------------

enum LinkDestKind {
  destXYZ,
  destFit,
  destFitH,
  destFitV,
  destFitR,
  destFitB,
  destFitBH,
  destFitBV
};

class LinkDest {
public:

  // Build a LinkDest from the array.
  LinkDest(const Array *a);

  // Copy a LinkDest.
  LinkDest *copy() const { return new LinkDest(this); }

  // Was the LinkDest created successfully?
  GBool isOk() const { return ok; }

  // Accessors.
  LinkDestKind getKind() const { return kind; }
  GBool isPageRef() const { return pageIsRef; }
  int getPageNum() const { return pageNum; }
  Ref getPageRef() const { return pageRef; }
  double getLeft() const { return left; }
  double getBottom() const { return bottom; }
  double getRight() const { return right; }
  double getTop() const { return top; }
  double getZoom() const { return zoom; }
  GBool getChangeLeft() const { return changeLeft; }
  GBool getChangeTop() const { return changeTop; }
  GBool getChangeZoom() const { return changeZoom; }

private:

  LinkDestKind kind;		// destination type
  GBool pageIsRef;		// is the page a reference or number?
  union {
    Ref pageRef;		// reference to page
    int pageNum;		// one-relative page number
  };
  double left, bottom;		// position
  double right, top;
  double zoom;			// zoom factor
  GBool changeLeft, changeTop;	// which position components to change:
  GBool changeZoom;		//   destXYZ uses all three;
				//   destFitH/BH use changeTop;
				//   destFitV/BV use changeLeft
  GBool ok;			// set if created successfully

  LinkDest(const LinkDest *dest);
};

//------------------------------------------------------------------------
// LinkGoTo
//------------------------------------------------------------------------

class LinkGoTo: public LinkAction {
public:

  // Build a LinkGoTo from a destination (dictionary, name, or string).
  LinkGoTo(const Object *destObj);

  // Destructor.
  ~LinkGoTo();

  // Was the LinkGoTo created successfully?
  GBool isOk() const override { return dest || namedDest; }

  // Accessors.
  LinkActionKind getKind() const override { return actionGoTo; }
  const LinkDest *getDest() const { return dest; }
  const GooString *getNamedDest() const { return namedDest; }

private:

  LinkDest *dest;		// regular destination (nullptr for remote
				//   link with bad destination)
  GooString *namedDest;	// named destination (only one of dest and
				//   and namedDest may be non-nullptr)
};

//------------------------------------------------------------------------
// LinkGoToR
//------------------------------------------------------------------------

class LinkGoToR: public LinkAction {
public:

  // Build a LinkGoToR from a file spec (dictionary) and destination
  // (dictionary, name, or string).
  LinkGoToR(Object *fileSpecObj, Object *destObj);

  // Destructor.
  ~LinkGoToR();

  // Was the LinkGoToR created successfully?
  GBool isOk() const override { return fileName && (dest || namedDest); }

  // Accessors.
  LinkActionKind getKind() const override { return actionGoToR; }
  const GooString *getFileName() const { return fileName; }
  const LinkDest *getDest() const { return dest; }
  const GooString *getNamedDest() const { return namedDest; }

private:

  GooString *fileName;		// file name
  LinkDest *dest;		// regular destination (nullptr for remote
				//   link with bad destination)
  GooString *namedDest;	// named destination (only one of dest and
				//   and namedDest may be non-nullptr)
};

//------------------------------------------------------------------------
// LinkLaunch
//------------------------------------------------------------------------

class LinkLaunch: public LinkAction {
public:

  // Build a LinkLaunch from an action dictionary.
  LinkLaunch(const Object *actionObj);

  // Destructor.
  ~LinkLaunch();

  // Was the LinkLaunch created successfully?
  GBool isOk() const override { return fileName != nullptr; }

  // Accessors.
  LinkActionKind getKind() const override { return actionLaunch; }
  const GooString *getFileName() const { return fileName; }
  const GooString *getParams() const { return params; }

private:

  GooString *fileName;		// file name
  GooString *params;		// parameters
};

//------------------------------------------------------------------------
// LinkURI
//------------------------------------------------------------------------

class LinkURI: public LinkAction {
public:

  // Build a LinkURI given the URI (string) and base URI.
  LinkURI(const Object *uriObj, const GooString *baseURI);

  // Destructor.
  ~LinkURI();

  // Was the LinkURI created successfully?
  GBool isOk() const override { return uri != nullptr; }

  // Accessors.
  LinkActionKind getKind() const override { return actionURI; }
  const GooString *getURI() const { return uri; }

private:

  GooString *uri;			// the URI
};

//------------------------------------------------------------------------
// LinkNamed
//------------------------------------------------------------------------

class LinkNamed: public LinkAction {
public:

  // Build a LinkNamed given the action name.
  LinkNamed(const Object *nameObj);

  ~LinkNamed();

  GBool isOk() const override { return name != nullptr; }

  LinkActionKind getKind() const override { return actionNamed; }
  const GooString *getName() const { return name; }

private:

  GooString *name;
};


//------------------------------------------------------------------------
// LinkMovie
//------------------------------------------------------------------------

class LinkMovie: public LinkAction {
public:

  enum OperationType {
    operationTypePlay,
    operationTypePause,
    operationTypeResume,
    operationTypeStop
  };

  LinkMovie(const Object *obj);
  ~LinkMovie();

  GBool isOk() const override { return annotRef.num >= 0 || annotTitle != nullptr; }
  LinkActionKind getKind() const override { return actionMovie; }

  // a movie action stores either an indirect reference to a movie annotation
  // or the movie annotation title

  GBool hasAnnotRef() const { return annotRef.num >= 0; }
  GBool hasAnnotTitle() const { return annotTitle != nullptr; }
  const Ref *getAnnotRef() const { return &annotRef; }
  const GooString *getAnnotTitle() const { return annotTitle; }

  OperationType getOperation() const { return operation; }

private:

  Ref annotRef;            // Annotation
  GooString *annotTitle;   // T

  OperationType operation; // Operation
};


//------------------------------------------------------------------------
// LinkRendition
//------------------------------------------------------------------------

class LinkRendition: public LinkAction {
public:
  /**
   * Describes the possible rendition operations.
   */
  enum RenditionOperation {
    NoRendition,
    PlayRendition,
    StopRendition,
    PauseRendition,
    ResumeRendition
  };

  LinkRendition(const Object *Obj);

  ~LinkRendition();

  GBool isOk() const override { return true; }

  LinkActionKind getKind() const override { return actionRendition; }

  GBool hasRenditionObject() const { return renditionObj.isDict(); }
  const Object* getRenditionObject() const { return &renditionObj; }

  GBool hasScreenAnnot() const { return screenRef.isRef(); }
  Ref getScreenAnnot() const { return screenRef.getRef(); }

  RenditionOperation getOperation() const { return operation; }

  const MediaRendition* getMedia() const { return media; }

  const GooString *getScript() const { return js; }

private:

  Object screenRef;
  Object renditionObj;
  RenditionOperation operation;

  MediaRendition* media;

  GooString *js;
};

//------------------------------------------------------------------------
// LinkSound
//------------------------------------------------------------------------

class LinkSound: public LinkAction {
public:

  LinkSound(const Object *soundObj);

  ~LinkSound();

  GBool isOk() const override { return sound != nullptr; }

  LinkActionKind getKind() const override { return actionSound; }

  double getVolume() const { return volume; }
  GBool getSynchronous() const { return sync; }
  GBool getRepeat() const { return repeat; }
  GBool getMix() const { return mix; }
  Sound *getSound() const { return sound; }

private:

  double volume;
  GBool sync;
  GBool repeat;
  GBool mix;
  Sound *sound;
};

//------------------------------------------------------------------------
// LinkJavaScript
//------------------------------------------------------------------------

class LinkJavaScript: public LinkAction {
public:

  // Build a LinkJavaScript given the action name.
  LinkJavaScript(Object *jsObj);

  ~LinkJavaScript();

  GBool isOk() const override { return js != nullptr; }

  LinkActionKind getKind() const override { return actionJavaScript; }
  const GooString *getScript() const { return js; }

private:

  GooString *js;
};

//------------------------------------------------------------------------
// LinkOCGState
//------------------------------------------------------------------------
class LinkOCGState: public LinkAction {
public:
  LinkOCGState(const Object *obj);

  ~LinkOCGState();

  GBool isOk() const override { return stateList != nullptr; }

  LinkActionKind getKind() const override { return actionOCGState; }

  enum State { On, Off, Toggle};
  struct StateList {
    StateList() { list = nullptr; }
    ~StateList();
    StateList(const StateList &) = delete;
    StateList& operator=(const StateList &) = delete;
    State st;
    GooList *list;
  };

  const GooList *getStateList() const { return stateList; }
  GBool getPreserveRB() const { return preserveRB; }

private:
  GooList *stateList;
  GBool preserveRB;
};

//------------------------------------------------------------------------
// LinkHide
//------------------------------------------------------------------------

class LinkHide: public LinkAction {
public:
  LinkHide(const Object *hideObj);

  ~LinkHide();

  GBool isOk() const override { return targetName != nullptr; }
  LinkActionKind getKind() const override { return actionHide; }

  // According to spec the target can be either:
  // a) A text string containing the fully qualified name of the target
  //    field.
  // b) An indirect reference to an annotation dictionary.
  // c) An array of "such dictionaries or text strings".
  //
  // While b / c appear to be very uncommon and can't easily be
  // created with Adobe Acrobat DC. So only support hide
  // actions with named targets (yet).
  GBool hasTargetName() const { return targetName != nullptr; }
  const GooString *getTargetName() const { return targetName; }

  // Should this action show or hide.
  GBool isShowAction() const { return show; }

private:
  GooString *targetName;
  GBool show;
};

//------------------------------------------------------------------------
// LinkUnknown
//------------------------------------------------------------------------

class LinkUnknown: public LinkAction {
public:

  // Build a LinkUnknown with the specified action type.
  LinkUnknown(const char *actionA);

  // Destructor.
  ~LinkUnknown();

  // Was the LinkUnknown create successfully?
  GBool isOk() const override { return action != nullptr; }

  // Accessors.
  LinkActionKind getKind() const override { return actionUnknown; }
  const GooString *getAction() const { return action; }

private:

  GooString *action;		// action subtype
};

//------------------------------------------------------------------------
// Links
//------------------------------------------------------------------------

class Links {
public:

  // Extract links from array of annotations.
  Links(Annots *annots);

  // Destructor.
  ~Links();

  Links(const Links &) = delete;
  Links& operator=(const Links &) = delete;

  // Iterate through list of links.
  int getNumLinks() const { return numLinks; }
  AnnotLink *getLink(int i) const { return links[i]; }

  // If point <x>,<y> is in a link, return the associated action;
  // else return nullptr.
  LinkAction *find(double x, double y) const;

  // Return true if <x>,<y> is in a link.
  GBool onLink(double x, double y) const;

private:

  AnnotLink **links;
  int numLinks;
};

#endif
