// -*- C++ -*-
// --------------------------------------------------------------------
// The Ipe document.
// --------------------------------------------------------------------
/*

    This file is part of the extensible drawing editor Ipe.
    Copyright (C) 1993-2007  Otfried Cheong

    Ipe 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 of the License, or
    (at your option) any later version.

    As a special exception, you have permission to link Ipe with the
    CGAL library and distribute executables, as long as you follow the
    requirements of the Gnu General Public License in regard to all of
    the software in the executable aside from CGAL.

    Ipe 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 Ipe; if not, you can find it at
    "http://www.gnu.org/copyleft/gpl.html", or write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#ifndef IPEDOC_H
#define IPEDOC_H

#include "ipeobj.h"
#include "ipepage.h"
#include "ipeimage.h"
#include "ipestyle.h"

class IpeFontPool;
class IpeBitmapFinder;

// --------------------------------------------------------------------

class IPE_EXPORT IpeDocument {
public:
  //! Properties of a document
  struct SProperties {
    SProperties();
    IpeString iTitle;
    IpeString iAuthor;
    IpeString iSubject;
    IpeString iKeywords;
    IpeString iPreamble;
    bool iFullScreen;
    bool iCropBox;
    bool iNumberPages;
    //! Date/time in PDF style "D:20010428191400" format.
    IpeString iCreated;
    IpeString iModified;
    //! Program that created this document (e.g. "Ipe 7.5").
    IpeString iCreator;
  };

  //! There are several Ipe document save formats.
  enum TFormat {
    EXml,  //!< Save as XML
    EPdf,  //!< Save as PDF
    EEps,  //!< Save as Encapsulated Postscript
    EIpe5,  //!< Old Ipe format
    EUnknown //!< Unknown file format
  };

  //! Options for saving Ipe documents (to PDF and Postscript)
  enum {
    ESaveNormal = 0, //!< Nothing special
    EExport = 1,     //!< Don't include Ipe markup
    ENoShading = 2,  //!< Don't shade background in PDF documents
    ELastView = 4,   //!< Create last view of each page only
    ENoColor = 8,    //!< No color commands in EPS output
  };

  IpeDocument();
  ~IpeDocument();

  static TFormat FileFormat(IpeDataSource &source);

  static IpeDocument *New(IpeDataSource &source, TFormat format, int &reason);
  static IpeDocument *New(const char *fname, int &reason);

  bool Save(IpeTellStream &stream, IpeString creator,
	    TFormat format, uint flags,
	    int fromPage, int toPage,
	    int compressLevel = 9) const;
  bool Save(const char *fname, IpeString creator,
	    TFormat format, uint flags,
	    int fromPage = -1, int toPage = -1,
	    int compressLevel = 9) const;

  void SaveAsXml(IpeStream &stream, IpeString creator,
		 bool usePdfBitmaps = false) const;

  bool AddStyleSheet(IpeDataSource &source);

  // Return number of pages of document.
  int pages() const { return int(iPages.size()); }
  int totalViews() const;

  //! Return page (const version).
  /*! The first page is no 0. */
  const IpePage *page(int no) const { return iPages[no]; }
  //! Return page.
  /*! The first page is no 0. */
  IpePage *page(int no) { return iPages[no]; }

  IpePage *setPage(int no, IpePage *page);
  IpePage *newPage(int gridSize);
  void addPage(int no, IpePage *page);
  IpePage *removePage(int no);

  //! Return document properties.
  inline SProperties Properties() const { return iProperties; }
  void SetProperties(const SProperties &info);

  IpeLayout layout() const;

  void SetStyleSheet(IpeStyleSheet *sheet);
  //! Return const pointer to topmost stylesheet.
  const IpeStyleSheet *StyleSheet() const { return iStyleSheet; }
  //! Return modifiable stylesheet.
  IpeStyleSheet *GetStyleSheet() { return iStyleSheet; }

  bool IsEdited() const;
  void SetEdited(bool edited);

  void SetFontPool(IpeFontPool *fontPool);
  //! Return the current IpeFontPool.
  inline const IpeFontPool *FontPool() const { return iFontPool; }
  bool HasTrueTypeFonts() const;

  void FindBitmaps(IpeBitmapFinder &bm) const;
  bool CheckStyle(IpeAttributeSeq &seq) const;

  //! Return attribute repository.
  inline IpeRepository *Repository() { return &iRepository; }
  //! Return attribute repository (const version).
  inline const IpeRepository *Repository() const { return &iRepository; }

private:
  IpeDocument(const IpeDocument &rhs);
  IpeDocument &operator=(const IpeDocument &rhs);
protected:
  std::vector<IpePage *> iPages;
  IpeStyleSheet *iStyleSheet;
  SProperties iProperties;
  bool iEdited;
  IpeRepository iRepository;
  IpeFontPool *iFontPool;
};

// --------------------------------------------------------------------
#endif
