package org.freehep.graphicsio.pdf.test;

import java.io.*;
import java.util.*;

import org.freehep.graphicsio.pdf.*;

/**
 * This class tests the lower-level PDF Writer interfaces.
 * It simply writes a document with several pages, including
 * some text and graphics.
 * <p>
 * @author Mark Donszelmann
 * @version $Id: freehep-graphicsio-pdf/PDFWriterLowLevelTest.java 967bf3619090 2005/12/01 05:41:40 duns $
 */
public class PDFWriterLowLevelTest {

    public static void main(String[] args) throws Exception {
        FileOutputStream out = new FileOutputStream("PDFWriterLowLevelTest.pdf");

        // PDF file
        PDFWriter pdf = new PDFWriter(out, "1.3");
        pdf.comment("PDFGraphicsTest file generated by PDFWriterLowLevelTest, Freehep lib");
        
        // info
        PDFDictionary info = pdf.openDictionary("DocInfo");
        info.entry("Title", "PDFWriter LowLevel Test Output");
        info.entry("Author", "Mark Donszelmann");
        info.entry("Subject", "LowLevel Test File of the PDFWriter of the FreeHEP library");
        info.entry("Keywords", "PDFWriter; FreeHEP");
        info.entry("Creator", "org.freehep.graphicsio-pdf.PDFWriter");
        info.entry("CreationDate", Calendar.getInstance());
        pdf.close(info);
        
        // catalog
        PDFDictionary catalog = pdf.openDictionary("Catalog");
        catalog.entry("Type", pdf.name("Catalog"));
        catalog.entry("Outlines", pdf.ref("Outlines"));
        catalog.entry("Pages", pdf.ref("RootPage"));
        catalog.entry("PageMode", pdf.name("UseOutlines"));
        catalog.entry("ViewerPreferences", pdf.ref("Preferences"));
        pdf.close(catalog);
        
        // preferences
        PDFDictionary prefs = pdf.openDictionary("Preferences");
        prefs.entry("FitWindow", false);
        prefs.entry("CenterWindow", false);
        pdf.close(prefs);
        
        // outlines
        PDFDictionary outlines = pdf.openDictionary("Outlines");
        outlines.entry("Type", pdf.name("Outlines"));
        outlines.entry("Count", 0);
        pdf.close(outlines);
        
        // pages
        PDFDictionary pages = pdf.openDictionary("RootPage");
        pages.entry("Type", pdf.name("Pages"));
        pages.entry("Kids", new Object[] {pdf.ref("FirstPage"), pdf.ref("SecondPage")});
        pages.entry("Count", 2);
        pages.entry("MediaBox", new int[] {0, 0, 612, 792});
        PDFDictionary resources = pages.openDictionary("Resources");
        resources.entry("ProcSet", pdf.ref("OurPageProcSet"));
        PDFDictionary fontList = resources.openDictionary("Font");
        fontList.entry("F1", pdf.ref("Helvetica"));
        resources.close(fontList);
        pages.close(resources);
        pdf.close(pages);
        
        // first page
        PDFDictionary firstPage = pdf.openDictionary("FirstPage");
        firstPage.entry("Type", pdf.name("Page"));
        firstPage.entry("Parent", pdf.ref("RootPage"));
        firstPage.entry("Contents", pdf.ref("FirstPageContent"));
        pdf.close(firstPage);

        // first page content
        PDFStream first = pdf.openStream("FirstPageContent");
        first.beginText();
        first.font(pdf.name("F1"), 24);
        first.text(100, 100);
        first.show("Hello");
        first.show(" World");
        first.endText();
        pdf.close(first);
                
        // second page
        PDFDictionary secondPage = pdf.openDictionary("SecondPage");
        secondPage.entry("Type", pdf.name("Page"));
        secondPage.entry("Parent", pdf.ref("RootPage"));
        secondPage.entry("Contents", pdf.ref("SecondPageContent"));
        pdf.close(secondPage);

        // second page content
        PDFStream second = pdf.openStream("SecondPageContent");
        second.comment("Draw a black line segment, using the default line width.");
        second.move(150, 250);
        second.line(150, 350);
        second.stroke();
        second.comment("Draw a thicker, dashed line segment.");
        second.width(4);
        second.comment("Set line width to 4 points");
        second.dash(new int[] {4,6}, 0);
        second.comment("Set dash pattern to 4 units on, 6 units off");
        second.move(150, 250);
        second.line(400, 250);
        second.stroke();
        second.dash(new int[0], 0);
        second.comment("Reset dash pattern to a solid line");
        second.width(1); 
        second.comment("Reset line width to 1 unit");
        second.comment("Draw a rectangle with a 1 unit red border, filled with light blue.");
        second.colorSpaceStroke(1.0, 0.0, 0.0);
        second.comment("Red for stroke color");
        second.colorSpace(0.5, 0.75, 1.0);
        second.comment("Light blue for fill color");
        second.rectangle(200, 300, 50, 75);
        second.fillAndStroke();
        second.comment("Draw a curve filled with gray and with a colored border.");
        second.colorSpaceStroke(0.5, 0.1, 0.2);
        second.colorSpace(0.7);
        second.move(300, 300);
        second.cubic(300, 400, 400, 400, 400, 300);
        second.closeFillAndStroke();
        pdf.close(second);
                
        // our page proc set
        pdf.object("OurPageProcSet", new Object[] {pdf.name("PDF"), pdf.name("Text")});
        
        // font
        PDFDictionary font = pdf.openDictionary("Helvetica");
        font.entry("Type", pdf.name("Font"));
        font.entry("Subtype", pdf.name("Type1"));
        font.entry("Name", pdf.name("F1"));
        font.entry("BaseFont", pdf.name("Helvetica"));
        pdf.close(font);
        
        // write xref table and trailer      
        pdf.close("Catalog", "DocInfo");
        out.close();
    }
}
