/* ****************************************************************************
  This file is part of KBabel

  Copyright (C) 1999-2000 by Matthias Kiefer
                            <matthias.kiefer@gmx.de>
                2001-2002 by Stanislav Visnovsky
                            <visnovsky@kde.org>
                2002-2003 by Marco Wegner 
                            <mail@marcowegner.de>

  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.

**************************************************************************** */


#include <qfile.h>
#include "qregexp.h"
#include <qstring.h>
#include <qstringlist.h>
#include <qtextstream.h>

#include <kgenericfactory.h>

#include "catalog.h"
#include "catalogitem.h"
#include "catalogsettings.h"
#include "linguistexport.h"

K_EXPORT_COMPONENT_FACTORY( kbabel_linguistexport, KGenericFactory<LinguistExportPlugin> )

using namespace KBabel;

LinguistExportPlugin::LinguistExportPlugin( QObject * parent, const char * name, const QStringList& )
  : CatalogExportPlugin( parent, name )
{
}

ConversionStatus LinguistExportPlugin::save( const QString& filename, const QString&, const Catalog * catalog )
{
  // Check whether we know how to handle the extra data.
  if ( catalog->importPluginID( ) != "Qt translation source" )
    return UNSUPPORTED_TYPE;
  
  QFile file( filename );
  if ( !file.open( IO_WriteOnly ) )
    return OS_ERROR;
    
  SaveSettings settings = catalog->saveSettings( );

  // New DOM document.  
  QDomDocument doc( "TS" );
  // Create the root element.
  doc.appendChild( doc.createElement( "TS" ) );
  
  // Create a default context just in case none is given in the messages.
  context = "Default";
  
  // Regular messages.
  for ( uint i = 0; i < catalog->numberOfEntries( ); i++ ) {
    QString comment( extractComment( doc, catalog->comment( i ) ) );
    createMessage( doc, catalog->msgid( i ).join( "" ), catalog->msgstr( i ).join( "" ), 
                   comment );
  }
  
  // Obsolete messages.
  if ( settings.saveObsolete ) {
    QValueList<CatalogItem> obsMessages = catalog->obsoleteEntries( );
    QValueList<CatalogItem>::Iterator it;
    for ( it = obsMessages.begin( ); it != obsMessages.end( ); ++it ) {
      QString comment( extractComment( doc, (*it).comment( ) ) );
      createMessage( doc, (*it).msgid( true ).join( "" ), (*it).msgstr( true ).join( "" ), 
                     comment, true );
    }
  }
  
  QTextStream stream( &file );
  doc.save( stream, 2 );
  file.close( );
  
  return OK;
}

const QString LinguistExportPlugin::extractComment( QDomDocument& doc, const QString& s )
{
  QString comment( s );
  if ( !comment.isEmpty( ) ) {
    // Extract the context and the actual comment.
    comment.remove( QRegExp( "^Context:[\\s]*" ) );
    QString newContext;
    int pos = comment.find( '\n' );
    if ( pos >= 0 ) {
      newContext = comment.left( pos );
      comment.replace( 0, pos + 1, "" );
    } else {
      newContext = comment;
      comment = "";
    }
    setContext( doc, newContext );
  }
  return comment;
}

void LinguistExportPlugin::createMessage( QDomDocument& doc, const QString& msgid, 
     const QString& msgstr, const QString& comment, bool obsolete )
{
    QDomElement elem;
    QDomText text;
    
    QDomElement messageElement = doc.createElement( "message" );
    
    elem = doc.createElement( "source" );
    text = doc.createTextNode( msgid );
    elem.appendChild( text );
    messageElement.appendChild( elem );
    
    if ( !comment.isEmpty( ) ) {
      elem = doc.createElement( "comment" );
      text = doc.createTextNode( comment );
      elem.appendChild( text );
      messageElement.appendChild( elem );
    }
    
    elem = doc.createElement( "translation" );
    if ( msgstr.isEmpty( ) ) {
      elem.setAttribute( "type", "unfinished" );
    } else {
      if ( obsolete )
        elem.setAttribute( "type", "obsolete" );
      text = doc.createTextNode( msgstr );
      elem.appendChild( text );
    }
    messageElement.appendChild( elem );
    contextElement.appendChild( messageElement );
}

void LinguistExportPlugin::setContext( QDomDocument& doc, QString newContext )
{
  // Nothing to do here.
  if ( newContext == context )
    return;
    
  // Find out whether there is already such a context in the QDomDocument.
  QDomNode node = doc.documentElement( ).firstChild( );
  while ( !node.isNull( ) ) {
    if ( node.isElement( ) ) {
      QDomElement elem = node.firstChild( ).toElement( );
      if ( elem.isElement( ) && elem.tagName( ) == "name" && elem.text( ) == newContext ) {
        // We found the context.
        context = newContext;
        contextElement = node.toElement( );
        // Nothing more to do.
        return;
      }
    }
    node = node.nextSibling( );
  }
  
  // Create new context element.
  contextElement = doc.createElement( "context" );
  doc.documentElement( ).appendChild( contextElement );
  // Appropriate name element.
  QDomElement nameElement = doc.createElement( "name" );
  QDomText text = doc.createTextNode( newContext );
  nameElement.appendChild( text );
  contextElement.appendChild( nameElement );
  // Store new context.
  context = newContext;
}
