// Copyright (C) 2004 Shintaro Matsuoka <shin@shoegazed.org>
// Copyright (C) 2006 Martin Aumueller <aumuell@reserv.at>
// See COPYING file for licensing information

#ifndef AMAROK_TQSTRINGX_H
#define AMAROK_TQSTRINGX_H

#include <tqglobal.h>
#include <tqregexp.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqmap.h>

namespace Amarok
{

class QStringx : public TQString
{
public:
    QStringx() {};
    QStringx( TQChar ch ) : TQString( ch ) {};
    QStringx( const TQString& s ) : TQString( s ) {};
    QStringx( const TQByteArray& ba ) : TQString( ba ) {};
    QStringx( const TQChar* unicode, uint length ) : TQString( unicode, length ) {};
    QStringx( const char* str ) : TQString( str ) {};
    virtual ~QStringx() {};

    // the numbers following % obviously are not taken into account
    TQString args( const TQStringList& args ) const
    {
        const TQStringList text = TQStringList::split( TQRegExp( "%\\d+" ), *this, true );

        TQValueListConstIterator<TQString> itrText = text.begin();
        TQValueListConstIterator<TQString> itrArgs = args.begin();
        TQString merged = (*itrText);
        ++itrText;
        while ( itrText != text.end() && itrArgs != args.end() )
        {
            merged += (*itrArgs) + (*itrText);
            ++itrText;
            ++itrArgs;
        }

        Q_ASSERT( itrText == text.end() && itrArgs == args.end() );

        return merged;
    }

    // %something gets replaced by the value corresponding to key "something" in args
    TQString namedArgs( const TQMap<TQString, TQString> args, bool opt=false ) const
    {
        TQRegExp rxArg( "%[a-zA-Z0-9]+" );

        TQString result;
        int start = 0;
        for( int pos = rxArg.search( *this );
                pos != -1;
                pos = rxArg.search( *this, start ) )
        {
            int len = rxArg.matchedLength();
            TQString p = rxArg.capturedTexts()[0].mid(1, len-1);

            result += mid( start, pos-start );
            if( args[p] != TQString() )
                result += args[p];
            else if( opt )
                return TQString();

            start = pos + len;
        }
        result += mid( start );

        return result;
    }

    // %something gets replaced by the value corresponding to key "something" in args,
    // however, if key "something" is not available,
    // then replace everything within surrounding { } by an empty string
    TQString namedOptArgs( const TQMap<TQString, TQString> args ) const
    {
        TQRegExp rxOptArg( "\\{.*%[a-zA-Z0-9_]+.*\\}" );
        rxOptArg.setMinimal( true );

        TQString result;
        int start = 0;
        for( int pos = rxOptArg.search( *this );
                pos != -1;
                pos = rxOptArg.search( *this, start ) )
        {
            int len = rxOptArg.matchedLength();
            QStringx opt = TQString(rxOptArg.capturedTexts()[0].mid(1, len-2));

            result += QStringx(mid( start, pos-start )).namedArgs( args );
            result += opt.namedArgs( args, true );

            start = pos + len;
        }
        result += QStringx( mid( start ) ).namedArgs( args );

        return result;
    }
};

} // namespace Amarok

#endif // AMAROK_TQSTRINGX_H
