/***************************************************************************
 * variant.h
 * This file is part of the KDE project
 * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 ***************************************************************************/

#ifndef KROSS_API_VARIANT_H
#define KROSS_API_VARIANT_H

#include <tqstring.h>
#include <tqvariant.h>

#include "object.h"
#include "value.h"
#include "exception.h"

namespace Kross { namespace Api {

    class List;

    /**
     * Variant value to wrap a TQVariant into a \a Kross::Api::Value
     * to enable primitive types like strings or numerics.
     */
    class Variant : public Value<Variant, TQVariant>
    {
            friend class Value<Variant, TQVariant>;
        public:

            /**
             * Constructor.
             *
             * \param value The initial TQVariant-value
             *        this Variant-Object has.
             * \param name The name this Value has.
             */
            Variant(const TQVariant& value);

            inline operator bool () { return getValue().toBool(); }
            inline operator int () { return getValue().toInt(); }
            inline operator uint () { return getValue().toUInt(); }
            inline operator double () { return getValue().toDouble(); }
            inline operator const char* () { return getValue().toString().latin1(); }

            inline operator TQString () { return getValue().toString(); }
            inline operator const TQString () { return getValue().toString(); }
            inline operator const TQString& () { return getValue().asString(); }

            inline operator TQCString () { return getValue().toCString(); }
            inline operator const TQCString () { return getValue().toCString(); }
            inline operator const TQCString& () { return getValue().asCString(); }

            inline operator TQVariant () { return getValue(); }
	    inline operator const TQVariant () { return getValue(); }
            inline operator const TQVariant& () { return getValue(); }

            /**
             * Operator to return a TQStringList.
             *
             * We can not just use getValue().toStringList() here cause maybe
             * this Kross::Api::Variant is a Kross::Api::List which could be
             * internaly used for list of strings as well. So, we use the
             * toStringList() function which will take care of translating a
             * Kross::Api::List to a TQStringList if possible or to throw an
             * exception if the Kross::Api::List isn't a TQStringList.
             */
            inline operator TQStringList () {
                return toStringList(this);
            }
            inline operator TQValueList<TQVariant> () {
                return toList(this);
            }

            /**
             * Destructor.
             */
            virtual ~Variant();

            /// \see Kross::Api::Object::getClassName()
            virtual const TQString getClassName() const;

            /**
             * \return a string representation of the variant.
             *
             * \see Kross::Api::Object::toString()
             */
            virtual const TQString toString();

            /**
             * Try to convert the given \a Object into
             * a TQVariant.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQVariant converted object.
             */
            static const TQVariant& toVariant(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a TQString.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQString converted object.
             */
            static const TQString toString(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a int.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a int converted object.
             */
            static int toInt(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a uint.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a uint converted object.
             */
            static uint toUInt(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a uint.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a uint converted object.
             */
            static double toDouble(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a TQ_LLONG.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQ_LLONG converted object.
             */
            static TQ_LLONG toLLONG(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a TQ_ULLONG.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQ_ULLONG converted object.
             */
            static TQ_ULLONG toULLONG(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a boolean value.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a bool converted object.
             */
            static bool toBool(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a TQStringList.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQValueList converted object.
             */
            static TQStringList toStringList(Object::Ptr object);

            /**
             * Try to convert the given \a Object into
             * a TQValueList of TQVariant's.
             *
             * \throw TypeException If the convert failed.
             * \param object The object to convert.
             * \return The to a TQValueList converted object.
             */
            static TQValueList<TQVariant> toList(Object::Ptr object);

    };

}}

#endif

