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

  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 "gettextexport.h"

#include <resources.h>
#include "catalog.h"
#include "catalogitem.h"
#include "catalogsettings.h"

#include <qfile.h>
#include <qtextcodec.h>

#include <kapplication.h>
#include <kdebug.h>
#include <kgenericfactory.h>

K_EXPORT_COMPONENT_FACTORY( kbabel_gettextexport, KGenericFactory<GettextExportPlugin> )

using namespace KBabel;

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

ConversionStatus GettextExportPlugin::save(const QString& localFile , const QString& mimetype, const Catalog* catalog)
{
   // check, whether we know how to handle the extra data
   if( catalog->importPluginID() != "GNU gettext") 
      return UNSUPPORTED_TYPE;

   // we support on the application/x-gettext MIME type
   if( mimetype != "application/x-gettext") 
      return UNSUPPORTED_TYPE;

   QFile file(localFile);

   if(file.open(IO_WriteOnly))
   {
      int progressRatio = QMAX(100/ QMAX(catalog->numberOfEntries(),1), 1);
      emit signalResetProgressBar(i18n("saving file"),100);

      QTextStream stream(&file);
      
      SaveSettings _saveSettings = catalog->saveSettings();
      
      if(_saveSettings.useOldEncoding && catalog->fileCodec())
      {
	    stream.setCodec(catalog->fileCodec());
      }
      else
      {
         switch(_saveSettings.encoding)
         {
            case UTF8:
               stream.setCodec(QTextCodec::codecForName("utf-8"));
               break;
            case UTF16:
               stream.setCodec(QTextCodec::codecForName("utf-16"));
               break;
            default:
	       stream.setCodec(QTextCodec::codecForLocale());
               break;
         }
      }

      // only save header if it is not empty
      if(!catalog->header().comment().isEmpty() || !catalog->header().msgstr().isEmpty())
      {
	 // write header
	  if(!catalog->header().comment().isEmpty())
	  {
	      stream << catalog->header().comment() << "\n";
	  }

	  QString str = catalog->header().msgid().first();	       
	  QStringList list=QStringList::split("\n",str);

	  if(str.left(1)=="\n")
		list.prepend("");

	  if(list.isEmpty())
		list.append("");

	  QValueList<QString>::ConstIterator lit;
	  
	  // if the msgid has more than one line
	  if(list.count() > 1)
		list.prepend("");

	  stream << "msgid ";
	  for( lit = list.begin(); lit != list.end(); ++lit )
	  {
		stream << "\"" << (*lit) << "\"\n";
	  }
	  
	  str = catalog->header().msgstr().first();

	  list=QStringList::split("\n",str);
	  
	  if(str.left(1)=="\n")
		list.prepend("");
		
	  if(list.isEmpty())
		list.append("");

    	  // if the msgstr has more than one line
    	  if(list.count() > 1)
        	list.prepend("");

    	  stream << "msgstr ";
    	  for( lit = list.begin(); lit != list.end(); ++lit )
    	  {
        	stream << "\"" << (*lit) << "\"\n";
    	  }

         stream << "\n";
      }

      QStringList list;
      for( uint counter = 0; counter < catalog->numberOfEntries() ; counter++ )
      {
          if(counter%10==0) {
             emit signalProgress(counter/progressRatio);
	  }
	  
	  // write entry
	  if(!catalog->comment(counter).isEmpty())
	  {
	      stream << catalog->comment(counter) << "\n";
	  }

	  QStringList list=msgidAsList(catalog, counter);
	  QValueList<QString>::ConstIterator lit;
	  
	  // if the msgid has more than one line
	  if(list.count() > 1)
		list.prepend("");

	  stream << "msgid ";
	  for( lit = list.begin(); lit != list.end(); ++lit )
	  {
		stream << "\"" << (*lit) << "\"\n";
	  }
	  
	  if( catalog->pluralForm(counter) == Gettext)
	  {
		list = msgidAsList(catalog, counter,true);
    		// if the msgid has more than one line
    		if(list.count() > 1)
        	    list.prepend("");

    		stream << "msgid_plural ";
    		for( lit = list.begin(); lit != list.end(); ++lit )
    		{
        	    stream << "\"" << (*lit) << "\"\n";
    		}
	  }
	  
	  if( catalog->pluralForm(counter) != Gettext)
	  {
		list=msgstrAsList(catalog, counter);
    		// if the msgstr has more than one line
    		if(list.count() > 1)
        	    list.prepend("");

    		stream << "msgstr ";
    		for( lit = list.begin(); lit != list.end(); ++lit )
    		{
        	    stream << "\"" << (*lit) << "\"\n";
    		}
	  }
	  else
	  {
		kdDebug(KBABEL) << "Saving gettext plural form" << endl;
    		int forms = catalog->msgstr(counter).count();
    		for(int i=0; i<forms; i++)
    		{
        	    list=msgstrAsList(catalog, counter, i);
        	    // if the msgstr has more than one line
        	    if(list.count() > 1)
            		list.prepend("");

        	    stream << "msgstr[" << i << "] ";
        	    for( lit = list.begin(); lit != list.end(); ++lit )
        	    {
            		stream << "\"" << (*lit) << "\"\n";
        	    }
    		}
	  }
	  
          stream << "\n";

	 kapp->processEvents(10);
	 if( isStopped() )
	 {
	    return STOPPED;
	 }
      }

      if( _saveSettings.saveObsolete )
      {
          QValueList<QString>::ConstIterator oit;
	  
	  QStringList _obsolete = catalog->catalogExtraData();

          for( oit = _obsolete.begin(); oit != _obsolete.end(); ++oit )
    	  {
              stream << (*oit) << "\n\n";

	      kapp->processEvents(10);
	      if( isStopped() )
	      {
		  return STOPPED;
	      }
          }
      }
      
      emit signalProgress(100);
      file.close();

      emit signalClearProgressBar();
   }
   else
   {
      //emit signalError(i18n("Wasn't able to open file %1").arg(filename.ascii()));
      return OS_ERROR;
   }

   return OK;
}

QStringList GettextExportPlugin::msgidAsList(const Catalog* catalog, uint item, bool plural) const
{
   QString str;
   if( catalog->pluralForm(item) == Gettext && plural)
	str = catalog->msgid(item).last();
   else
	str = catalog->msgid(item).first();
		       
   QStringList list=QStringList::split("\n",str);
			  
   if(str.left(1)=="\n")
	list.prepend("");
				   
   if(list.isEmpty())
	list.append("");

   return list;
}

QStringList GettextExportPlugin::msgstrAsList(const Catalog* catalog, uint item, uint nr) const
{
   QString str;
   
   if(catalog->pluralForm(item) == Gettext && nr > 0)
   {
	if( nr > catalog->msgstr(item).count() )
	{
	    kdWarning(KBABEL) << "request for non existing plural form " << nr << endl;
	}
	else
	{
	    str = *(catalog->msgstr(item).at(nr));
	}
   }
   else
   {
	str = catalog->msgstr(item).first();
   }

   QStringList list=QStringList::split("\n",str);

   if(str.left(1)=="\n")
	list.prepend("");

   if(list.isEmpty())
	list.append("");

   return list;
}
