/*
 * Copyright (C) 2009-2010, Pino Toscano <pino@kde.org>
 * Copyright (C) 2016 Jakub Kucharski <jakubkucharski97@gmail.com>
 *
 * 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.
 */

#ifndef POPPLER_DOCUMENT_H
#define POPPLER_DOCUMENT_H

#include "poppler-global.h"
#include "poppler-font.h"

namespace poppler
{

class document_private;
class embedded_file;
class page;
class toc;

class POPPLER_CPP_EXPORT document : public poppler::noncopyable
{
public:
    enum page_mode_enum {
        use_none,
        use_outlines,
        use_thumbs,
        fullscreen,
        use_oc,
        use_attach
    };

    enum page_layout_enum {
        no_layout,
        single_page,
        one_column,
        two_column_left,
        two_column_right,
        two_page_left,
        two_page_right
    };

    ~document();

    bool is_locked() const;
    bool unlock(const std::string &owner_password, const std::string &user_password);

    page_mode_enum page_mode() const;
    page_layout_enum page_layout() const;
    void get_pdf_version(int *major, int *minor) const;
    std::vector<std::string> info_keys() const;

    ustring info_key(const std::string &key) const;
    bool set_info_key(const std::string &key, const ustring &val);

    time_type info_date(const std::string &key) const;
    bool set_info_date(const std::string &key, time_type val);

    ustring get_title() const;
    bool set_title(const ustring &title);
    ustring get_author() const;
    bool set_author(const ustring &author);
    ustring get_subject() const;
    bool set_subject(const ustring &subject);
    ustring get_keywords() const;
    bool set_keywords(const ustring &keywords);
    ustring get_creator() const;
    bool set_creator(const ustring &creator);
    ustring get_producer() const;
    bool set_producer(const ustring &producer);
    time_type get_creation_date() const;
    bool set_creation_date(time_type creation_date);
    time_type get_modification_date() const;
    bool set_modification_date(time_type mod_date);

    bool remove_info();

    bool is_encrypted() const;
    bool is_linearized() const;
    bool has_permission(permission_enum which) const;
    ustring metadata() const;
    bool get_pdf_id(std::string *permanent_id, std::string *update_id) const;

    int pages() const;
    page* create_page(const ustring &label) const;
    page* create_page(int index) const;

    std::vector<font_info> fonts() const;
    font_iterator* create_font_iterator(int start_page = 0) const;

    toc* create_toc() const;

    bool has_embedded_files() const;
    std::vector<embedded_file *> embedded_files() const;

    bool save(const std::string &filename) const;
    bool save_a_copy(const std::string &filename) const;

    static document* load_from_file(const std::string &file_name,
                                    const std::string &owner_password = std::string(),
                                    const std::string &user_password = std::string());
    static document* load_from_data(byte_array *file_data,
                                    const std::string &owner_password = std::string(),
                                    const std::string &user_password = std::string());
    static document* load_from_raw_data(const char *file_data,
                                        int file_data_length,
                                        const std::string &owner_password = std::string(),
                                        const std::string &user_password = std::string());

private:
    document(document_private &dd);

    document_private *d;
    friend class document_private;
};

}

#endif
