/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/
/*
Author: Christian Hubinger <chubinger@gmail.com>, (C) 2001-2004
*/

#include "kmflistviewitem.h"

// QT includes

// KDE includes
#include <kdebug.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kglobal.h>

// Project includes
#include "../core/ipaddress.h"
#include "../core/kmfnetzone.h"
#include "../core/kmfnethost.h"
#include "../core/iptable.h"
#include "../core/iptchain.h"
#include "../core/iptrule.h"
#include "../core/iptruleoption.h"
#include "../core/netfilterobject.h"

KMFListViewItem::KMFListViewItem( KListView *parent, NetfilterObject* obj ) : KListViewItem( parent ) {
	m_top = false;
	loadNetfilterObject(obj);
	m_inUse = false;
}
KMFListViewItem::KMFListViewItem( KListView *parent, KListViewItem *after, NetfilterObject* obj ) : KListViewItem( parent, after ) {
	m_top = false;
	loadNetfilterObject(obj);
	m_inUse = false;
}
KMFListViewItem::KMFListViewItem( KListViewItem *parent, NetfilterObject* obj ) : KListViewItem( parent ) {
	m_top = false;
	loadNetfilterObject(obj);
	m_inUse = false;
}
KMFListViewItem::KMFListViewItem( KListViewItem *parent, KListViewItem *after, NetfilterObject* obj ) : KListViewItem( parent, after ) {
	m_top = false;
	loadNetfilterObject(obj);
	m_inUse = false;
}

KMFListViewItem::~KMFListViewItem() {
}

void KMFListViewItem::loadNetfilterObject( NetfilterObject* obj ) {
	m_obj_id = -1;
	m_table = 0;
	m_chain = 0;
	m_rule = 0;
	m_option = 0;
	m_zone = 0;
	m_host = 0;
	m_type = -1;
	if ( ! obj )
		return;

	m_obj_id = obj->objectID();

	if ( IPTable *table = dynamic_cast<IPTable*> ( obj ) ) {
		m_type = KMFListViewItem::TABLE;
		m_table = table;
	} else if ( IPTChain *chain = dynamic_cast<IPTChain*> ( obj ) ) {
		m_type = KMFListViewItem::CHAIN;
		m_chain = chain;
	} else if ( IPTRule *rule = dynamic_cast<IPTRule*> ( obj ) ) {
		m_type = KMFListViewItem::RULE;
		m_rule = rule;
	} else if ( IPTRuleOption *opt = dynamic_cast<IPTRuleOption*> ( obj )  ) {
		m_type = KMFListViewItem::RULEOPTION;
		m_option = opt;
	} if ( KMFNetZone *zone = dynamic_cast<KMFNetZone*> ( obj )  ) {
		m_type = KMFListViewItem::NETZONE;
		m_zone = zone;
	}  if ( KMFNetHost *host = dynamic_cast<KMFNetHost*> ( obj )  ) {
		m_type = KMFListViewItem::NETHOST;
		m_host = host;
	}
}

void KMFListViewItem::setTopItem( bool onoff ) {
	m_top = onoff;
}

void KMFListViewItem::setInUse( bool onoff ) {
	if ( ! onoff )
		setChildrenInUse ( true );
	m_inUse = onoff;
}

bool KMFListViewItem::inUse() {
	bool ret = m_inUse;
	m_inUse = false;
	return ret;
}


NetfilterObject* KMFListViewItem::netfilterObject() const {
	if ( m_type == TABLE )
		return m_table;
	else if ( m_type == CHAIN )
		return m_chain;
	else if ( m_type == RULE )
		return m_rule;
	else if ( m_type == RULEOPTION )
		return m_option;
	else if ( m_type == NETZONE )
		return m_zone;
	else if ( m_type == NETHOST )
		return m_host;
	return 0;
}

void  KMFListViewItem::setChildrenInUse( bool onoff ) {
	KMFListViewItem* item = this;
	item = dynamic_cast<KMFListViewItem*> ( item->firstChild() );
	while ( item ){
		item->setInUse( onoff );
		item = dynamic_cast<KMFListViewItem*> ( item->nextSibling() );
	}
}
void  KMFListViewItem::deleteChildren() {
	while ( firstChild() ) {
		kdDebug() << "Deleting Item: " << text(0) << " " << text(2) << endl;
		delete firstChild();
	}
}

void KMFListViewItem::setupZoneView() {
	kdDebug() << "void KMFListViewItem::setupZoneView()" << endl;
	if ( m_type != NETZONE )
		return;
	KIconLoader *loader = KGlobal:: iconLoader();

	setText( 0,m_zone->guiName() );
	if ( m_zone->name() == "incoming_world" || m_zone->name() == "outgoing_world" )
		setPixmap(0, loader->loadIcon("network", KIcon::Small ) );
	else
	setPixmap(0, loader->loadIcon("network_local", KIcon::Small ) );

	if (  m_zone->name().startsWith("incoming_world") ||  m_zone->name().startsWith("outgoing_world") )
		setText( 1, "[" + m_zone->address()->toString() + i18n("/%1]").arg( m_zone->maskLength() ) );

	if ( m_zone->name().startsWith("incoming_world") )
		setText( 2,"" +  i18n("%1 -> Localhost").arg( m_zone->guiName() ) );
	if ( m_zone->name().startsWith("outgoing_world") )
		setText( 2, i18n("Localhost -> %1").arg( m_zone->guiName() ) );

	QPtrListIterator<KMFNetZone> it ( m_zone->zones() );
	while ( it.current() ) {
		KMFListViewItem *item = new KMFListViewItem( this, 0,  it.current() );
		item->loadNetfilterObject( it.current() );
		item->setupZoneView();
		setOpen(true);
		++it;
	}
	QPtrListIterator<KMFNetHost> it2 ( m_zone->hosts() );
	while ( it2.current() ) {
		KMFListViewItem *item = new KMFListViewItem( this, 0,  it2.current() );
		item->loadNetfilterObject( it2.current() );
		item->setPixmap(0, loader->loadIcon("home_white", KIcon::Small ) );
		item->setText( 0, it2.current()->guiName() );
		item->setText( 1,"[" +  it2.current()->address()->toString() + "]" );
		
		if ( it2.current()->name().startsWith("incoming_world") ) {
			item->setText( 2,"" +  i18n("%1 -> Localhost").arg( it2.current()->guiName() ) );
		}
		if ( it2.current()->name().startsWith("outgoing_world") ) {
			item->setText( 2, i18n("Localhost -> %1").arg( it2.current()->guiName() ) );
		}
		setOpen(true);
		++it2;
	}

}

QString KMFListViewItem::key( int column, bool ascending ) const {
// 	kdDebug() << "QString KMFListViewItem::key( int column, bool ascending )" << endl;
	if ( m_type ==  TABLE ) {
		if ( text(0) == i18n("Documentation:") ) {
			return "0000";
		}
	} else if ( m_type ==  CHAIN ) {
		if ( text(0) == i18n("Documentation:") ||  text(2) == "INPUT" ) {
			return "0000";
		} else if ( text(0) == i18n("Chain logging:")  || text(2) == "OUTPUT"  ) {
			return "1111";
		} else if ( text(0) == i18n("Chain Feeds:")   || text(2) ==  "FORWARD"  ) {
			return "2222";
		} else if ( text(0) == i18n("Chain forwards:")  || text(2) ==  "PREROUTING" ) {
			return "3333";
		} else if ( text(0) == i18n("Rule(s):") || text(2) ==  "POSTROUTING" ) {
			return "4444";
		} else if ( text(0) == i18n("Cmd:") ) {
			return "9999";
		} else if (text(0).contains( i18n("Chain (User-Defined):") ) ) {
			int index = m_chain->table()->chains().find( m_chain );
			QString ret = "";
			return ret.setNum( 5555 + index );
		}
	} else if ( m_type ==  RULE ) {
		if ( text(0) == i18n("Documentation:") ) {
			return "0000";
		} else if ( text(0) == i18n("Cmd:") ) {
			return "8888";
		} else if ( text(0) == i18n("Target:") ) {
			return "9999";
		} else {
			QString ret = "";
			ret = ret.setNum( m_rule->ruleNum() );
			while ( ret.length() < 5 ) {
				ret.prepend("0");
			}
			return ret;
		}
	} else if ( m_type ==  RULEOPTION ) {
		QPtrList<QString>* types = IPTRuleOption::getAvailableOptionTypes();
		QPtrListIterator< QString > it ( *types );
		int i = 0;
		int index = -1;
		bool finished = false;
		while ( it.current() && ! finished ) {
			QString type = *it.current();
			++it;
// 			kdDebug() << "Checking type: " << type << endl;
			if ( type == m_option->getOptionType() ) {
				index = i;
				finished = true;
			}
			i++;
		}
		QString ret = "";
// 		kdDebug() << "QString KMFListViewItem::key(...) returnd: " << ret << " for ruleoption type: " <<  m_option->getOptionType() <<  endl;
		return ret.setNum( 5555 + index );
	} else if ( m_type ==  NETZONE ) {
		if ( m_zone )
			return "" + m_zone->name();
	} else if ( m_type == NETHOST ) {
		if ( m_host )
			return "" + m_host->name();
	}


	return KListViewItem::key( column, ascending );
}
