/*********************************************************************

SYBREX SYSTEMS INCORPORATED
Copyright (C) 2005 Sybrex Systems Incorporated
All rights reserved.

NOTICE: Sybrex permits you to use, modify, and distribute this file
in accordance with the terms of the Sybrex license agreement
accompanying it. If you have received this file from a source other
than Sybrex, then your use, modification, or distribution of it
requires the prior written permission of Sybrex.

----------------------------------------------------------------------
main.c
*********************************************************************/

#include <stdio.h>          /* Use standard Input/Output Console API */

#include "VSLibA.h"         /* Use Versy PDF Library */
#include "VSExcept.h"       /* Use Exceptions API */
#include "VSError.h"        /* Use Errors API */
#include "VSDocA.h"         /* Use PDF Document API */
#include "VSFontA.h"        /* Use Common Versy PDF Routines */
#include "VSPageA.h"        /* Use PDF Page Document API */
#include "VSCanvasA.h"      /* Use Content Drawing API */
#include "VSActionA.h"      /* Use Actions API */
#include "VSOutlineA.h"     /* Use Outline API */

#define PageWidth   595    /* Page width definition */
#define PageHeight  842    /* Page height definition */
/* Determination of graphics objects coordinates, normalized to 100 */
#define cx(x) (PageWidth*(x)/100)
#define cy(y) (PageHeight*(y)/100)

#define rnd ((ppReal)rand()/(ppReal)RAND_MAX) /* Random number from 0 to 1 */

#define PageCount 164
char *PageContentName[ PageCount ] = {
                    "Contents",
                    "Preface",
                    "1 Introduction",
                        "1.1 About PDF format",
                        "1.2 PDF 1.6 Features",
                        "1.3 Related Publications",
                        "1.4 About Versy PDF Library",
                    "2 Overview",
                        "2.1 Imaging Model",
                        "2.2 Other General Properties",
                        "2.3 Creating PDF",
                        "2.4 PDF and the PostScript Language",
                    "3 Versy PDF Library",
                        "3.1 Configuration",
                            "3.1.1 Set Platform",
                            "3.1.2 Set Library Properties",
                        "3.2 Structures",
                            "3.2.1 PDF Library Structure",
                            "3.2.2 PDF Document Structure",
                            "3.2.3 Base PDF Data Types",
                            "3.2.4 Base PDF Data Objects",
                            "3.2.5 Error Types",
                            "3.2.6 Exception Types",
                            "3.2.7 Base processing routines",
                            "3.2.8 Versy PDF Name Space",
                        "3.3 Models",
                            "3.3.1 Graphics",
                                "3.3.1.1 Graphics Objects",
                                "3.3.1.2 Coordinate Systems",
                                    "3.3.1.2.1 Coordinate Spaces",
                                        "3.3.1.2.1.1 Device Space",
                                        "3.3.1.2.1.2 User Space",
                                        "3.3.1.2.1.3 Other Coordinate Spaces",
                                        "3.3.1.2.1.4 Relationships among Coordinate Spaces",
                                    "3.3.1.2.2 Common Transformations",
                                    "3.3.1.2.3 Transformation Matrices",
                                "3.3.1.3 Graphics State",
                                    "3.3.1.3.1 Graphics State Stack",
                                    "3.3.1.3.2 Details of Graphics State Parameters",
                                        "3.3.1.3.2.1 Line Width",
                                        "3.3.1.3.2.2 Line Cap Style",
                                        "3.3.1.3.2.3 Line Join Style",
                                        "3.3.1.3.2.4 Miter Limit",
                                        "3.3.1.3.2.5 Line Dash Pattern",
                                    "3.3.1.3.3 Graphics State Operators",
                                    "3.3.1.3.4 Graphics State Parameter Dictionaries",
                                "3.3.1.4 Path Construction and Painting",
                                "3.3.1.5 Color Spaces",
                                "3.3.1.6 Patterns",
                                "3.3.1.7 External Objects",
                                "3.3.1.8 Images",
                                "3.3.1.9 Form XObjects",
                                "3.3.1.10 Optional Content",
                            "3.3.2 Text",
                                "3.3.2.1 Organization and Use of Fonts",
                                    "3.3.2.1.1 Basics of Showing Text",
                                    "3.3.2.1.2 Achieving Special Graphical Effects",
                                    "3.3.2.1.3 Glyph Positioning and Metrics",
                                "3.3.2.2 Text State Parameters and Operators",
                                    "3.3.2.2.1 Character Spacing",
                                    "3.3.2.2.2 Word Spacing",
                                    "3.3.2.2.3 Horizontal Scaling",
                                    "3.3.2.2.4 Leading",
                                    "3.3.2.2.5 Text Rendering Mode",
                                    "3.3.2.2.6 Text Rise",
                                    "3.3.2.2.7 Text Knockout",
                                "3.3.2.3 Text Objects",
                                    "3.3.2.3.1 Text-Positioning Operators",
                                    "3.3.2.3.2 Text-Showing Operators",
                                    "3.3.2.3.3 Text Space Details",
                                "3.3.2.4 Variable text",
                            "3.3.3 Fonts",
                                "3.3.3.1 Introduction to Font Data Structures",
                                "3.3.3.2 Simple Fonts",
                                    "3.3.3.2.1 Type 1 Fonts",
                                    "3.3.3.2.2 TrueType Fonts",
                                    "3.3.3.2.3 Font Subsets",
                                    "3.3.3.2.4 Type 3 Fonts",
                                    "3.3.3.2.5 Character Encoding",
                                "3.3.3.3 Composite Fonts",
                                "3.3.3.4 Font Descriptors",
                            "3.3.4 Drawing",
                                "3.3.4.1 Graphics Operator categories",
                                    "3.3.4.1.1 General graphics state operators",
                                    "3.3.4.1.2 Special graphics state operators",
                                    "3.3.4.1.3 Path construction operators",
                                    "3.3.4.1.4 Path painting operators",
                                    "3.3.4.1.5 Clipping paths operators",
                                    "3.3.4.1.6 Text objects operators",
                                    "3.3.4.1.7 Text state operators",
                                    "3.3.4.1.8 Text positioning operators",
                                    "3.3.4.1.9 Text showing operators",
                                    "3.3.4.1.10 Type 3 fonts operators",
                                    "3.3.4.1.11 Color operators",
                                    "3.3.4.1.12 Shading patterns operators",
                                    "3.3.4.1.13 Inline images operators",
                                    "3.3.4.1.14 XObjects operators",
                                    "3.3.4.1.15 Marked content operators",
                                    "3.3.4.1.16 Compatibility operators",
                                "3.3.4.2 Page Content",
                                "3.3.4.3 Control Content",
                                "3.3.4.4 Appearance Stream",
                                "3.3.4.5 Operator Summary",
                            "3.3.5 Images",
                                "3.3.5.1 Image Parameters",
                                "3.3.5.2 Sample Representation",
                                "3.3.5.3 Image Coordinate System",
                                "3.3.5.4 Image Dictionaries",
                                    "3.3.5.4.1 Decode Arrays",
                                    "3.3.5.4.2 Image Interpolation",
                                    "3.3.5.4.3 Alternate Images",
                                "3.3.5.5 Masked Images",
                                    "3.3.5.5.1 Stencil Masking",
                                    "3.3.5.5.2 Explicit Masking",
                                    "3.3.5.5.3 Color Key Masking",
                                "3.3.5.6 Inline Images",
                            "3.3.6 Composite models",
                        "3.4 Application Program Interface (API)",
                            "3.4.1 PDF Library API",
                            "3.4.2 PDF Document API",
                            "3.4.3 PDF Page API",
                            "3.4.4 PDF Exception API",
                            "3.4.5 PDF Files API",
                            "3.4.6 PDF Data API",
                            "3.4.7 PDF Connection API",
                        "3.5 Features",
                            "3.5.1 Graphic States",
                            "3.5.2 Actions",
                            "3.5.3 Annotations",
                            "3.5.4 AcroForm (Interactive Objects)",
                                "3.5.4.1 Edit Box",
                                "3.5.4.2 Push Button",
                                "3.5.4.3 Check Box",
                                "3.5.4.4 Radio Button",
                                "3.5.4.5 Combo Box",
                                "3.5.4.6 List Box",
                                "3.5.4.7 Signatures",
                                    "3.5.4.7.1 Invisible Document Signature",
                                    "3.5.4.7.2 Signature Stamp",
                                    "3.5.4.7.3 Encode filters",
                                    "3.5.4.7.4 RSA encrypting and rights",
                                "3.5.4.8 Compositing interactive forms",
                            "3.5.5 Outlines",
                            "3.5.6 Threads and Articles",
                            "3.5.8 Security",
                                "3.5.8.1 Permissions",
                                "3.5.8.2 Encrypting key",
                                "3.5.8.3 Passwords",
                                "3.5.8.4 User's rights",
                                "3.5.8.5 Owner's rights",
                            "3.5.9 Packing PDF Objects",
                            "3.5.10 Linearizing PDF Document",
                            "3.5.11 Multimedia",
                                "3.5.11.1 Sound",
                                "3.5.11.2 Video",
                            "3.5.12 Other Features",
                        "3.6 Versy PDF Library Conception",
                    "4 Appendix",
                        "4.1 Versy PDF Library Functions List",
                        "4.2 Implementation Limits",
                        "4.3 PDF Application Samples",
                        "4.4 PDF Files Examples",
                    "Bibliography",
                    "Index"
};

ppInt8 ParseOutlineStrings( char *PrevOutline, char *CurrOutline )
{
    ppInt32 Length, i = 0;

    if ( strlen( CurrOutline ) < strlen( PrevOutline ) )
        Length = (ppInt32)strlen( CurrOutline );
    else
        Length = (ppInt32)strlen( PrevOutline );

    while (( i < Length ) && ( PrevOutline[i] == CurrOutline[i] ))
        i++;

    if ( i == 0 )
        return -2;

    if ( i == Length )
        return 0;

    if (( PrevOutline[i] == ' ' ) && ( CurrOutline[i] == '.' ))
        return 1;

    if (( PrevOutline[i] == '.' ) && ( CurrOutline[i] == ' ' ))
        return -1;

    if (( PrevOutline[i+1] == '.' ) && ( CurrOutline[i+1] == ' ' ))
        return -1;

    return 0;
}

int main()
{
    PDFLibHandle	PDFLibrary;     /* PDF Library Handle */
	PDFDocHandle	Doc = NULL;     /* PDF Document Handle */
    PBXHandle       PaintBox;       /* Handle of Paint Box for Content Drawing */

    PDFOutlineHandle PDFRootOutline;  /* Outline Handle of List Root */
    PDFOutlineHandle PDFParentOutline;/* Outline Handle of Current Parent Item */
    PDFOutlineHandle PDFChildOutline; /* Outline Handle of Current Child Item */
    
    PDFExplicitDest ExplicitDestination; /* Variable Destination link */
    char            TextString[ 255 ];   /* Composite temporary text string */

    ppInt32         ErrorCode;      /* Check Error Code */
    ppInt32         i, j;           /* Variable counter */

    PDFLibrary = InitPDFLibrary( NULL, NULL );  /* Initialize PDF Library */
    PDFTRY( PDFLibrary )                        /* On error keep exception */

        Doc = PDFDocCreate( PDFLibrary );   /* Create new destination PDF file */
        PDFDocSetAutoLaunch( Doc, true );   /* Launch destination PDF file after work */

        /* Initialize Outline List by Creation Outline Root */
        PDFRootOutline = PDFParentOutline = PDFOutlineAddNewChild( Doc, PDFDocGetOutlineRoot( Doc ) );
        /* Set root title as "Versy PDF Library " */
        PDFOutlineSetTitle( Doc, PDFRootOutline, "Versy PDF Reference", 19 );
        /* Initialize number generation : rnd is number from 0 to 1 */
        srand( 0 );

        /* Create pages on each outline item */
        for ( i = 0; i < PageCount; i++ ) {
            /* Create new page in PDF document */
            PaintBox = PDFPageCreatePaintBox( Doc, PDFDocAppendPage( Doc, PageWidth, PageHeight ), 72 ); /* Create Page Content PaintBox with default resolution ( 72 dpi )*/
            /* Save the current graphics state on the graphics state stack. */
            PBXStateStore( PaintBox );
            /* Out text with render mode */
            PBXSetTextRenderingMode( PaintBox, 2 );
            /* Set the text font as Helvetica Bold, size is 4% of page height */
            PBXSetActiveFont( PaintBox, PDFFontAppend14Standard( Doc, stdfHelveticaBold, etStandardEncoding ),
                cy(3), false, false );
            /* Set the stroking Color as Dark Green */
            PBXSetStrokeColor( PaintBox, ULRGBToColor( rnd, rnd, rnd ) );
            /* Text Color set a Light Yellow */
            PBXSetFillColor( PaintBox, ULRGBToColor( rnd, rnd, rnd ) );
            /* Output text of title on top-center site of page */
            PBXTextOut( PaintBox, cx(50) - PBXGetTextWidth( PaintBox, PageContentName[ i ] ) / 2, cy(3), 0,
                PageContentName[ i ] );
            /* Set random line width */
            PBXSetLineWidth( PaintBox, cy( 3 * rnd ) );
            /* Set random line RGB-color */
            PBXSetStrokeColor( PaintBox, ULRGBToColor( rnd, rnd, rnd ) );
            /* Set random dash mode for drawing lines */
            /* Generate dash string */
            sprintf( TextString, "[%d %d %d %d] 0", 1 + (ppInt32)( rnd * 20 ), 1+(ppInt32)( rnd * 20 ),
                1 + (ppInt32)( rnd * 20 ), 1 + (ppInt32)( rnd * 20 ) );
            /* Apply dash style */
            PBXSetDash( PaintBox, TextString );
            /* Draw 40 lines on each page with different style */
            for ( j = 5; j < 45; j++ ) {
                /* Set point on page content */
                PBXMoveTo( PaintBox, cx( 10 ), cy( 2 * j ) );
                /* Draw horizontal line */
                PBXLineTo( PaintBox, cx( 90 ), cy( 2 * j ) );
            }
            /* Paint lines */
            PBXStroke( PaintBox );
            /* Restore the graphics state by removing the most recently saved state
            from the stack and making it the current state.*/
            PBXStateRestore( PaintBox );
            PBXClose( PaintBox, true ); /* Free PaintBox of Page Content */

            if ( i > 0 ) {  /* case location on current item title by text strings */
                switch( ParseOutlineStrings( PageContentName[ i - 1 ] , PageContentName[ i ] ) ) {
                case -2 :
                    /* Current outline link to outline root */
                    PDFParentOutline = PDFRootOutline;
                    break;
                case -1 :
                    /* Current outline link to grand-parent */
                    PDFParentOutline = PDFOutlineGetParent( Doc, PDFParentOutline );
                    break;
                case 1 :
                    /* Current outline link to child */
                    PDFParentOutline = PDFChildOutline;
                    break;
                default:; /* else link to simple parent */
                }
            }
            /* Create new outline item and link it */
            PDFChildOutline = PDFOutlineAddNewChild( Doc, PDFParentOutline );
            /* Set outline title from const text string array */
            PDFOutlineSetTitle( Doc, PDFChildOutline, PageContentName[ i ], (ppInt32)strlen( PageContentName[ i ] ) );
            /* Fit destination page to width */
            ExplicitDestination.Type = edtFitH;
            /* Page number i */
            ExplicitDestination.Page = i;
            /* Link to top of the page */
            ExplicitDestination.a = cy( 100 );
            /* Destination link to outline item as action */
            PDFOutlineSetAction( Doc, PDFChildOutline, PDFActionNewGoToDestination( Doc, ExplicitDestination ) );
        }

        /* Save destination PDF file as "outlines.pdf" in current path */
        PDFDocSaveToFile( Doc, "../Data/out/Outlines.pdf" );
    PDFFINALLY( PDFLibrary ) /* Do further if haven't PDF Library Exceptions */
		if ( Doc ) PDFDocClose ( Doc ); /* Close PDF Document and free memory */
		ErrorCode = PDFLASTERROR( PDFLibrary ); /* Check last error, if 0 then finished successfully */
        DonePDFLibrary( &PDFLibrary );/* Free PDF Library */
    PDFTRYEND( PDFLibrary ); /* End of try...end block */
    return ErrorCode; /* Return Error Code as program result */
}