/* -*- C++ -*-

Copyright (C) 2002 Francesco Bresciani <fbresciani@users.sourceforge.net>
This file is part of Kemistry

Kemistry 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, or (at your option)
any later version.

Kemistry 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
NU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Kemistry; see the file COPYING.  If not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/


#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kurlrequester.h>

#include <qcheckbox.h>
#include <qradiobutton.h>

#include <fstream>

#include "kembabel.h"

#include "data.h"
#include "fileformat.h"
#include "mol.h"

void KemBabelWidget::fillCombos()
{
	QString temp;
	int _inputIdx, _outputIdx;

	_inputIdx = _outputIdx = 0;
	
	_comboInputFormat->insertItem( i18n( "Autodetect from file extension" ) );
	_comboOutputFormat->insertItem( i18n( "Autodetect from file extension" ) );

	for ( unsigned int i = 0; i < OpenBabel::extab.Count(); i++ )
	{
		if ( OpenBabel::extab.IsReadable( i ) )
		{
			_comboInputFormat->insertItem( QString( "%1 (*.%2)" )
					.arg(i18n( OpenBabel::extab.GetDescription( i ) ) )
					.arg( OpenBabel::extab.GetExtension( i ) ) );
			_inputFormatMap[ ++_inputIdx ] = i;
		}

		if ( OpenBabel::extab.IsWritable( i ) )
		{
			_comboOutputFormat->insertItem( QString( "%1 (*.%2)" )
					.arg( i18n( OpenBabel::extab.GetDescription( i ) ) )
					.arg( OpenBabel::extab.GetExtension( i ) ) );
			_outputFormatMap[ ++_outputIdx ] = i;
		}
	}

}

void KemBabelWidget::slotConvert()
{
	bool addH = false, deleteH = false, addHpH = false;

	//check options
	if ( _checkAddH->isChecked() )
		addH = true;
	if ( _checkAddHpH->isChecked() )
		addHpH = true;
	if ( _checkDeleteH->isChecked() )
		deleteH = true;

	QString inputURLString, outputURLString;

	//get url for input and output file
	inputURLString = _KURLReqInput->url();
	outputURLString = _KURLReqOutput->url();

	//check if the url strings are empty
	if ( inputURLString.isEmpty() || outputURLString.isEmpty() )
	{
		KMessageBox::sorry( this, i18n( "You must specify both an input and an"
					" output file name" ) );
		return;
	}


	if ( !OpenBabel::extab.CanReadExtension( const_cast<char*>
				(inputURLString.latin1()) )
				&& ( _comboInputFormat->currentItem() == 0 ) )
	{
		KMessageBox::sorry( this, i18n( "Cannot detect file format from "
					"extension for input file '%1'.\n" 
					"You must set the format in the Input file format "
					"combo box" ).arg( inputURLString) );
		return;
	}

	if ( !OpenBabel::extab.CanWriteExtension( const_cast<char*>
			( outputURLString.latin1() ) )
			&& ( _comboOutputFormat->currentItem() == 0 ) )
	{
		KMessageBox::sorry( this, i18n( "Cannot detect file format from "
					"extension for output file '%1'.\n"
					"You must set the format in the Output file format "
					"combo box" ).arg( outputURLString ) );
		return;
	}

	OpenBabel::io_type intype = OpenBabel::UNDEFINED, 
	outtype = OpenBabel::UNDEFINED;

	//set input type
	int idx = _comboInputFormat->currentItem();

	if ( idx == 0 )
		//Autodetect selected
		intype = OpenBabel::extab.FilenameToType( const_cast<char*>
			(inputURLString.latin1() ) );
	else
		intype = OpenBabel::extab.GetType( _inputFormatMap[ idx ] );
	
	//set output type
	idx = _comboOutputFormat->currentItem();

	if ( idx == 0 )
		outtype = OpenBabel::extab.FilenameToType( const_cast<char*>
			( outputURLString.latin1() ) );
	else
		outtype = OpenBabel::extab.GetType( _outputFormatMap[ idx ] );

	OpenBabel::OBMol mol( intype, outtype );
	OpenBabel::OBFileFormat ff;

	//read molecule
	std::ifstream inFStream( inputURLString.latin1() );
	if ( !inFStream )
	{
		KMessageBox::error( this, i18n( "Cannot read input file '%1'" )
				.arg( inputURLString ) );
		return;
	}

	ff.ReadMolecule( inFStream, mol, inputURLString.latin1() );

	//perform the required transformations
	if ( deleteH )
		mol.DeleteHydrogens();
	if ( addH )
		mol.AddHydrogens( addHpH );

	//write molecule
	std::ofstream outFStream( outputURLString.latin1() );
	if ( !outFStream )
	{
		KMessageBox::error( this, i18n( "Cannot write output file '%1'" )
				.arg( outputURLString ) );
		inFStream.close();
		return;
	}

	ff.WriteMolecule( outFStream, mol, "3D" );

	//close streams
	inFStream.close();
	outFStream.close();
}
