/* ****************************************************************************
  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.

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


// Qt include files
#include <qfile.h>
#include <qfileinfo.h>
#include <qobject.h>
#include <qregexp.h>
#include <qstring.h>
#include <qstringlist.h>
// KDE include files
#include <kdebug.h>
#include <kgenericfactory.h>
// Project specific include files
#include "catalogitem.h"
#include "linguistimport.h"

K_EXPORT_COMPONENT_FACTORY( kbabel_linguistimport, KGenericFactory<LinguistImportPlugin> )

using namespace KBabel;

LinguistImportPlugin::LinguistImportPlugin( QObject * parent, const char * name, const QStringList& )
  : CatalogImportPlugin( parent, name )
{
}

ConversionStatus LinguistImportPlugin::load( const QString& filename, const QString& )
{
  if ( filename.isEmpty( ) )
    kdDebug( ) << "fatal error: empty filename to open" << endl;
    
  QFileInfo info( filename );
  
  if ( !info.exists( ) || info.isDir( ) )
    return NO_FILE;
    
  if ( !info.isReadable( ) )
    return NO_PERMISSIONS;
    
  QFile file( filename );
  if ( !file.open( IO_ReadOnly ) )
    return NO_PERMISSIONS;
    
  QDomDocument doc;
  if ( !doc.setContent( &file ) ) {
    return PARSE_ERROR;
    file.close( );
  }
  file.close( );
  
  if ( doc.doctype( ).name( ) != "TS" )
    return UNSUPPORTED_TYPE;

  // Count the number of messages in this file. This is needed for updating 
  // the progress bar correctly.
  QString temp = doc.toString( );
  QRegExp rx( "<message>" );
  msgcnt = 0;
  int pos = temp.find( rx );
  while ( pos >= 0 ) {
    msgcnt++;
    pos = temp.find( rx, pos + rx.matchedLength( ) );
  }

  cnt = 0;
  emit signalClearProgressBar( );
  kdDebug( ) << "start parsing..." << endl;
  
  parse( doc.documentElement( ) );
  //setCatalogExtraData( obsMessages );
  
  emit signalProgress( 100 );
  kdDebug( ) << "finished parsing..." << endl;
  
  setMimeTypes( "application/x-linguist" );
    
  return OK;
}

void LinguistImportPlugin::parse( const QDomElement& parentElement )
{
  QDomNode node = parentElement.firstChild( );
  
  while ( !node.isNull( ) ) {
    if ( node.isElement( ) ) {
      QDomElement elem = node.toElement( );
      
      if ( elem.tagName( ) == "context" ) {
        // nothing to do here
      } else if ( elem.tagName( ) == "name" ) {
        context = elem.text( );
      } else if ( elem.tagName( ) == "message" ) {
        CatalogItem item;
        QString comment;
        bool isObsolete = false;

        QDomNodeList nodeList = node.childNodes( );
        for ( uint i = 0; i < nodeList.count( ); ++i ) {
          if ( nodeList.item( i ).isElement( ) ) {
            QDomElement elem = nodeList.item( i ).toElement( );
            
            if ( elem.tagName( ) == "source" ) {
              item.setMsgid( elem.text( ) );
            } else if ( elem.tagName( ) == "translation" ) {
              item.setMsgstr( elem.text( ) );
              if ( elem.attribute( "type" ) == "unfinished" ) {
                // Nothing to do, CatalogItem finds out.
              } else if ( elem.attribute( "type" ) == "obsolete" ) {
                isObsolete = true;
              }
            } else if ( elem.tagName( ) == "comment" ) {
              if ( !elem.text( ).isEmpty( ) )
                comment = elem.text( );
            }
          }
        }

        item.setComment( "Context: " + context + '\n' + comment );
        
        appendCatalogItem( item, isObsolete );
        
        // Update the progress bar.
        cnt++;   
        uint prog = 100*cnt/msgcnt;
        emit signalProgress( prog );
      }
      // recursive parsing
      parse( elem );
    }
    node = node.nextSibling( );
  }
}
