package pl.edu.icm.cermine;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import pl.edu.icm.cermine.exception.AnalysisException;
import pl.edu.icm.cermine.structure.*;
import pl.edu.icm.cermine.structure.model.BxDocument;
import pl.edu.icm.cermine.structure.tools.BxModelUtils;


/**
 * Document geometric structure extractor. Extracts the geometric hierarchical structure
 * (pages, zones, lines, words and characters) from a PDF file and stores it as a BxDocument object.
 *
 * @author Dominika Tkaczyk
 */
public class PdfBxStructureExtractor implements DocumentStructureExtractor {

    /** individual character extractor */
    private CharacterExtractor characterExtractor;
    
    /** document object segmenter */
    private DocumentSegmenter documentSegmenter;
    
    /** reading order resolver */
    private ReadingOrderResolver roResolver;
    
    /** iniial zone classifier */
    private ZoneClassifier initialClassifier;


    public PdfBxStructureExtractor() throws AnalysisException {
        characterExtractor = new ITextCharacterExtractor();
        documentSegmenter = new DocstrumSegmenter();
        roResolver = new HierarchicalReadingOrderResolver();
        
        InputStreamReader modelISRI = new InputStreamReader(PdfBxStructureExtractor.class
				.getResourceAsStream("/pl/edu/icm/cermine/structure/svm_initial_classifier"));
        BufferedReader modelFileI = new BufferedReader(modelISRI);
        InputStreamReader rangeISRI = new InputStreamReader(PdfBxStructureExtractor.class
		        .getResourceAsStream("/pl/edu/icm/cermine/structure/svm_initial_classifier.range"));
        BufferedReader rangeFileI = new BufferedReader(rangeISRI);
        initialClassifier = new SVMInitialZoneClassifier(modelFileI, rangeFileI);
    }
    
    public PdfBxStructureExtractor(InputStream model, InputStream range) throws AnalysisException {
        characterExtractor = new ITextCharacterExtractor();
        documentSegmenter = new DocstrumSegmenter();
        roResolver = new HierarchicalReadingOrderResolver();
        
        InputStreamReader modelISRI = new InputStreamReader(model);
        BufferedReader modelFileI = new BufferedReader(modelISRI);
        InputStreamReader rangeISRI = new InputStreamReader(range);
        BufferedReader rangeFileI = new BufferedReader(rangeISRI);
        initialClassifier = new SVMInitialZoneClassifier(modelFileI, rangeFileI);
    }

    public PdfBxStructureExtractor(CharacterExtractor glyphExtractor, DocumentSegmenter pageSegmenter, 
            ReadingOrderResolver roResolver, ZoneClassifier initialClassifier) {
        this.characterExtractor = glyphExtractor;
        this.documentSegmenter = pageSegmenter;
        this.roResolver = roResolver;
        this.initialClassifier = initialClassifier;
    }
    
    /**
     * Extracts the geometric structure from a PDF file and stores it as BxDocument.
     * 
     * @param stream
     * @return BxDocument object storing the geometric structure
     * @throws AnalysisException 
     */
    @Override
    public BxDocument extractStructure(InputStream stream) throws AnalysisException {
        BxDocument doc = characterExtractor.extractCharacters(stream);
        doc = documentSegmenter.segmentDocument(doc);
        BxModelUtils.setParents(doc);
        doc = roResolver.resolve(doc);
        return initialClassifier.classifyZones(doc);
    }

    public void setGlyphExtractor(CharacterExtractor glyphExtractor) {
        this.characterExtractor = glyphExtractor;
    }

    public void setInitialClassifier(ZoneClassifier initialClassifier) {
        this.initialClassifier = initialClassifier;
    }

    public void setPageSegmenter(DocumentSegmenter pageSegmenter) {
        this.documentSegmenter = pageSegmenter;
    }

    public void setRoResolver(ReadingOrderResolver roResolver) {
        this.roResolver = roResolver;
    }
   
}
@@ -72,54 +72,305 @@
 .io.
-InputStream;%0Aimport java.io.InputStreamReader;
+BufferedWriter;%0Aimport java.io.FileInputStream;%0Aimport java.io.FileNotFoundException;%0Aimport java.io.FileWriter;%0Aimport java.io.IOException;%0Aimport java.io.InputStream;%0Aimport java.io.InputStreamReader;%0A%0Aimport org.jdom.Element;%0Aimport org.jdom.output.Format;%0Aimport org.jdom.output.XMLOutputter;%0A
 %0Aimp
@@ -417,24 +417,85 @@
 sException;%0A
+import pl.edu.icm.cermine.exception.TransformationException;%0A
 import pl.ed
@@ -631,16 +631,92 @@
 lUtils;%0A
+import pl.edu.icm.cermine.structure.transformers.BxDocumentToTrueVizWriter;%0A
 %0A%0A/**%0A *
@@ -4312,13 +4312,731 @@
 ;%0A    %7D%0A
+    %0A    public static void main(String%5B%5D args) throws AnalysisException, IOException, TransformationException %7B%0A    %09if(args.length != 1)%7B%0A    %09%09System.err.println(%22USAGE: program FILE_PATH%22);%0A    %09%09System.exit(1);%0A    %09%7D%0A%0A    %09PdfBxStructureExtractor extractor = new PdfBxStructureExtractor();%0A    %09InputStream in = new FileInputStream(args%5B0%5D);%0A    %09BxDocument result = extractor.extractStructure(in);%0A    %09%0A%09%09FileWriter fstream = new FileWriter(%22PdfBxStructureExtractor_out.xml%22);%0A%09%09BufferedWriter out = new BufferedWriter(fstream);%0A    %09BxDocumentToTrueVizWriter writer = new BxDocumentToTrueVizWriter();%0A%09%09out.write(writer.write(result.getPages()));%0A    %09writer.write(result.getPages());%0A    %09out.close();%0A    %7D%0A
    %0A%7D

add usage example