/***************************************************************************
 *   Copyright (C) 2004 by Alexander Dymo  <cloudtemple@mskat.net>         *
 *                                                                         *
 *   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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/
#include "multiproperty.h"

#include "propertylist.h"

namespace PropertyLib{

MultiProperty::MultiProperty(Property *prop)
    :m_propertyList(0)
{
    list.append(prop);
}

MultiProperty::MultiProperty(PropertyList *propertyList)
    :m_propertyList(propertyList)
{
}

MultiProperty::MultiProperty(PropertyList *propertyList, Property *prop)
    :m_propertyList(propertyList)
{
    list.append(prop);
}

MultiProperty::~MultiProperty()
{
}

TQString MultiProperty::name() const
{
    if (list.count() >= 1)
        return list.getFirst()->name();
    return TQString();   
}

int MultiProperty::type() const
{
    if (list.count() >= 1)
        return list.getFirst()->type();
    return TQVariant::Invalid;   
}

TQVariant MultiProperty::value() const
{
    TQVariant value;
    if (list.count() >= 1)
        value = list.getFirst()->value();

    TQPtrListIterator<Property> it(list);
    Property *property;
    while ((property = it.current()) != 0)
    {
        if (property->value() != value)
            return TQVariant::Invalid;
        ++it;
    }

    return value;
}

TQString MultiProperty::description() const
{
    TQString description;
    if (list.count() >= 1)
        description = list.getFirst()->description();

    TQPtrListIterator<Property> it(list);
    Property *property;
    while ((property = it.current()) != 0)
    {
        if (property->description() != description)
            return TQString();
        ++it;
    }

    return description;
}

bool MultiProperty::readOnly() const
{
    bool v = true;
    if (list.count() >= 1)
        v = list.getFirst()->readOnly();

    TQPtrListIterator<Property> it(list);
    Property *property;
    while ((property = it.current()) != 0)
    {
        if (property->readOnly() != v)
            return false;
        ++it;
    }

    return v;
}

bool MultiProperty::visible() const
{
    bool v = true;
    if (list.count() >= 1)
        v = list.getFirst()->readOnly();

    TQPtrListIterator<Property> it(list);
    Property *property;
    while ((property = it.current()) != 0)
    {
        if (property->visible() != v)
            return false;
        ++it;
    }

    return v;
}

TQStringVariantMap MultiProperty::valueList() const
{
    if (list.count() >= 1)
        return list.getFirst()->valueList;
    return TQStringVariantMap();
}

void MultiProperty::setDescription(const TQString &description)
{
    Property *property;
    for (property = list.first(); property; property = list.next())
        property->setDescription(description);
}

/*void MultiProperty::setName(const TQString &name)
{
}

void MultiProperty::setType(int type)
{
}
*/
void MultiProperty::setValue(const TQVariant &value)
{
    Property *property;
    for (property = list.first(); property; property = list.next())
    {
        property->setValue(value);
        if (m_propertyList)
        {
//             tqWarning("emit change");
            emit m_propertyList->propertyValueChanged(property);
        }
    }
}

void MultiProperty::setValue(const TQVariant &value, bool emitChange)
{
    Property *property;
    for (property = list.first(); property; property = list.next())
    {
        property->setValue(value);
        if (emitChange && m_propertyList)
            emit m_propertyList->propertyValueChanged(property);
    }
}

void MultiProperty::setValueList(const TQStringVariantMap &valueList)
{
    Property *property;
    for (property = list.first(); property; property = list.next())
        property->setValueList(valueList);
}

void MultiProperty::addProperty(Property *prop)
{
    list.append(prop);
}

void MultiProperty::removeProperty(Property *prop)
{
/*    tqWarning("op >>            removing %s", prop->name().ascii());
    tqWarning("op >>            list is %d", list.count());*/
    /*bool b = */list.remove(prop);
/*    tqWarning("op >>            list is %d", list.count());
    tqWarning("op >>            removal is %s", b?"true":"false");    */
}

bool MultiProperty::operator ==(const MultiProperty &prop) const
{
    if ( (type() == prop.type()) && (name() == prop.name()) )
        return true;
    return false;
}

bool MultiProperty::operator ==(const Property &prop) const
{
/*    tqWarning("MultiProperty::operator == for %s = %s", name().ascii(), prop.name().ascii());
    tqWarning("MultiProperty::operator == for %d = %d", type(), prop.type());*/
    if ( (type() == prop.type()) && (name() == prop.name()) )
        return true;
    return false;
}

void MultiProperty::addProperty( MultiProperty *prop)
{
    Property *property;
    for (property = prop->list.first(); property; property = prop->list.next())
        addProperty(property);
}

void MultiProperty::removeProperty( MultiProperty *prop)
{
    Property *property;
    for (property = prop->list.first(); property; property = prop->list.next())
        removeProperty(property);
}

TQVariant MultiProperty::findValueDescription() const
{
    TQVariant val = value();
    if (type() != Property::ValueFromList)
        return val;
    TQStringVariantMap vl = valueList();
    for (TQStringVariantMap::const_iterator it = vl.begin(); it != vl.end(); ++ it)
    {
        if (it.data() == val)
            return it.key();
    }
    return "";
}

TQVariant MultiProperty::findValueDescription(TQVariant val) const
{
    if (type() != Property::ValueFromList)
        return val;
    TQStringVariantMap vl = valueList();
    for (TQStringVariantMap::const_iterator it = vl.begin(); it != vl.end(); ++ it)
    {
        if (it.data() == val)
            return it.key();
    }
    return "";
}

bool MultiProperty::valid() const
{
    return list.count() != 0;
}

void MultiProperty::undo()
{
    Property *property;
    for (property = list.first(); property; property = list.next())
    {
        property->setValue(property->oldValue(), false);
        if (m_propertyList)
            emit m_propertyList->propertyValueChanged(property);
    }
}

}
