/*---------------------------------------------------------------------------*
 |          Copyright (c) 2005-2010 PDFlib GmbH. All rights reserved.        |
 +---------------------------------------------------------------------------+
 |    This software may not be copied or distributed except as expressly     |
 |    authorized by PDFlib GmbH's general license agreement or a custom      |
 |    license agreement signed by PDFlib GmbH.                               |
 |    For more information about licensing please refer to www.pdflib.com.   |
 *---------------------------------------------------------------------------*/

/* $Id: TET.java,v 1.21.2.2 2012/02/21 21:44:57 rjs Exp $
 *
 * TET Java class
 */

package com.pdflib;

/** Text Extraction Toolkit (TET):
    Toolkit for extracting Text, Images, and Metadata from PDF Documents.
    <p>
    Note that this is only a syntax summary. For complete information
    please refer to the TET API reference manual which is available
    in the "doc" directory of the TET distribution.
    @author Rainer Schaaf
    @version 4.1
*/

public final class TET {

    // The initialization code for loading the TET shared library.
    // The library name will be transformed into something platform-
    // specific by the VM, e.g. libtet.so or tet.dll.

    static {
	try {
	    System.loadLibrary("tet");
	} catch (UnsatisfiedLinkError e) {
	    System.err.println(
	"Cannot load the TET shared library/DLL for Java.\n" +
	"Make sure to properly install the native TET library.\n\n" +
	"For your information, the current value of java.library.path is:\n" +
	 System.getProperty("java.library.path") + "\n");

	    throw e;
	}
    }

    // ------------------------------------------------------------------------
    // public char_info/image_info fields

    /** UTF-32 Unicode value of the current character.
    <p>
    It will be 0 if the corresponding UTF-16 value is the trailing value
    of a surrogate pair (i.e. if type=11).
    */
    public int uv;

    /** Type of the character.
    <p>
    The following types describe real
    characters which correspond to a glyph on the page. The values of all
    other properties/fields are determined by the corresponding glyph:
    <ul>
    <li>0 Normal character which corresponds to exactly one glyph</li>
    <li>1 Start of a sequence (e.g. ligature)</li>
    </ul>
    The following types describe artificial characters which do not
    correspond to a glyph on the page. The x and y fields will specify the
    most recent real character.s endpoint, the width field will be 0, and
    all other fields except uv will contain the values corresponding to the
    most recent real character:
    <ul>
    <li>10 Continuation of a sequence (e.g. ligature)</li>
    <li>11 (Deprecated and unused)</li>
    <li>12 Inserted word, line, or zone separator</li>
    </ul>
    */
    public int type;

    /** Indicates whether the glyph could be mapped to Unicode.
    <p>
    Usually false, but will be true if the original glyph could
    not be mapped to Unicode and has been replaced with the character
    specified as unknownchar.
    */
    public boolean unknown;

    /** Glyph attributes expressed as bits.
    <p>
    The bits can be combined:
    <ul>
    <li>bit 0 Geometric or semantic subscript</li>
    <li>bit 1 Geometric or semantic superscript</li>
    <li>bit 2 Drop cap character (initial large character at the start of
          a paragraph)</li>
    <li>bit 3 Glyph- or word-based shadow duplicate of this glyph has been removed</li>
    <li>bit 4 Glyph represents last character before hyphenation point</li>
    <li>bit 5 Hyphenation artifact (i.e. the hyphen character) which was
          removed unless fold={{_hyphenation keep}} was specified.</li>
    <li>bit 6 Glyph represents the character after hyphenation point</li>
    </ul>
    */
    public int attributes;

    /** x position of the glyph's or image's reference point.
    <p>
    x/y describe the position of the glyph's or image's reference point.
    <p>
    Text: The reference point is the lower left corner of the glyph box for
    horizontal writing mode, and the top center point for vertical writing
    mode. For artificial characters the x, y coordinates will be those of
    the end point of the most recent real character.
    <p>
    Images: The reference point is the lower left corner of the image.
    */
    public double x;

    /** y position of the glyph's or image's reference point.
    @see com.pdflib.TET#x
    */
    public double y;

    /** Width of glyph or image.
    <p>
    Text: Width of the corresponding glyph (for both horizontal and vertical
    writing mode). For artificial characters the width will be 0.
    <p>
    Images: Width of the image on the page in points, measured
    along the image's edges
    */
    public double width;

    /** Height of glyph or image.
    @see com.pdflib.TET#width
    */
    public double height;

    /** Direction of inline text progression or direction of the pixel rows.
    <p>
    Text: Direction of inline text progression in degrees measured
    counter-clockwise.
    For horizontal writing mode this is the direction of the text baseline;
    for vertical writing mode it is the digression from the standard -90&deg;
    direction. The angle will be in the range -180&deg; < alpha <= +180&deg;. For
    standard horizontal text as well as for standard text in vertical writing
    mode the angle will be 0&deg;.
    <p>
    Images: Direction of the pixel rows. The angle will be in the range
    -180&deg; < alpha <= +180&deg;. For upright images alpha will be 0&deg;.
    */
    public double alpha;

    /** Text slanting angle or direction of pixel columns relative to the perpendicular of alpha.
    <p>
    Text: Text slanting angle in degrees (counter-clockwise), relative to
    the perpendicular of alpha.
    The angle will be 0&deg; for upright text, and
    negative for italicized (slanted) text. The angle will be in the range
    -180&deg; < beta <= 180&deg;, but different from &plusmn;90&deg;. If abs(beta) > 90&deg;
    the text is mirrored at the baseline.
    <p>
    Images: Direction of the pixel columns, relative to the perpendicular of
    alpha. The angle will be in the range -180&deg; < beta <= +180&deg;, but different
    from &plusmn;90&deg;. For upright images beta will be in the range -90&deg;
    < beta < +90&deg;.  If abs(beta) > 90&deg; the image will be mirrored at the
    baseline.
    */
    public double beta;

    /** Index of the image in the pCOS pseudo object images[].
    <p>
    Detailed image properties can be retrieved via the entries in this
    pseudo object.
    */
    public int imageid;

    /** Index of the font in the fonts[] pseudo object.
    <p>
    fontid is never negative.
    */
    public int fontid;

    /** Size of the font (always positive).
    <p>
    The relation of this value to the actual height of glyphs is not fixed,
    but may vary with the font design. For most fonts the font size is chosen
    such that it encompasses all ascenders (including accented characters)
    and descenders.
    */
    public double fontsize;

    /** Text rendering mode.
    <ul>
    <li>0 fill text</li>
    <li>1 stroke text (outline)</li>
    <li>2 fill and stroke text</li>
    <li>3 invisible text (often used for OCR results)</li>
    <li>4 fill text and add it to the clipping path</li>
    <li>5 stroke text and add it to the clipping path</li>
    <li>6 fill and stroke text and add it to the clipping path</li>
    <li>7 add text to the clipping path</li>
    <ul>
    */
    public int textrendering;


    // ------------------------------------------------------------------------
    // public functions

    /** Create a new TET object.
	@exception com.pdflib.TETException May throw an exception in case
	of memory shortage.
     */
    public TET() throws TETException
    {
	tet = TET_new();
    }

    /** Release a document handle and all internal resources related to
	that document.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final void close_document(int doc) throws TETException
    {
	TET_close_document(tet, doc);
    }

    /** Release a page handle and all related resources.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final void close_page(int page) throws TETException
    {
	TET_close_page(tet, page);
    }

    /** Create a named virtual read-only file from data provided in memory.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final void create_pvf(String filename, byte[] data,
	String optlist) throws TETException
    {
	TET_create_pvf(tet, filename, data, optlist);
    }

    /** Delete a TET context and release all its internal resources.
	This should be called for cleanup when processing is done,
	and after a TETException occurred.
        This method may also be called by the finalizer, but it is safe to
	issue multiple calls.
     */
    public final void delete()
    {
	TET_delete(tet);
	tet = (long) 0;
    }

    /** Delete a named virtual file and free its data structures (but not the
        contents).
        @return  -1 if the virtual file exists but is locked, and
	          1 otherwise.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int delete_pvf(String filename) throws TETException
    {
        return TET_delete_pvf(tet, filename);
    }

    /** Get the name of the API function which caused an exception or failed.
       @return TETlib API function name
     */
    public final String get_apiname()
    {
        return TET_get_apiname(tet);
    }

    /** Get the text of the last thrown exception or the reason for a
	failed function call.
       @return TETlib error message
     */
    public final String get_errmsg()
    {
        return TET_get_errmsg(tet);
    }

    /** Get the number of the last thrown exception or the reason for a
	failed function call.
        @return TETlib error number
     */
    public final int get_errnum()
    {
        return TET_get_errnum(tet);
    }

    /** Get detailed information for the next character in the most recent
	text fragment.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int get_char_info(int page) throws TETException
    {
	return TET_get_char_info(tet, page);
    }

    /** Retrieve image data in memory.
        @return The data representing the image.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final byte[] get_image_data(int doc, int imageid, String optlist)
	throws TETException
    {
        return TET_get_image_data(tet, doc, imageid, optlist);
    }

    /** Retrieve information about the next image on the page (but not the
        actual pixel data).
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int get_image_info(int page) throws TETException
    {
	return TET_get_image_info(tet, page);
    }

    /** Get the next text fragment from a page's content.
        @return A string containing the next text fragment from the page.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final String get_text(int page) throws TETException
    {
	return TET_get_text(tet, page);
    }

    /** Query properties of a virtual file or the PDFlib Virtual Filesystem (PVF)
        @return The value of some file parameter as requested by keyword.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
    */
    public final double info_pvf(String filename, String keyword)
	throws TETException
    {
        return TET_info_pvf(tet, filename, keyword);
    }


    /** Open a PDF document from file for text extraction.
	@return -1 on error, and 1 otherwise
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int open_document(String filename, String optlist) throws
    TETException
    {
	return TET_open_document(tet, filename, optlist);
    }

    /** @deprecated use TET_create_pvf( ) and TET_open_document( ).
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int open_document_mem(byte[] data, String optlist) throws
    TETException
    {
	return TET_open_document_mem(tet, data, optlist);
    }

    /** Open a page for text extraction.
	@return -1 on error, and 1 otherwise
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int open_page(int doc, int pageno, String optlist)
    throws TETException
    {
	return TET_open_page(tet, doc, pageno, optlist);
    }

    /** Get the value of a pCOS path with type number or boolean.
        @return The numerical value of the parameter.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final double pcos_get_number(int doc, String path)
	throws TETException
    {
	return TET_pcos_get_number(tet, doc, path);
    }

    /** Get the value of a pCOS path with type name, string or boolean.
        @return The parameter's string value
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final String pcos_get_string(int doc, String path)
	throws TETException
    {
	return TET_pcos_get_string(tet, doc, path);
    }

    /** Get the contents of a pCOS path with type stream or fstream.
        @return The data contained in the stream.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final byte[] pcos_get_stream(int doc, String optlist, String path)
		throws TETException
    {
	return TET_pcos_get_stream(tet, doc, optlist, path);
    }

    /** Set one or more global options for TET.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final void set_option(String optlist) throws TETException
    {
	TET_set_option(tet, optlist);
    }

    /** Write image data to disk.
	@return -1 on error, and 1 otherwise
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int write_image_file(int doc, int imageid, String optlist)
    throws TETException
    {
	return TET_write_image_file(tet, doc, imageid, optlist);
    }

    /** Process a page and create TETML output.
	@return -1 on error, and 1 otherwise
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final int process_page(int doc, int pageno, String optlist)
    throws TETException
    {
	return TET_process_page(tet, doc, pageno, optlist);
    }

    /** Retrieve data from memory.
        @return A string containing the next chunk of data.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
     */
    public final byte[]  get_xml_data(int doc, String optlist)
	throws TETException
    {
        return TET_get_xml_data(tet, doc, optlist);
    }


    /** Convert a string in an arbitrary encoding to a Unicode string in various
        formats.
        @return The converted Unicode string.
	@exception com.pdflib.TETException May throw an exception for
	various reasons.
    */
    public final String convert_to_unicode(String inputformat, byte[] input, String optlist)
	throws TETException
    {
        return TET_convert_to_unicode(tet, inputformat, input, optlist);
    }



    // ------------------------------------------------------------------------
    // private functions

    private long tet;

    protected final void finalize()
    {
	TET_delete(tet);
	tet = (long) 0;
    }

    private final static native void TET_close_document(long jtet, int jdoc)
	    throws TETException;

    private final static native void TET_close_page(long jtet,
	    int jpage) throws TETException;

    private final static native void TET_create_pvf(long jtet,
	    String jfilename, byte[] jdata, String joptlist)
	    throws TETException;

    private final static native synchronized void TET_delete(long jtet);

    private final static native int TET_delete_pvf(long jtet,
	    String jfilename) throws TETException;

    private final static native String TET_get_apiname(long jtet);

    private final static native String TET_get_errmsg(long jtet);

    private final static native int TET_get_errnum(long jtet);

    private final static native byte[] TET_get_image_data(long jtet,
    	    int jdoc, int jimageid, String joptlist) throws TETException;

    // this must _not_ be "static" since it will fill the char_info fields
    private final native int TET_get_char_info(long jtet, int jpage)
	    throws TETException;

    // this must _not_ be "static" since it will fill the image_info fields
    private final native int TET_get_image_info(long jtet, int jpage)
	    throws TETException;

    private final static native String TET_get_text(long jtet,
	    int jpage) throws TETException;

    private final static native synchronized long TET_new() throws
            TETException;

    private final static native double TET_info_pvf(long jtet,
	    String filename, String jkeyword) throws TETException;

    private final static native int TET_open_document(long jtet,
	    String jfilename, String joptlist) throws TETException;

    private final static native int TET_open_document_mem(long jtet,
	    byte[] jdata, String joptlist) throws TETException;

    private final static native int TET_open_page(long jtet, int jdoc,
	    int jpageno, String joptlist) throws TETException;

    private final static native double TET_pcos_get_number(long jtet, int jdoc,
	    String jpath) throws TETException;

    private final static native String TET_pcos_get_string(long jtet, int jdoc,
	    String jpath) throws TETException;

    private final static native byte[] TET_pcos_get_stream(long jtet, int jdoc,
	    String optlist, String jpath) throws TETException;

    private final static native void TET_set_option(long jtet,
	    String joptlist) throws TETException;

    private final static native int TET_write_image_file(long jtet, int jdoc,
	    int jimageid, String joptlist) throws TETException;

    private final static native int TET_process_page(long jtet, int jdoc,
	    int jpageno, String joptlist) throws TETException;

    private final static native byte[] TET_get_xml_data(long jtet,
    	    int jdoc, String joptlist) throws TETException;

    private final static native String TET_convert_to_unicode(long jtet,
	    String jinputformat, byte[] input, String joptlist) throws TETException;
}
