/*
  Paper sizes command-line utility.

  Copyright (c) 2021-2023 Reuben Thomas <rrt@sc3d.org>.

  This library is API/ABI-compatible with that of the original libpaper by
  Yves Arrouye <Yves.Arrouye@marin.fdn.fr>, 1996, but it lacks the following
  APIs: defaultpapersizefile, systempapersizefile, paperlast, paperprev.

  This file is part of libpaper.

  This program is free software: you can redistribute it and/or modify it
  under the terms of the MIT license.

  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.
*/

#ifndef PAPER_H
#define PAPER_H

#include <stddef.h>

/* Allow the include file to be used directly from C++. */
#ifdef __cplusplus
extern "C" {
#endif

/* Opaque struct. */
struct paper;

enum paper_unit {
    PAPER_UNIT_PT,
    PAPER_UNIT_MM,
    PAPER_UNIT_IN,
    PAPER_NUM_UNITS,
    PAPER_UNIT_INVALID = -1
};

enum paper_error {
    PAPER_OK,
    PAPER_BAD_WIDTH,
    PAPER_BAD_HEIGHT,
    PAPER_BAD_UNIT,
    PAPER_MISSING_FIELD,
    PAPER_NOMEM = -1
};

extern size_t paper_lineno;
extern char *paper_specsfile;

/*
 * Initialize the library, and read configured paper sizes.
 * This function must be called before any other in the library.
 * Returns a paper_error value (PAPER_OK for success).
 */
int paperinit(void);

/*
 * Free any resources allocated by paperinit().
 * After calling it, no other library function may be called, except
 * paperinit().
 * Returns a paper_error value (PAPER_OK for success).
 */
int paperdone(void);

/*
 * Return the name of the given paper.
 */
const char *papername(const struct paper *paper);

/*
 * Return the width of the given paper in its natural units.
 */
double paperwidth(const struct paper *paper);

/*
 * Return the height of the given paper in its natural units.
 */
double paperheight(const struct paper *paper);

/*
 * Return the natural unit of the given paper.
 */
enum paper_unit paperunit(const struct paper *paper);

/*
 * Return the width of the given paper in PostScript points.
 */
double paperpswidth(const struct paper *paper);

/*
 * Return the height of the given paper in PostScript points.
 */
double paperpsheight(const struct paper *paper);

/*
 * Look up a paper size by name (case-insensitive).
 * Return the paper if found, or NULL if not.
 */
const struct paper *paperinfo(const char *papername);

/*
 * Look up a paper size by size (in PostScript points).
 * Return the paper if found, or NULL if not.
 */
const struct paper *paperwithsize(double pswidth, double psheight);

/*
 * Returns the current paper size, as specified in paper(1), or NULL if none
 * can be determined.
 */
const struct paper *defaultpaper(void);

/*
 * Deprecated, only for backwards compatibility. Returns the default
 * configured paper name.
 */
const char *defaultpapername(void);

/*
 * Deprecated, only for backwards compatibility; does the same as
 * defaultpapername(), but returns a value that must be freed.
 */
char *systempapername(void);

/*
 * Return the first paper in the list of known paper sizes.
 */
const struct paper *paperfirst(void);

/*
 * Return the next paper in the list of known paper sizes.
 */
const struct paper *papernext(const struct paper *paper);

/*
 * Return the name of the given unit.
 */
const char *paperunitname(enum paper_unit n);

/*
 * Return the conversion factor from pts to the given unit.
 */
double paperunitfactor(enum paper_unit n);

/*
 * Return the unit with the given name.
 */
enum paper_unit paperunitfromname(const char *name);

/*
 * Set prefix dir for the library for systems that can't auto-detect it.
 */
void papersetprefixdir(const char *new_prefix);

#ifdef __cplusplus
}
#endif

#endif
