/* ====================================================================
   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.
==================================================================== */

package org.apache.poi.hwpf.extractor;

import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.extractor.POIOLE2TextExtractor;
import org.apache.poi.hwpf.HWPFOldDocument;
import org.apache.poi.hwpf.converter.WordToTextConverter;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * Class to extract the text from old (Word 6 / Word 95) Word Documents.
 *
 * This should only be used on the older files, for most uses you
 *  should call {@link WordExtractor} which deals properly
 *  with HWPF.
 */
public final class Word6Extractor implements POIOLE2TextExtractor {
    private HWPFOldDocument doc;
    private boolean doCloseFilesystem = true;

    /**
     * Create a new Word Extractor
     * @param is InputStream containing the word file
     */
    public Word6Extractor(InputStream is) throws IOException {
        this( new POIFSFileSystem(is) );
    }

    /**
     * Create a new Word Extractor
     *
     * @param fs
     *            POIFSFileSystem containing the word file
     */
    public Word6Extractor( POIFSFileSystem fs ) throws IOException {
        this( fs.getRoot() );
    }

    /**
     * @deprecated Use {@link #Word6Extractor(DirectoryNode)} instead
     */
    @Deprecated
    public Word6Extractor( DirectoryNode dir, POIFSFileSystem fs ) throws IOException {
        this( dir );
    }

    public Word6Extractor( DirectoryNode dir ) throws IOException {
        this( new HWPFOldDocument( dir ) );
    }

    /**
     * Create a new Word Extractor
     * @param doc The HWPFOldDocument to extract from
     */
    public Word6Extractor(HWPFOldDocument doc) {
        this.doc = doc;
    }

    /**
     * Get the text from the word file, as an array with one String
     *  per paragraph
     */
    @Deprecated
    public String[] getParagraphText() {
        String[] ret;

        // Extract using the model code
        try {
            Range r = doc.getRange();

            ret = WordExtractor.getParagraphText(r);
        } catch (Exception e) {
            // Something's up with turning the text pieces into paragraphs
            // Fall back to ripping out the text pieces
            ret = new String[doc.getTextTable().getTextPieces().size()];
            for(int i=0; i<ret.length; i++) {
                ret[i] = doc.getTextTable().getTextPieces().get(i).getStringBuilder().toString();

                // Fix the line endings
                ret[i] = ret[i].replaceAll("\r", "\ufffe");
                ret[i] = ret[i].replaceAll("\ufffe","\r\n");
            }
        }

        return ret;
    }

    public String getText() {
        try {
            WordToTextConverter wordToTextConverter = new WordToTextConverter();
            wordToTextConverter.processDocument( doc );
            return wordToTextConverter.getText();
        } catch ( Exception exc ) {
            // fall-back
            StringBuilder text = new StringBuilder();

            for ( String t : getParagraphText() ) {
                text.append( t );
            }

            return text.toString();
        }
    }

    @Override
    public HWPFOldDocument getDocument() {
        return doc;
    }

    @Override
    public void setCloseFilesystem(boolean doCloseFilesystem) {
        this.doCloseFilesystem = doCloseFilesystem;
    }

    @Override
    public boolean isCloseFilesystem() {
        return doCloseFilesystem;
    }

    @Override
    public HWPFOldDocument getFilesystem() {
        return doc;
    }
}
