/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package ps;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;
import org.apache.xmlgraphics.ps.dsc.DSCException;
import org.apache.xmlgraphics.ps.dsc.tools.PageExtractor;
 
/**
 * Demonstrates how the DSC parser can be used to extract a series of pages from a DSC-compliant
 * PostScript file. For details how this works, please look into the PageExtractor class
 * where the actual functionality is located. This sample class only calls the code there.
 */
public class DSCProcessingExample1 {

    /**
     * Extracts a series of pages from a DSC-compliant PostScript file.
     * @param srcFile the source PostScript file
     * @param tgtFile the target file to write the extracted pages to
     * @param from the starting page number
     * @param to the ending page number
     * @throws IOException In case of an I/O error
     */
    public void extractPages(File srcFile, File tgtFile, int from, int to) throws IOException {
        InputStream in = new java.io.FileInputStream(srcFile);
        in = new java.io.BufferedInputStream(in);
        try {
            OutputStream out = new java.io.FileOutputStream(tgtFile);
            out = new java.io.BufferedOutputStream(out);
            try {
                PageExtractor.extractPages(in, out, from, to);
            } catch (DSCException e) {
                throw new RuntimeException(e.getMessage());
            } finally {
                IOUtils.closeQuietly(out);
            }
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    
    private static void showInfo() {
        System.out.println(
                "Call: DSCProcessingExample1 <source-file> <target-file> <from-page> <to-page>");
    }
    
    /**
     * Command-line interface
     * @param args command-line arguments
     */
    public static void main(String[] args) {
        try {
            File srcFile , tgtFile;
            int from, to;
            if (args.length >= 4) {
                srcFile = new File(args[0]);
                tgtFile = new File(args[1]);
                from = Integer.parseInt(args[2]);
                to = Integer.parseInt(args[3]);
            } else {
                throw new IllegalArgumentException("Invalid number of parameters!");
            }
            if (!srcFile.exists()) {
                throw new IllegalArgumentException("Source file not found: " + srcFile);
            }
            DSCProcessingExample1 app = new DSCProcessingExample1();
            app.extractPages(srcFile, tgtFile, from, to);
            System.out.println("File written: " + tgtFile.getCanonicalPath());
        } catch (IllegalArgumentException iae) {
            System.err.println(iae.getMessage());
            showInfo();
            System.exit(1);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

}
