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

import java.io.IOException;

import org.apache.poi.hslf.record.Document;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.record.SlidePersistAtom;
import org.apache.poi.hslf.record.TextBytesAtom;
import org.apache.poi.hslf.record.TextCharsAtom;
import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;

/**
 * Uses record level code to locate SlideListWithText entries.
 * Having found them, it sees if they have any text, and prints out
 *  what it finds.
 */
public final class SLWTTextListing {
    public static void main(String[] args) throws IOException {
        if(args.length < 1) {
            System.err.println("Need to give a filename");
            System.exit(1);
        }

        HSLFSlideShowImpl ss = new HSLFSlideShowImpl(args[0]);

        // Find the documents, and then their SLWT
        Record[] records = ss.getRecords();
        for(int i=0; i<records.length; i++) {
            if(records[i] instanceof Document) {
                Record docRecord = records[i];
                Record[] docChildren = docRecord.getChildRecords();
                for(int j=0; j<docChildren.length; j++) {
                    if(docChildren[j] instanceof SlideListWithText) {
                        System.out.println("Found SLWT at pos " + j + " in the Document at " + i);
                        System.out.println("  Has " + docChildren[j].getChildRecords().length + " children");

                        // Grab the SlideAtomSet's, which contain
                        //  a SlidePersistAtom and then a bunch of text
                        //  + related records
                        SlideListWithText slwt = (SlideListWithText)docChildren[j];
                        SlideListWithText.SlideAtomsSet[] thisSets = slwt.getSlideAtomsSets();
                        System.out.println("  Has " + thisSets.length + " AtomSets in it");

                        // Loop over the sets, showing what they contain
                        for(int k=0; k<thisSets.length; k++) {
                            SlidePersistAtom spa = thisSets[k].getSlidePersistAtom();
                            System.out.println("    " + k + " has slide id " + spa.getSlideIdentifier() );
                            System.out.println("    " + k + " has ref id " + spa.getRefID() );

                            // Loop over the records, printing the text
                            Record[] slwtc = thisSets[k].getSlideRecords();
                            for(int l=0; l<slwtc.length; l++) {
                                String text = null;
                                if(slwtc[l] instanceof TextBytesAtom) {
                                    TextBytesAtom tba = (TextBytesAtom)slwtc[l];
                                    text = tba.getText();
                                }
                                if(slwtc[l] instanceof TextCharsAtom) {
                                    TextCharsAtom tca = (TextCharsAtom)slwtc[l];
                                    text = tca.getText();
                                }

                                if(text != null) {
                                    text = text.replace('\r','\n');
                                    System.out.println("        ''" + text + "''");
                                }
                            }
                        }
                    }
                }
            }
        }
        
        ss.close();
    }
}
