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

  Copyright (C) 1999-2000 by Matthias Kiefer
                            <matthias.kiefer@gmx.de>
		2002	  by Stanislav Visnovsky
			    <visnovsky@nenya.ms.mff.cuni.cz>

  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., 675 Mass Ave, Cambridge, MA 02139, USA.

**************************************************************************** */
#include "catalogitem.h"
#include "editcmd.h"
#include "resources.h"
#include "libgettext/pofiles.h"

#include "tagextractor.h"

#include <qtextstream.h>
#include <qtextcodec.h>
#include <FlexLexer.h>

CatalogItem::CatalogItem()
    : _tagList(0)
{
   clear();
}

CatalogItem::CatalogItem(QString itemStr)
    : _tagList(0)
{
   clear();
   QTextStream stream(&itemStr,IO_ReadOnly);

   read(stream);
}

CatalogItem::~CatalogItem()
{
    if(_tagList)
        delete _tagList;
}

CatalogItem::CatalogItem(const char* msgid, const char* msgstr,
			 const char* comment)
    : _tagList(0)
{
    clear();

    _comment=comment;
    (*_msgid.begin())=msgid;
    (*_msgstr.begin())=msgstr;
    _valid=true;
	_error = None;
}

QString CatalogItem::comment() const
{
    return _comment;
}

QString CatalogItem::msgid() const
{
    return _msgid.first();
}

QString CatalogItem::msgstr() const
{
    return _msgstr.first();
}


QStringList CatalogItem::msgidAsList(bool plural) const
{
   QString str;
   if(_gettextPluralForm && plural)
       str = _msgid.last();
   else
       str = _msgid.first();
   
   QStringList list=QStringList::split("\n",str);

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

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

   return list;
}


QStringList CatalogItem::msgstrAsList(int nr) const
{
   QString str;
   if(_gettextPluralForm && nr > 0)
   {
       QStringList::ConstIterator it = _msgstr.at(nr);
       if(it != _msgstr.end())
       {
           str = *it;
       }
       else
       {
           kdDebug(KBABEL) << "request for non existing plural form " 
               << nr << endl;
       }
   }
   else
   {
       str = _msgstr.first();
   }
   
   QStringList list=QStringList::split("\n",str);

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

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

   return list;
}

QStringList CatalogItem::commentAsList() const
{
   QStringList list=QStringList::split("\n",comment());

   return list;
}


const QStringList& CatalogItem::tagList()
{
    if(!_tagList)
    {
        TagExtractor te(msgid());
        _tagList = new QStringList(te.tags());
    }

    return *_tagList;
}


bool CatalogItem::isFuzzy() const
{
   bool flag=false;
   if( _comment.contains(", fuzzy") )
     flag=true;

   return flag;
}

bool CatalogItem::isCformat() const
{
   bool flag=false;
   if(_comment.contains(", c-format"))
     flag=true;

   return flag;
}

bool CatalogItem::isUntranslated() const
{
   return _msgstr.first().isEmpty();
}

bool CatalogItem::isPluralForm() const
{
    return _gettextPluralForm;
}

int CatalogItem::totalLines() const
{
   int lines=0;
   if(!_comment.isEmpty())
   {
      lines = _comment.contains('\n')+1;
   }
   int msgidLines=0;
   QStringList::ConstIterator it;
   for(it=_msgid.begin(); it != _msgid.end(); ++it)
   {
      msgidLines += (*it).contains('\n')+1;
   }
   int msgstrLines=0;
   for(it=_msgstr.begin(); it != _msgstr.end(); ++it)
   {
      msgstrLines += (*it).contains('\n')+1;
   }

   if(msgidLines>1)
      msgidLines++;
   if(msgstrLines>1)
      msgstrLines++;

   lines+=( msgidLines+msgstrLines );

   return lines;
}


void CatalogItem::setSyntaxError(bool on)
{
	if(on)
		_error = _error | Syntax;
	else
		_error = _error & ~Syntax;
}

QPtrList<EditCommand> CatalogItem::removeFuzzy(bool doIt)
{
   QPtrList<EditCommand> editList;
   editList.setAutoDelete(false);

   QString comment=_comment;

   if(isFuzzy())
   {
       EditCommand *cmd;
       QString fuzzyStr(", fuzzy");

       int offset;
       offset=comment.find(fuzzyStr);
       while(offset>=0)
       {
          cmd = new DelTextCmd(offset,fuzzyStr);
          cmd->setPart(EditCommand::Comment);
          editList.append(cmd);
	  
          comment.remove(offset,fuzzyStr.length());

          offset=comment.find(fuzzyStr,offset+1);
       }
       
       // remove empty comment lines
       if( comment.contains( QRegExp("^#\\s*$") ))
       {
          cmd = new DelTextCmd(0,comment);
          cmd->setPart(EditCommand::Comment);
          editList.append(cmd);
	  
          comment="";
       }
       if( comment.contains( QRegExp("\n#\\s*$") ))
       {
          offset=comment.find( QRegExp("\n#\\s*$") );
          while(offset>=0)
          {
             cmd = new DelTextCmd(offset,comment.mid(offset));
             cmd->setPart(EditCommand::Comment);
             editList.append(cmd);

             comment.remove(offset,comment.length()-offset);

             offset=comment.find( QRegExp("\n#\\s*$"), offset+1 );
          }
       }
       if( comment.contains( QRegExp("\n#\\s*\n") ))
       {
          offset=comment.find( QRegExp("\n#\\s*\n") )+1;
          while(offset>=0)
          {
             int endIndex=comment.find("\n",offset)+1;

             cmd = new DelTextCmd(offset,comment.mid(offset,endIndex-offset));
             cmd->setPart(EditCommand::Comment);
             editList.append(cmd);

             comment.remove(offset,endIndex-offset);

             offset=comment.find( QRegExp("\n#\\s*\n"), offset+1 );
          }
       }
       
       if(doIt)
          _comment=comment;

   }

   return editList;
}



QPtrList<EditCommand> CatalogItem::addFuzzy(bool doIt)
{
   QPtrList<EditCommand> editList;
   editList.setAutoDelete(false);


   if(!isFuzzy())
   {
       EditCommand *cmd;
       int offset=_comment.length();

       QString addStr;
       if(offset > 0 && _comment[offset-1] != '\n')
       {
           addStr='\n';
       }
       addStr+="#, fuzzy";

       cmd = new InsTextCmd(offset,addStr);
       cmd->setPart(EditCommand::Comment);
       editList.append(cmd);


       if(doIt)
          _comment+=addStr;
   }

   return editList;
}


void CatalogItem::processCommand(EditCommand* cmd, bool undo)
{
    if(cmd->terminator()!=0)
       return;

    DelTextCmd* delcmd = (DelTextCmd*) cmd;

    bool ins =  true;
    if (delcmd->type() == EditCommand::Delete )
       ins = undo;
    else if (delcmd->type() == EditCommand::Insert )
       ins = !undo;
    else
    {
       kdDebug() << "what kind of edit command is this?" << endl;
       return;
    }

    if ( ins )
    {
       if(delcmd->part()==EditCommand::Msgstr)
       {
          (*_msgstr.begin()).insert(delcmd->offset,delcmd->str);
       }
       else if(delcmd->part()==EditCommand::Comment)
       {
          _comment.insert(delcmd->offset,delcmd->str);
       }
    }
    else
    { // del
       if(delcmd->part()==EditCommand::Msgstr)
       {
          (*_msgstr.begin()).remove(delcmd->offset,delcmd->str.length());
       }
       else if(delcmd->part()==EditCommand::Comment)
       {
          _comment.remove(delcmd->offset,delcmd->str.length());
       }
    }
}


void CatalogItem::clear()
{
   _comment="";
   _msgid.clear();
   _msgid.append("");
   _msgstr.clear();
   _msgstr.append("");
   _valid=true;
   _error=None;
   _gettextPluralForm=false;

   if(_tagList)
   {
       delete _tagList;
       _tagList=0;
   }
}


bool CatalogItem::checkArgs(const QRegExp& comment) 
{
	if( !isCformat() ) return true;
	bool hasError = false;

	if(!isUntranslated())
	{
		QString formatChars="dioxXucsfeEgGp%";

		QString line=_msgid.first();
		line.replace( comment, "");
		line.replace( QRegExp("\\n"), "" );
		line.simplifyWhiteSpace();
		
		int index=line.find(QRegExp("%."));
		
		QStringList argList;
		while(index>=0)
		{
			int endIndex=line.find(QRegExp("[^\\d]"),index+1);
			if(endIndex<0)
			{
				endIndex=line.length();
			}
			else if( formatChars.contains(line[endIndex]) )
			{
					endIndex++;
			}
			
			if(endIndex - index > 1 )
				argList.append(line.mid(index,endIndex-index));
	
			index=line.find(QRegExp("%."),endIndex);
		}
	
		line=_msgstr.first().simplifyWhiteSpace();
		index=line.find(QRegExp("%."));

		while(index>=0)
		{
			int endIndex=line.find(QRegExp("[^\\d]"),index+1);
			if(endIndex<0)
			{
				endIndex=line.length();
			}
			else if( formatChars.contains(line[endIndex]) )
			{
					endIndex++;
			}
	
			if(endIndex - index > 1 )
			{
				QStringList::Iterator it = argList.find(line.mid(index,endIndex-index));
				if( it!= argList.end())
				{
					argList.remove(it);
				}
				else
				{
					hasError = true;
				}
			}

			index=line.find(QRegExp("%."),endIndex);
		}

		if(!argList.isEmpty())
		{
			hasError = true;
		}
	}
	
	if(hasError)
	{
		_error = _error | Args;
	}
	else
	{
		_error = _error & ~Args;
	}
			
	return !hasError;
}


bool CatalogItem::checkAccelerator(QChar accelMarker, const QRegExp& comment)
{
	bool hasError = false;
	if(!isUntranslated())
	{
		QString lineid=_msgid.first();
		lineid.replace( comment, "");
		lineid.replace( QRegExp("\\n"), "" );
		lineid.simplifyWhiteSpace();
		QString linestr=_msgstr.first();
		linestr.replace( comment, "");
		linestr.replace( QRegExp("\\n"), "" );
		linestr.simplifyWhiteSpace();

		QString regStr(accelMarker);
		regStr+="[^\\s]";
		QRegExp reg(regStr);
		int n = lineid.contains(reg);
		if( accelMarker = '&' ) 
		    n = n - lineid.contains(QRegExp("&[a-z,A-Z,\\-,0-9,#]*;"));
		int m = linestr.contains(reg);
		if( accelMarker = '&' ) 
		    m = m - linestr.contains(QRegExp("&[a-z,A-Z,\\-,0-9,#]*;"));

		hasError = ( n<=1 &&  m != n);
	}

	if(hasError)
	{
		_error = _error | Accel;
	}
	else
	{
		_error = _error & ~Accel;
	}
			
	return !hasError;
}


bool CatalogItem::checkEquation() 
{
	bool error = false;
	
    QString msg=_msgid.first();
	if(!isUntranslated() && !msg.contains('\n') 
					&& msg.contains(QRegExp("^[a-zA-Z0-9]+=.+")))
	{
		int index = msg.find('=');
		QString left = msg.left(index);
		index = _msgstr.first().find('=');
		if(left != _msgstr.first().left(index))
			error = true;
	}
	
	if(error)
	{
		_error = _error | Equation;
	}
	else
	{
		_error = _error & ~Equation;
	}

	return !error;
}


bool CatalogItem::checkForContext(const QRegExp& reg)
{
	bool error = false;

	if(!isUntranslated() && _msgid.first().contains(reg) 
            && _msgstr.first().contains(reg))
	{
		error = true;
	}
	
	if(error)
	{
		_error = _error | Context;
	}
	else
	{
		_error = _error & ~Context;
	}

	return !error;
}

bool CatalogItem::checkSingularPlural(const QRegExp& reg, const int neededLines)
{
	bool error = false;

	if(!isUntranslated() && _msgid.first().contains(reg))
	{
        if(neededLines <= 0 || _msgstr.first().contains(reg))
        {
    		error = true;
        }
        else if( _msgstr.first().contains(QString("\\n"))+1 != neededLines )
        {
            error = true;
        }
	}
	
	if(error)
	{
		_error = _error | SingularPlural;
	}
	else
	{
		_error = _error & ~SingularPlural;
	}

	return !error;
}



int CatalogItem::checkErrors(QChar accelMarker,const QRegExp& contextInfo
        , const QRegExp& singularPlural, const int neededLines)
{
	_error=None;

	checkArgs(contextInfo);
	checkAccelerator(accelMarker, contextInfo);
	checkEquation();
	checkForContext(contextInfo);
    checkSingularPlural(singularPlural,neededLines);

	return _error;
}

QString CatalogItem::asString()
{
   QString temp;
   QTextStream stream(&temp,IO_WriteOnly);

   write(stream);
   return temp;
}


void CatalogItem::write(QTextStream& stream) const
{
   if(!comment().isEmpty())
   {
      stream << comment() << "\n";
   }

   QStringList list=msgidAsList();
   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(_gettextPluralForm)
   {
       list = msgidAsList(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(!_gettextPluralForm)
   {
       list=msgstrAsList();
       // 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
   {
       int forms = _msgstr.count();
       for(int i=0; i<forms; i++)
       {
           list=msgstrAsList(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";
           }
       }
   }
}


CatalogItem::IOStatus CatalogItem::read(QTextStream& stream)
{
   enum {Begin,Comment,Msgid,Msgstr} part=Begin;

   clear();

   _valid=false;

   QString line;
   bool cancelLoop=false;
   bool error=false;
   bool recoverableError=false;
   bool obsolete=false;
   QStringList::Iterator msgstrIt=_msgstr.begin();
   
   while(!stream.eof() && !cancelLoop)
   {
       int pos=stream.device()->at();

       line=stream.readLine();
       if(line.isNull()) // file end
		   break;

       // remove whitespaces from beginning and end of line
       line=line.stripWhiteSpace();

       if(part==Begin)
       {
           // ignore trailing newlines
           if(line.isEmpty())
              continue;

           if(line.contains(QRegExp("^#~")))
           {
              obsolete=true;
	      part=Comment;
	      _comment=line;
           }
           else if(line.contains(QRegExp("^#")))
           {
               part=Comment;
               _comment=line;
           }
           else if(line.contains(QRegExp("^msgid\\s*\".*\"$")))
           {
               part=Msgid;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid\\s*\""),"");
               line.replace(QRegExp("\"$"),"");

               (*_msgid.begin())=line;
           }
		     // one of the quotation marks is missing
           else if(line.contains(QRegExp("^msgid\\s*\"?.*\"?$")))
           {
               part=Msgid;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*_msgid.begin())=line;

			   if(!line.isEmpty())
			       recoverableError=true;
           }
           else
           {
              kdDebug(KBABEL) << "no comment or msgid found after a comment: " << line << endl;

               cancelLoop=true;
               error=true;
           }
       }
       else if(part==Comment)
       {
            if(line.isEmpty() && obsolete ) return Obsolete;
	    if(line.isEmpty() )
	       continue;
            else if(line.contains(QRegExp("^#~")))
            {
               _comment+=("\n"+line);
	       obsolete=true;
            }
            else if(line.contains(QRegExp("^#")))
            {
               _comment+=("\n"+line);
            }
            else if(line.contains(QRegExp("^msgid\\s*\".*\"$")))
            {
               part=Msgid;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid\\s*\""),"");
               line.replace(QRegExp("\"$"),"");

               (*_msgid.begin())=line;
            }
			// one of the quotation marks is missing
			else if(line.contains(QRegExp("^msgid\\s*\"?.*\"?$")))
            {
               part=Msgid;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*_msgid.begin())=line;
			   
			   if(!line.isEmpty())
			       recoverableError=true;
            }
            else
            {
               kdDebug(KBABEL) << "no comment or msgid found after a comment while parsing: " << _comment << endl;

               error=true;
               cancelLoop=true;
            }
        }
        else if(part==Msgid)
        {
            if(line.isEmpty())
               continue;
            else if(line.contains(QRegExp("^\".*\\n?\"$")))
            {
               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^\""),"");
               line.replace(QRegExp("\"$"),"");

               QStringList::Iterator it;
               if(_gettextPluralForm)
                   it = _msgid.fromLast();
               else
                   it = _msgid.begin();
               
               // add Msgid line to item
               if((*it).isEmpty())
                  (*it)=line;
               else
                  (*it)+=("\n"+line);
            }
            else if(line.contains(QRegExp("^msgid_plural\\s*\".*\"$")))
            {
               part=Msgid;
               _gettextPluralForm = true;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid_plural\\s*\""),"");
               line.replace(QRegExp("\"$"),"");

               _msgid.append(line);
            }
			// one of the quotation marks is missing
			else if(line.contains(QRegExp("^msgid_plural\\s*\"?.*\"?$")))
            {
               part=Msgid;
               _gettextPluralForm = true;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgid_plural\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               _msgid.append(line);
			   
               if(!line.isEmpty())
			       recoverableError=true;
            }
           else if(!_gettextPluralForm 
                   && line.contains(QRegExp("^msgstr\\s*\".*\\n?\"$")))
            {
               part=Msgstr;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*msgstrIt)=line;
            }
			else if(!_gettextPluralForm
                    && line.contains(QRegExp("^msgstr\\s*\"?.*\\n?\"?$")))
            {
               part=Msgstr;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*msgstrIt)=line;

			   if(!line.isEmpty())
			       recoverableError=true;
            }
            else if(_gettextPluralForm 
                    && line.contains(QRegExp("^msgstr\\[0\\]\\s*\".*\\n?\"$")))
            {
               part=Msgstr;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\[0\\]\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*msgstrIt)=line;
            }
			else if(_gettextPluralForm 
                    && line.contains(QRegExp("^msgstr\\[0\\]\\s*\"?.*\\n?\"?$")))
            {
               part=Msgstr;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\[0\\]\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               (*msgstrIt)=line;

			   if(!line.isEmpty())
			       recoverableError=true;
            }
 
            else if(line.contains(QRegExp("^#")) || line.contains(QRegExp("^msgid")))
            {
               kdDebug(KBABEL) << "no msgstr or msgid found after a msgid while parsing: " << _msgid.first() << endl;

               cancelLoop=true;
               error=true;
            }
            // a line of the msgid with a missing quotation mark
            else if(line.contains(QRegExp("^\"?.+\\n?\"?$")))
            {
               recoverableError=true;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^\""),"");
               line.replace(QRegExp("\"$"),"");

               QStringList::Iterator it;
               if(_gettextPluralForm)
                   it = _msgid.fromLast();
               else
                   it = _msgid.begin();
               
               // add Msgid line to item
               if((*it).isEmpty())
                  (*it)=line;
               else
                  (*it)+=("\n"+line);
            }
            else
            {
               kdDebug(KBABEL) << "no msgstr or msgid found after a msgid while parsing: " << _msgid.first() << endl;

               cancelLoop=true;
               error=true;
            }
        }
        else if(part==Msgstr)
        {
            if(line.isEmpty())
               continue;
            // another line of the msgstr
            else if(line.contains(QRegExp("^\".*\\n?\"$")))
            {
               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^\""),"");
               line.replace(QRegExp("\"$"),"");

               if((*msgstrIt).isEmpty())
                  (*msgstrIt)=line;
               else
                  (*msgstrIt)+=("\n"+line);
            }
            else if(_gettextPluralForm 
                    && line.contains(QRegExp("^msgstr\\[[0-9]+\\]\\s*\".*\\n?\"$")))
            {
               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\[[0-9]+\\]\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               msgstrIt=_msgstr.append(line);
            }
			else if(_gettextPluralForm 
                    && line.contains(QRegExp("^msgstr\\[[0-9]\\]\\s*\"?.*\\n?\"?$")))
            {
               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^msgstr\\[[0-9]\\]\\s*\"?"),"");
               line.replace(QRegExp("\"$"),"");

               msgstrIt=_msgstr.append(line);

			   if(!line.isEmpty())
			       recoverableError=true;
            }
            else if(line.contains(QRegExp("^\\s*msgid")) || line.contains(QRegExp("^\\s*#")))
            {
               cancelLoop=true;
               stream.device()->at(pos);// reset position in stream to beginning of this line
               break;
            }
            else if(line.contains(QRegExp("^msgstr")))
            {
               kdDebug(KBABEL) << "no msgid or comment found after a msgstr while parsing: " << _msgstr.last() << endl;

               cancelLoop=true;
               error=true;
            }
            // another line of the msgstr with a missing quotation mark
            else if(line.contains(QRegExp("^\"?.+\\n?\"?$")))
            {
               recoverableError=true;

               // remove quotes at beginning and the end of the lines
               line.replace(QRegExp("^\""),"");
               line.replace(QRegExp("\"$"),"");

               if((*msgstrIt).isEmpty())
                  (*msgstrIt)=line;
               else
                  (*msgstrIt)+=("\n"+line);
            }
            else
            {
               kdDebug(KBABEL) << "no msgid or comment found after a msgstr while parsing: " << _msgstr.last() << endl;

               cancelLoop=true;
               error=true;
            }
        }
    }
/*
   if(_gettextPluralForm)
   {
       kdDebug() << "gettext plural form:\n"
                 << "msgid:\n" << _msgid.first() << "\n"
                 << "msgid_plural:\n" << _msgid.last() << "\n" << endl;
       int counter=0;
       for(QStringList::Iterator it = _msgstr.begin(); it != _msgstr.end(); ++it)
       {
           kdDebug() << "msgstr[" << counter << "]:\n" 
                     << (*it) << endl;
           counter++;
       }
   }
  */ 
    if(error)
       return ParseError;
	else if(recoverableError)
		return RecoveredParseError;
    else
    {
      _valid=true;
      return obsolete ? Obsolete : Ok;
    }
}

// this does not like any incorrect files
CatalogItem::IOStatus CatalogItem::fastRead(FlexLexer *lexer, QTextCodec *codec, bool storeText)
{
   clear();

   _valid=false;

    // comment
    if( lastToken == T_COMMENT )
    {
	_comment = codec->toUnicode(lexer->YYText());
	while( lexer->yylex() == T_COMMENT )
	    _comment += "\n"+codec->toUnicode(lexer->YYText());
//	kdDebug() << "Comment: " << _comment << endl;
    }

    //obsolete
    if( lastToken == T_OBSOLETE ) {
	lexer->yylex();
	return Obsolete;
    }
        
    // msgid
    if( lastToken != T_MSGID ) return ParseError;
    
    if( lexer->yylex() != T_STRING ) return ParseError;
    QStringList::Iterator it = _msgid.begin();
    *it = codec->toUnicode(lexer->YYText());
    if( storeText )
	while( lexer->yylex() == T_STRING )
    	    (*it) += ("\n"+ codec->toUnicode(lexer->YYText()) );
    else {
	if( lexer->yylex() == T_STRING ) // this is not header
	{
	    *it = "SKIPPED";
	    while( lexer->yylex() == T_STRING );
	}
    }
    
//    kdDebug() << "Msgid: " << *it << endl;

    if( lastToken == T_MSGIDPLURAL ) 
    {
	_gettextPluralForm = true;
	if( lexer->yylex() != T_STRING ) return ParseError;
	it = _msgid.fromLast();
	*it = codec->toUnicode(lexer->YYText());
	if( storeText ) 
	    while( lexer->yylex() == T_STRING )
    		(*it)+="\n"+ codec->toUnicode(lexer->YYText());
	else while( lexer->yylex() == T_STRING );
//	kdDebug() << "Msgid_plural: " << *it << endl;
    }
    
    // msgstr
    if( lastToken != T_MSGSTR ) return ParseError;

    if( !_gettextPluralForm )
    {
	if( lexer->yylex() != T_STRING ) return ParseError;
	it = _msgstr.begin();
	*it = codec->toUnicode(lexer->YYText());
	if( storeText || msgid().isEmpty() ) // if we should store the text or it is a header
	    while( lexer->yylex() == T_STRING )
    		(*it)+= ("\n"+ codec->toUnicode(lexer->YYText()));
	else 
	if( lexer->yylex() == T_STRING ) // check next token, whether it is really translated
	{
	    *it = "SKIPPED";
	    while( lexer->yylex() == T_STRING );
	}
//	kdDebug() << "Msgstr: " << *it << endl;
    } 
    else 
    {
	QString s = codec->toUnicode(lexer->YYText());
	while( lastToken == T_MSGSTR && s.contains( QRegExp("^msgstr\\[[0-9]+\\]" ) ) )
	{
	    if( lexer->yylex() != T_STRING ) return ParseError;
	    it = _msgstr.fromLast();
	    *it = codec->toUnicode(lexer->YYText());
	    
	    if( storeText )
		do {
    		    (*it)+="\n"+codec->toUnicode(lexer->YYText());
		} while( lexer->yylex() == T_STRING );
	    else while( lexer->yylex() == T_STRING );
//	    kdDebug() << "Msgstr: " << *it << endl;
	    s = codec->toUnicode(lexer->YYText());
	} 
    }
    
     _valid=true;
    return Ok;
}

