/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* writerperfect
 * Version: MPL 2.0 / LGPLv2.1+
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Major Contributor(s):
 * Copyright (C) 2002-2004 William Lachance (wrlach@gmail.com)
 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms
 * of the GNU Lesser General Public License Version 2.1 or later
 * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
 * applicable instead of those above.
 *
 * For further information visit http://libwpd.sourceforge.net
 */

#include <stdio.h>
#include <string.h>

#include "ABWConverter.hxx"

#include "ABWWrapper.hxx"

#include "ABWStringDocumentHandler.hxx"
#include "UsageHelper.hxx"
#include "UserOptions.hxx"
#include "WPWrapper.hxx"

namespace writerperfectrvngabw
{
ABWConverter::ABWConverter(shared_ptr<UserOptions> options, std::string const &toolName, std::string const &usageMessage) :
	m_options(options), m_toolName(toolName), m_usageMessage(usageMessage)
{
}

ABWConverter::~ABWConverter()
{
}

int ABWConverter::printUsage() const
{
	if (m_toolName.empty() || m_usageMessage.empty())
	{
		fprintf(stderr, "INTERNAL ERROR: not enough data to show help.\n");
		return 1;
	}
	UsageHelper usage(m_toolName.c_str(), m_usageMessage.c_str());
	usage.addToDescription("If OUTPUT is missing, the result is printed to standard output.\n");
	if (m_options) m_options->addOptionsToUsageHelper(usage);
	return usage.printUsage();
}

bool ABWConverter::parseAndTreatOptions(int argc, char const *const *argv, int &exitCode) const
{
	if (!m_options)
	{
		fprintf(stderr, "INTERNAL ERROR: can not find the options.\n");
		exitCode=1;
	}
	else if (!m_options->parseOptions(argc, argv) || m_options->m_showHelp)
		exitCode=printUsage();
	else if (m_options->m_showListEncoding)
		exitCode=UsageHelper::printEncodings();
	else if (m_options->m_showVersion)
		exitCode=UsageHelper::printVersion(m_toolName.c_str());
	else if (!m_options->getInput())
		exitCode=printUsage();
	else
		return false;
	return true;
}

// basic wrapper
bool ABWConverter::convertDocument(writerperfect::WPWrapper &wrapper, librevenge::RVNGInputStream &input)
{
	if (!m_options)
		return false;
	writerperfectrvngabw::ABWStringDocumentHandler contentHandler;
	librvngabw::ABWTextGenerator collector(&contentHandler);
	if (!wrapper.parseDocument(input, collector)) return false;
	return contentHandler.write(m_options->getOutput());
}

bool ABWConverter::isSupportedFormat(writerperfect::WPWrapper &wrapper, shared_ptr<librevenge::RVNGInputStream> &input)
{
	if (!input)
		return false;
	return input.get() && wrapper.checkInput(input) && wrapper.m_type==writerperfect::WPWrapper::Text;
}

int ABWConverter::convert(writerperfect::WPWrapper &wrapper, int argc, char const *const *argv)
{
	int exitCode;
	if (parseAndTreatOptions(argc, argv, exitCode))
		return exitCode;

	shared_ptr<librevenge::RVNGInputStream> input(new librevenge::RVNGFileStream(m_options->getInput()));
	if (!isSupportedFormat(wrapper, input))
	{
		if (!wrapper.m_errorSent)
			fprintf(stderr, "ERROR: We have no confidence that you are giving us a valid document.\n");
		return 1;
	}

	if (!input || !convertDocument(wrapper, *input))
	{
		if (!wrapper.m_errorSent)
			fprintf(stderr, "ERROR : Couldn't convert the document\n");
		return 1;
	}

	return 0;
}

// ABWWrapper
bool ABWConverter::convertDocument(ABWWrapper &wrapper, librevenge::RVNGInputStream &input)
{
	if (!m_options)
		return false;
	writerperfectrvngabw::ABWStringDocumentHandler contentHandler;
	librvngabw::ABWTextGenerator collector(&contentHandler);
	if (!wrapper.parseDocument(input, collector)) return false;
	return contentHandler.write(m_options->getOutput());
}

bool ABWConverter::isSupportedFormat(ABWWrapper &wrapper, shared_ptr<librevenge::RVNGInputStream> &input)
{
	if (!input)
		return false;
	return input.get() && wrapper.checkInput(input) && wrapper.getType()==writerperfect::WPWrapper::Text;
}

int ABWConverter::convert(ABWWrapper &wrapper, int argc, char const *const *argv)
{
	int exitCode;
	if (parseAndTreatOptions(argc, argv, exitCode))
		return exitCode;

	shared_ptr<librevenge::RVNGInputStream> input(new librevenge::RVNGFileStream(m_options->getInput()));
	if (!isSupportedFormat(wrapper, input))
	{
		if (!wrapper.isErrorSent())
			fprintf(stderr, "ERROR: We have no confidence that you are giving us a valid document.\n");
		return 1;
	}

	if (!input || !convertDocument(wrapper, *input))
	{
		if (!wrapper.isErrorSent())
			fprintf(stderr, "ERROR : Couldn't convert the document\n");
		return 1;
	}

	return 0;
}
}

/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */
