package com.pdflib.cookbook.pcos;

import java.util.StringTokenizer;

import com.pdflib.pCOS;
import com.pdflib.pCOSException;

/**
 * Wrapper class for running the pCOS Cookbook examples.
 * <p>
 * This abstract class provides a wrapper to run pCOS Cookbook example code over
 * one or multiple files. The user of this class must implement the
 * example_code function.
 *
 * @version $Id: pcos_cookbook_example.java,v 1.7 2007/09/20 12:16:09 katja Exp $
 */

public abstract class pcos_cookbook_example {
    private static final int HEADER_LINE_LENGTH = 65;

    private String[] argv;
    private String readable_name;
    private String full_rcs_file_name;
    private String revision;
    private String search_path;

    /**
     * Constructor taking data for banner, search path and usage.
     *
     * @param argv
     *              array with input file names
     * @param readable_name
     *              one or two word human readable description of example
     * @param search_path
     *              this directory will be passed to pCOS as search path
     * @param full_rcs_file_name
     *              expanded $RCSfile CVS keyword
     * @param revision
     *              expanded $Revision CVS keyword
     */
    public pcos_cookbook_example(String[] argv, String readable_name,
        String search_path, String full_rcs_file_name, String revision) {
        this.argv = argv;
        this.readable_name = readable_name;
        this.full_rcs_file_name = full_rcs_file_name;
        this.revision = revision;
        this.search_path = search_path;
    }

    /**
     * Execute the wrapper that calls example_code for each file.
     *
     * This method is inteded to be called from the derived's class
     * main routine. It will check the args array
     * and prints a usage message if it is empty.
     * <p>
     * Otherwise it will create a pCOS object and call the
     * example_code routine for each filename argument.
     * <p>
     * If any document provokes a pCOSException the execute will
     * terminate and the remaining documents will not be processed.
     */
    protected void execute() {
        // expects "$RCSfile: pcos_cookbook_example.java,v $"
        StringTokenizer s = new StringTokenizer(full_rcs_file_name);
        s.nextToken();
        String rcs_file = s.nextToken();

        // Strip off ",v"
        StringTokenizer suffix_stripper = new StringTokenizer(rcs_file, ".");
        String class_name = suffix_stripper.nextToken();

        if (argv.length == 0) {
            System.err.println("usage: " + class_name + " <PDF file> ...");
            return;
        }

        String banner = readable_name + " (" + class_name + ".java, " +
            revision + "): ";
        System.out.print(banner);

        int dash_length = HEADER_LINE_LENGTH - banner.length();
        if (dash_length > 0) {
            StringBuffer buffer = new StringBuffer(dash_length);
            for (int i = 0; i < dash_length; i += 1) {
                buffer.append('-');
            }
            System.out.print(buffer.toString());
        }
        System.out.println();

        pCOS p = null;

        try {
            p = new pCOS();

            p.set_option("SearchPath=" + search_path);

            for (int i = 0; i < argv.length; i += 1) {
                example_code(p, argv[i]);
            }
        }
        catch (pCOSException e) {
            System.err.println("pCOS exception occurred:");
            System.err.println("[" + e.get_errnum() + "] " + e.get_apiname()
                    + ": " + e.get_errmsg());
        }
        catch (Exception e) {
            System.err.println(e.getMessage());
        }
        finally {
            if (p != null) {
                p.delete();
            }
        }
    }

    /**
     * The function that executes the actual Cookbook example code.
     *
     * The wrapper calls this method once for each file provided on the command
     * line. The wrapper passes a pCOS object create with
     * new pCOS(), and the pathname from the command line.
     *
     * @param p
     *            a valid pCOS object
     * @param filename
     *            the pathname of the current input document
     * @throws pCOSException
     *            a pCOS call threw an exception
     * @throws Exception
     *             the example code throws an exeption if it detects an error
     */
    public abstract void example_code(pCOS p, String filename)
        throws pCOSException, Exception;
}