//========================================================================
//
// XRef.h
//
// Copyright 1996 Derek B. Noonburg
//
//========================================================================

#ifndef XREF_H
#define XREF_H

#ifdef __GNUC__
#pragma interface
#endif

#include <stdio.h>
#include "../server/mystdio.h"
#include "gtypes.h"
#include "Object.h"

class Dict;
class FileStream;

//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------

struct XRefEntry {
  int offset;
  int gen;
  GBool used;
};

class XRef {
public:

  // Constructor.  Read xref table from stream.
  XRef(FileStream *str);

  // Destructor.
  ~XRef();

  // Is xref table valid?
  GBool isOk() { return ok; }

  // Is the file encrypted?
  GBool isEncrypted() { return encrypted; }

  // Are printing and copying allowed?  If not, print an error message.
  GBool okToPrint();
  GBool okToCopy();
  GBool okToChange();
  GBool okToAddNotes();

  // Get catalog object.
  Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); }

  // Get encryption key
  GString *getEncryptionKey() { return &encryptionKey; };

  // Fetch an indirect reference.
  Object *fetch(int num, int gen, Object *obj);

  // Return the document's Info dictionary (if any).
  Object *getDocInfo(Object *obj);

private:

  myFILE *file;                 // input file
  int start;                    // offset in file (to allow for garbage
				//   at beginning of file)
  XRefEntry *entries;           // xref entries
  int size;                     // size of <entries> array
  int rootNum, rootGen;         // catalog dict
  GBool ok;                     // true if xref table is valid
  Object trailerDict;           // trailer dictionary

  GBool m_okToPrint;
  GBool m_okToCopy;
  GBool m_okToChange;
  GBool m_okToAddNotes;
  Object encryptionDict;              // encryption dictionary
  GBool encrypted;
  GString encryptionKey;

  GBool setupDecryption();
  GBool checkUserPassword(GString *userPassword);
  GBool MakeEncryptionKey(GString *password, GString *encryptionKey);
  GBool preparePassword(GString *password, GString *preparedPassword);

  int readTrailer(FileStream *str);
  GBool readXRef(FileStream *str, int *pos);
  GBool constructXRef(FileStream *str);
  GBool checkEncrypted();
};

//------------------------------------------------------------------------
// The global xref table
//------------------------------------------------------------------------

extern XRef *xref;

#endif
