/* NMM - Network-Integrated Multimedia Middleware
 *
 * Copyright (C) 2006
 *               Motama GmbH, Saarbruecken, Germany
 *
 * Maintainer: Bernhard Fuchshumer <fub@motama.com>
 *
 * 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; version 2
 * of the License only.
 *
 * 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 "hostlist.h"

#include <QString>

#include <kdebug.h>

#include <string>
#include <QDBusBusService>
#include <QStringList>
#include <QDBusReply>
using namespace std;

HostList::HostList( QObject *parent ) : QAbstractTableModel( parent)
{
	//DCOP stuff -- find app
	QDBusReply<QStringList> appListReply = QDBus::sessionBus().busService()->listNames();
	//DCOPCStringList appList = m_client->registeredApplications();
	string appId;
	bool found = false;

	for( DCOPCStringList::ConstIterator it = appList.begin(); it != appList.end(); ++it)
    {
		appId = it->data();
		if (appId.find("phonontest")!=string::npos)
		{
			m_dcopAppId = *it;
			found = true;
			break;
		}
	}
	if (!found)
	{
		//TODO panic mode!!
		kDebug() << "oO" << endl;
		//exit(42);
	}

	//setup host list
	QByteArray data, replyData;
	DCOPCString replyType;
	QDataStream arg(&data, QIODevice::WriteOnly);
	QList<int> idList;
	
	if (!m_client->call(m_dcopAppId, "ConfigProxy", "getBranchIds()", data, replyType, replyData))
		kDebug() << "there was some error using DCOP." << endl;
	else {
		QDataStream reply(&replyData, QIODevice::ReadOnly);
	if (replyType == "QList<int>") {
		reply >> idList;
		kDebug() << "got result!" << endl;
	} else
		kDebug() << "getBranchIds returned an unexpected type of reply!" << endl;
	}

	//get the branches
	for (int i = 0; i < idList.size(); ++i)
	{
		QByteArray data, replyData;
		DCOPCString replyType;
		QDataStream arg(&data, QIODevice::WriteOnly);
	
		int id = idList.at(i);
	
		arg << id;
		if (!m_client->call(m_dcopAppId, "ConfigProxy", "getBranch(int)", data, replyType, replyData))
			kDebug() << "there was some error using DCOP." << endl;
		else {
			QDataStream reply(&replyData, QIODevice::ReadOnly);
		if (replyType == "QStringList") {
			QStringList result;
			reply >> result;
			kDebug() << "the result is: " << result.at(0).ascii() << ", " << result.at(1).ascii() << ", " << result.at(2).ascii() << endl;
			//store branch
			QString hostname = result.at(0);
			QString sinkname = result.at(1);
			QString idStr = result.at(2);
			bool inserted = false;
			//check if there already is a HostListItem for this hostname
			//simply iterate through all items (even though is not efficient, this should not take very long, since there are not very much items present)
			for (QList<HostListItem>::iterator it = m_hostList.begin(); it != m_hostList.end(); it++)
			{
				if (it->getHostname() == hostname)
				{
					if (sinkname.contains("Playback"))
					{
						it->enableAudio(true);
						it->setAudioSink(sinkname);
						it->setAudioId(idStr.toInt());
						it->setAudioEditable(false);
					}
					else
					{
						it->enableVideo(true);
						it->setVideoSink(sinkname);
						it->setVideoEditable(false);
					}
					inserted = true;
				}
			}
			
			if (!inserted) //new hostname
			{
				if (sinkname.contains("Playback"))//audio
					m_hostList.push_back(HostListItem(false, hostname, sinkname, idStr.toInt()));
				else //video
					m_hostList.push_back(HostListItem(false, hostname, sinkname));
			}
			
		} else
			kDebug() << "getBranch returned an unexpected type of reply!" << endl;
		}
	}
}

HostList::~HostList()
{
}

int HostList::rowCount(const QModelIndex & parent /* = QModelIndex()*/) const
{
	return m_hostList.size() - parent.row() - 1;
}


QVariant HostList::data(const QModelIndex & index, int role /* = Qt::DisplayRole*/) const
{

	return m_hostList[index.row()].getColumn((HostListItem::Column)index.column(), role);

}

QVariant HostList::headerData( int section, Qt::Orientation orientation, int role /* = Qt::DisplayRole*/ ) const
{
	if (role != Qt::DisplayRole)
		return QVariant();

	if (orientation == Qt::Horizontal)
	{
		return HostListItem::getColumnHeader(section);
	}
	else
		return QVariant(section+1);
}

bool HostList::setData(const QModelIndex & index, const QVariant & value, int role /* = Qt::EditRole*/)
{
	bool retval = false;
	if (role == Qt::EditRole)
	{
		retval =  m_hostList[index.row()].setColumn((HostListItem::Column)index.column(), value);
		this->layoutChanged();
	}
	return retval;
}

int HostList::columnCount(const QModelIndex & parent /* = QModelIndex()*/) const
{
	return HostListItem::memberCount - parent.column() -1;
}

Qt::ItemFlags HostList::flags ( const QModelIndex & index ) const
{
	return m_hostList[index.row()].getFlags((HostListItem::Column) index.column());
}



void HostList::addRow()
{
	int index = 0;
	if (m_hostList.size()>0)
		index = m_hostList.size()-1;
	insertRows(index, 1);
}

bool HostList::insertRows(int position, int rows, const QModelIndex &index /*= QModelIndex()*/)
{
	beginInsertRows(QModelIndex(), position, position+rows-1);
	
	for (int i = 0; i<rows ; i++)
	{
		m_hostList.push_back(HostListItem(true, "someHost", false, false, "PlaybackNode", "XDisplayNode", 0, -1, "UNKNOWN"));
	}

	endInsertRows();
	return true;
}
//bool HostList::removeRows(int position, int rows, const QModelIndex &index = QModelIndex());

void HostList::addBranches()
{
	for (QList<HostListItem>::iterator it = m_hostList.begin(); it != m_hostList.end(); it++)
	{
		QString host = it->getHostname();

		if (it->hasAudio() && it->isAudioEditable() && it->isAudioModified())
		{
			QByteArray data, replyData;
			DCOPCString replyType;
			QDataStream arg(&data, QIODevice::WriteOnly);
			int streamId = it->getAudioId();
			QString sink = it->getAudioSink();

			arg << streamId << sink << host;
			if (!m_client->call(m_dcopAppId, "ConfigProxy", "addRemoteBranch(int, QString, QString)", data, replyType, replyData))
				kDebug() << "there was some error using DCOP." << endl;
			else {
				QDataStream reply(&replyData, QIODevice::ReadOnly);
			if (replyType == "bool") {
				bool result;
				reply >> result;
				kDebug() << "the result is: " << result << endl;
			} else
				kDebug() << "doIt returned an unexpected type of reply!" << endl;
			}
		}
		
		if (it->hasVideo() && it->isVideoEditable() && it->isVideoModified())
		{
			QByteArray data, replyData;
			DCOPCString replyType;
			QDataStream arg(&data, QIODevice::WriteOnly);
			int streamId = 0;
			QString sink = it->getVideoSink();

			arg << streamId << sink << host;
			if (!m_client->call(m_dcopAppId, "ConfigProxy", "addRemoteBranch(int, QString, QString)", data, replyType, replyData))
				kDebug() << "there was some error using DCOP." << endl;
			else {
				QDataStream reply(&replyData, QIODevice::ReadOnly);
			if (replyType == "bool") {
				bool result;
				reply >> result;
				kDebug() << "the result is: " << result << endl;
			} else
				kDebug() << "doIt returned an unexpected type of reply!" << endl;
			}
		}
	}
}

#include "hostlist.moc"
