/*
 * $Id: SoWordDocConverter.java,v 1.8 2006/06/06 20:36:00 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: SoWordDocConverter.java,v $
 * Revision 1.8  2006/06/06 20:36:00  marbobo
 * + Mögliche NPE abgefangen
 *
 * Revision 1.7  2006/04/04 07:54:08  korowa
 * Konvertierung ins PDF-Format hinzugefügt.Nur erlaubte Konvertierungen werden durchgeführt(DocConverter:conversions) bzw. zurückgeliefert.
 *
 * Revision 1.6  2004/11/10 15:02:43  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.5  2004/06/27 17:12:46  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.4  2003/11/29 22:13:52  koppy
 * InputStreams in VKCInputStream gekappselt
 *
 * Revision 1.3  2003/09/24 15:00:14  lawern
 * von getPath auf getCannonicalPath umgestellt
 *
 * Revision 1.2  2003/09/11 08:27:21  lawern
 * einige Methoden public gemacht
 *
 * Revision 1.1  2003/07/28 11:01:13  lawern
 * SoWordDocConverter hinzugefügt
 *
 */
package vkc.converter;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;

import vkc.misc.VKCLogManager;
import vkc.util.FileUtils;
import vkc.util.VKCInputStream;
import vkc.util.ZipUtils;

/**
 * Klasse zum Konvertieren von Textdokumenten.
 *
 * @author lawern
 */
public class SoWordDocConverter extends DocConverter {
	private static final boolean debug = false;

	public static String docSuffix = ".doc";

	private File zipFile = null;

	private File rtfFile = null;

	private String htmlFile = null;

	private File pdfFile = null;

	private File htmlDir = null;

	//private DocConverter htmlConverter = null;
	private RTFExtractor rtfExtractor = null;

	public SoWordDocConverter() {
	}

	/**
	 * Liefert den Suffix für temporäre Dateien zurück.
	 *
	 * @return docSuffix
	 */
	public String getDocSuffix() {
		return docSuffix;
	}

	/**
	 * Diese Methode konvertiert das übergebene Dokument in die in der
	 * Collection definierten Formate. Der Parameter conversions wird zur Zeit
	 * noch nicht ausgewertet.
	 *
	 * @param docFile URL des zu konvertierendes Dokument
	 * @param conversions Collection von VKCDocumentTypes welche die zu
	 *        erzeugenden Konvertierungen beschreibt.
	 */
	public void convert(URL docFile, Collection conversions) {
		if (debug) {
			System.out.println("SoWordDocConverter: " + docFile);
		}
		if (enableHtml) {
			try {
				htmlDir = File.createTempFile("WordDoc", "");
				htmlDir.delete();
				htmlDir.mkdir();

				if (!debug) {
					htmlDir.deleteOnExit();
				}

				rtfFile = File.createTempFile("WordDoc", ".rtf");

				if (!debug) {
					rtfFile.deleteOnExit();
				}

				htmlFile = htmlDir.getCanonicalPath() + File.separator + "index.html";
			} catch (java.io.IOException ioe) {
				VKCLogManager.errorLog(this, "3", "Can't create temp-file.", ioe);
			}
		}

		if (enableTdf) {
			try {
				rtfFile = File.createTempFile("temp", ".rtf");
		
				if (!debug) {
					rtfFile.deleteOnExit();
				}
			} catch (java.io.IOException ioe) {
				VKCLogManager.errorLog(this, "3", "Can't create temp-file.", ioe);
			}
		}

		if (enablePdf) {
			try {
				pdfFile = File.createTempFile("temp", ".pdf");

				if (!debug) {
					pdfFile.deleteOnExit();
				}
			} catch (java.io.IOException ioe) {
				VKCLogManager.errorLog(this, "3", "Can't create temp-file.", ioe);
			}
		}
		//Dokument konvertieren
		try {
			int formatsNumber = 0;

			if (enablePdf) {
				formatsNumber++;
			}
			
			if (enableHtml) {
				formatsNumber++;
			}
			
			if (enableTdf) {
				formatsNumber++;
			}
			
			int i = 0;
			String[] convertTypes = new String[formatsNumber];// +1 --> wegen der Erzeugung des RTF-Formats

			if (enableTdf) {
				convertTypes[i] = "Rich Text Format";
				i++;
			}
			
			if (enableHtml) {
				convertTypes[i] = "HTML (StarWriter)";
				i++;
			}
			
			if (enablePdf) {
				convertTypes[i] = "writer_pdf_Export";
				i++;
			}
			
			i = 0;
			URL[] urls = new URL[formatsNumber];
			
			if (enableTdf) {
				urls[i] = rtfFile.toURL();
				i++;
			}

			if (enableHtml) {
				urls[i] = new File(htmlFile).toURL();
				i++;
			}
			
			if (enablePdf) {
				urls[i] = pdfFile.toURL();
				i++;
			}

			new SOfficeDocConverter().convert(docFile, convertTypes, urls);
		} catch (IOException e1) {
			VKCLogManager.errorLog(this, "", e1.getMessage(), e1);
		}

		if (enableHtml) {
			FileUtils.deleteZeroByteFile(new File(htmlFile));
		}
		
		if (enableTdf) {
			FileUtils.deleteZeroByteFile(rtfFile);
		}
		
		if (enablePdf) {
			FileUtils.deleteZeroByteFile(pdfFile);
		}
		
		if (enableHtml) {
			if (!new File(htmlFile).exists()) {
				VKCLogManager.errorLog(this, "6", "HTML conversion not generated.");

				try {
					FileUtils.deleteDirectory(htmlDir);
				} catch (Exception ex) {
					VKCLogManager.errorLog(this, "", ex.getMessage(), ex);
				}
			} else {
				try {
					//Html-Version zusammenzipen
					zipFile = File.createTempFile("WordDoc", ".zip");

					if (!debug) {
						zipFile.deleteOnExit();
					}

					ZipUtils.zip(htmlDir, zipFile, true, htmlDir.getCanonicalPath() + File.separator);
				} catch (java.io.IOException ioe) {
					VKCLogManager.errorLog(this, "4", "Can't create temp-file.", ioe);
				}

				//Html-Verzeichnis löschen
				try {
					FileUtils.deleteDirectory(htmlDir);
				} catch (Exception ex) {
					VKCLogManager.errorLog(this, "5", "Can't delete temp-dir.", ex);
				}
			}
		}

		//      RTF-Dateien löschen
		if (enableTdf && rtfFile.exists()) {
			rtfExtractor = new RTFExtractor();

			try {
				rtfExtractor.analyse(rtfFile.toURL().toString());
			} catch (MalformedURLException e) {
			}
		
			try {
				FileUtils.deleteFilesByPrefix(rtfFile.getParentFile(), rtfFile.getName().replace('.', '_'));
			} catch (Exception e2) {
				VKCLogManager.errorLog(this, "", e2.getMessage(), e2);
			}

			rtfFile.delete();
		}
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * Tdf-Konvertierung.
	 *
	 * @return Stream der Tdf-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getTdfStream() {
		//        if (htmlConverter != null) {
		//            return htmlConverter.getTdfStream();
		//        }
		if (rtfExtractor != null) {
			byte[] tdfArray = rtfExtractor.getTdfArray();
			
			return new VKCInputStream(new ByteArrayInputStream(tdfArray), tdfArray.length);
		}

		return null;
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * HTML-Konvertierung.
	 *
	 * @return Stream der HTML-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getHtmlStream() {
		if (zipFile != null) {
			incOpenStreams();

			try {
				return new VKCInputStream(new BufferedInputStream(new FileInputStream(zipFile)), zipFile.length()) {
					public void close() throws IOException {
						super.close();
						closeHtmlStream();
					}
				};
			} catch (Exception e) {
				VKCLogManager.errorLog(this, "2", "ZIP-File not found!", e);
			}
		}

		return null;
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * PDF-Konvertierung.
	 *
	 * @return Stream der PDF-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getPdfStream() {
		if (pdfFile != null) {
			incOpenStreams();

			try {
				return new VKCInputStream(new BufferedInputStream(new FileInputStream(pdfFile)), pdfFile.length()) {
					public void close() throws IOException {
						super.close();
						closePdfStream();
					}
				};
			} catch (Exception e) {
				VKCLogManager.errorLog(this, "1", "PDF-File not found!", e);
			}
		}

		return null;
	}

	void closePdfStream() {
		if (debug) {
			System.out.println("closePdfStream");
		}

		decOpenStreams();
	}

	/**
	 * Gibt eine Liste zurueck, der alle HREFs einer Seite enthält.
	 *
	 * @return Link-Vektor
	 */
	public ArrayList getLinks() {
		//        if (htmlConverter != null) {
		//            return htmlConverter.getLinks();
		//        }
		return null;
	}

	/**
	 * Liefert den Titel des Dokuments zurück.
	 *
	 * @return Titel des Dokuments oder <code>null</code>
	 */
	public String getTitle() {
		//        if (htmlConverter != null) {
		//            return htmlConverter.getTitle();
		//        }
		if (rtfExtractor != null) {
			return rtfExtractor.getTitle();
		}

		return null;
	}

	/**
	 * Liefert die Beschreibung des Dokuments zurück.
	 *
	 * @return Beschreibung des Dokuments oder <code>null</code>
	 */
	public String getDescription() {
		if (rtfExtractor != null) {
			return rtfExtractor.getDescription();
		}

		return null;
	}

	/**
	 * Liefert die Schlagwörter des Dokuments zurück.
	 *
	 * @return Schlagwörter des Dokuments oder <code>null</code>
	 */
	public String getKeyWords() {
		if (rtfExtractor != null) {
			return rtfExtractor.getKeyWords();
		}

		return null;
	}

	/**
	 * Liefert eine Collection mit Objekten vom Typ TdfElement zurück, welche
	 * das Dokument beschreiben.
	 *
	 * @return Collection mit Objekten vom Typ TdfElement
	 */
	public Collection getElements() {
		//        if (htmlConverter != null) {
		//            return htmlConverter.getElements();
		//        }
		if (rtfExtractor != null) {
			return rtfExtractor.getElements();
		}

		return null;
	}

	/**
	 * Löschen der TDF-Streams
	 */
	void closeTdfStream() {
		if (debug) {
			System.out.println("closeTdfStream");
		}

		decOpenStreams();
	}

	/**
	 * Löschen des Ascii-Streams
	 */
	void closeHtmlStream() {
		if (debug) {
			System.out.println("closeHtmlStream");
		}

		decOpenStreams();

		//ZIP-Datei löschen
		if (zipFile != null) {
			zipFile.delete();
		}
	}

	/**
	 * Schließt das Konverter-Objekt und fügt es wieder in den Konverter-Pool
	 * ein.
	 */
	final void closeConverter() {
		//temporäre Dateien löschen
		if (zipFile != null) {
			zipFile.delete();
		}
		//this-Referenz wieder in die Queue einfügen
	}
}