/*
 * File:     Transcription2Tiger.java
 * Project:  MPI Linguistic Application
 * Date:     03 April 2006
 *
 * Copyright (C) 2001-2006  Max Planck Institute for Psycholinguistics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package mpi.eudico.client.util;

import mpi.eudico.client.annotator.export.ExportTigerDialog;

import mpi.eudico.server.corpora.clom.Annotation;
import mpi.eudico.server.corpora.clom.Tier;
import mpi.eudico.server.corpora.clom.Transcription;

import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;
import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;
import mpi.eudico.server.corpora.clomimpl.type.Constraint;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import javax.swing.JFrame;


/**
 * $Id: Transcription2Tiger.java,v 1.3 2006/03/23 09:24:38 klasal Exp $ exports annotation on
 * selected tiers into the Tiger Syntax Format (as leaf nodes) In "Tiger-terminology": annotations
 * will become feature values of terminal nodes
 *
 * @author $Author: klasal $
 * @version $Revision: 1.3 $
 */
public class Transcription2Tiger {
    private static final String wordFeature = "word";
    private static final String posFeature = "pos";
    private static final String morphFeature = "morph";
    public static final String[] features = new String[] {
            wordFeature, posFeature, morphFeature
        };

    /**
     * DOCUMENT ME!
     *
     * @param transcription DOCUMENT ME!
     * @param tierNames DOCUMENT ME!
     * @param file DOCUMENT ME!
     * @param encoding DOCUMENT ME!
     * @param beginTime DOCUMENT ME!
     * @param endTime DOCUMENT ME!
     *
     * @throws IOException DOCUMENT ME!
     */
    public static void exportTiers(Transcription transcription,
        String[] tierNames, String[] featureNames, File file, String encoding,
        long beginTime, long endTime) throws IOException {
        HashMap tierRelationHash = new HashMap();

        for (int i = 0; i < tierNames.length; i++) {
            TierImpl tier = (TierImpl) transcription.getTierWithId(tierNames[i]);
            String sentenceTierName = tier.getRootTier().getName();
            HashMap featureHash;

            if (tierRelationHash.containsKey(sentenceTierName)) {
                featureHash = (HashMap) tierRelationHash.get(sentenceTierName);
            } else {
                featureHash = new HashMap();
                tierRelationHash.put(sentenceTierName, featureHash);
            }

            //String featureName = (tier.getLinguisticType().getConstraints().getStereoType() == Constraint.TIME_SUBDIVISION)
            //    ? wordFeature : posFeature;
            featureHash.put(featureNames[i], tier);
        }

        exportTiers(transcription, tierRelationHash, file, encoding, beginTime,
            endTime);
    }

    /**
     * DOCUMENT ME!
     *
     * @param args DOCUMENT ME!
     */
    public static void main(String[] args) {
        String filename = "resources/testdata/elan/elan-example2.eaf";
        Transcription transcription = new TranscriptionImpl(filename);
        JFrame frame = new JFrame();
        ExportTigerDialog dialog = new ExportTigerDialog(frame, false,
                transcription, null);
        dialog.setVisible(true);
    }

    private static Vector getOrderedAnnotations(Transcription transcription,
        Set sentenceTierIds) {
        Vector annotations = new Vector();
        Iterator it = sentenceTierIds.iterator();

        annotations.addAll(((TierImpl) transcription.getTierWithId(
                (String) it.next())).getAnnotations());

        while (it.hasNext()) {
            Vector moreAnnotations = ((TierImpl) transcription.getTierWithId((String) it.next())).getAnnotations();

            for (int j = 0; j < moreAnnotations.size(); j++) {
                boolean added = false;

                for (int k = 0; k < annotations.size(); k++) {
                    if (((Annotation) annotations.get(k)).getBeginTimeBoundary() > ((Annotation) moreAnnotations.get(
                                j)).getBeginTimeBoundary()) {
                        annotations.add(k, moreAnnotations.get(j));
                        added = true;

                        break;
                    }
                }

                if (!added) {
                    annotations.add(moreAnnotations.get(j));
                }
            }
        }

        return annotations;
    }

    /**
     * DOCUMENT ME!
     *
     * @param transcription DOCUMENT ME!
     * @param tierRelationHash DOCUMENT ME!
     * @param file DOCUMENT ME!
     * @param beginTime DOCUMENT ME!
     * @param endTime DOCUMENT ME!
     *
     * @throws IOException DOCUMENT ME!
     */
    private static void exportTiers(Transcription transcription,
        HashMap tierRelationHash, File file, String encoding, long beginTime,
        long endTime) throws IOException {
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(file), encoding));
        writer.write(
            "<?xml version=\"1.0\" encoding =\"UTF-8\" standalone=\"yes\"?>\n");
        writer.write("<corpus id=\"" + transcription.getName() + "\">\n");
        writer.write("<body>\n");

        Vector annotations = getOrderedAnnotations(transcription,
                tierRelationHash.keySet());

        for (int i = 0; i < annotations.size(); i++) {
            Annotation sentenceAnnotation = (Annotation) annotations.get(i);

            if ((beginTime <= sentenceAnnotation.getBeginTimeBoundary()) &&
                    (sentenceAnnotation.getEndTimeBoundary() <= endTime)) {
                writer.write("<s id=\"" + sentenceAnnotation.getId() + "\">\n");
                writer.write("<graph>\n");
                writer.write("<terminals>\n");

                HashMap featureHash = (HashMap) tierRelationHash.get(sentenceAnnotation.getTier()
                                                                                       .getName());
                Vector wordAnnotations = sentenceAnnotation.getChildrenOnTier((Tier) featureHash.get(
                            wordFeature));

                for (int j = 0; j < wordAnnotations.size(); j++) {
                    writer.write("<t ");

                    Annotation wordAnnotation = (Annotation) wordAnnotations.get(j);

                    writer.write("id=\"" + wordAnnotation.getId() + "\" ");

                    writer.write(wordFeature + "=\"" +
                        wordAnnotation.getValue() + "\"");

                    if (featureHash.containsKey(posFeature)) {
                        Vector posAnnotations = wordAnnotation.getChildrenOnTier((Tier) featureHash.get(
                                    posFeature));

                        if (posAnnotations.size() > 0) {
                            Annotation posAnnotation = (Annotation) posAnnotations.get(0);
                            writer.write(" " + posFeature + "=\"" +
                                posAnnotation.getValue() + "\"");
                        }
                    }

                    writer.write("/>\n");
                }

                writer.write("</terminals>\n");
                writer.write("</graph>\n");
                writer.write("</s>\n");
            }
        }

        writer.write("</body>\n");
        writer.write("</corpus>");

        writer.flush();
        writer.close();
    }
}
