/***************************************************************************
 *                                                                         *
 *   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@irrsinnig.org>, (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/xmlnames.h"
#include "../core/ipaddress.h"
#include "../core/kmfnetzone.h"
#include "../core/kmfnethost.h"
#include "../core/kmftarget.h"
#include "../core/kmftargetconfig.h"
#include "../core/kmfprotocol.h"
#include "../core/kmfprotocolcategory.h"
#include "../core/iptable.h"
#include "../core/iptchain.h"
#include "../core/iptrule.h"
#include "../core/iptruleoption.h"
#include "../core/netfilterobject.h"
namespace KMF {
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_object = obj;
	// m_obj_id = -1;
	m_table = 0;
	m_chain = 0;
	m_rule = 0;
	m_option = 0;
	m_zone = 0;
	m_host = 0;
	m_target = 0;
	m_protocol = 0;
	m_protocolCategory = 0;
	// m_type = -1;
	if ( ! obj )
		return;

	m_obj_id = obj->uuid();

	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;
	} else if ( KMFNetZone *zone = dynamic_cast<KMFNetZone*> ( obj )  ) {
		// m_type = KMFListViewItem::NETZONE;
		m_zone = zone;
	} else if ( KMFNetHost *host = dynamic_cast<KMFNetHost*> ( obj )  ) {
		// m_type = KMFListViewItem::NETHOST;
		m_host = host;
	} else if ( KMFTarget *host = dynamic_cast<KMFTarget*> ( obj )  ) {
		// m_type = KMFListViewItem::KMFTARGET;
		m_target = host;
	} else if ( KMFProtocol *prot = dynamic_cast<KMFProtocol*> ( obj )  ) {
		// m_type = KMFListViewItem::KMFTARGET;
		// kdDebug() << "KMFListViewItem::loadNetfilterObject(..) - loaded Protocol" << endl;
		m_protocol = prot;
	} else if ( KMFProtocolCategory *protCat = dynamic_cast<KMFProtocolCategory*> ( obj )  ) {
		// m_type = KMFListViewItem::KMFTARGET;
		// kdDebug() << "KMFListViewItem::loadNetfilterObject(..) - loaded Protocol" << endl;
		m_protocolCategory = protCat;
	}
}

int KMFListViewItem::type() {
	return m_object->type();
}

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 {
	return m_object;
}

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::setupProtocolView() {
	kdDebug() << " KMFListViewItem::setupProtocolView()" << endl;
	if ( ! m_protocol ) {
		kdDebug() << " KMFListViewItem::setupProtocolView(): m_protocol == 0" << endl;
		return;
	}
	
	while( firstChild() ) {
		delete firstChild();
	}
	
	setPixmap(0, KGlobal:: iconLoader()->loadIcon("kmyfirewall", KIcon::Small ) );
	setText( 0, protocol()->name() );
	setText( 1, protocol()->description() );
	// setOpen( true );

	if ( protocol()->tcpPorts().size() > 0 ) {
		KMFListViewItem *tcpPorts = new KMFListViewItem( this, 0, protocol() );
		tcpPorts->loadNetfilterObject( protocol() );
		tcpPorts->setText( 0, i18n("TCP Ports:") );
		tcpPorts->setText( 1, protocol()->tcpPortsList() );
	}
	if ( protocol()->udpPorts().size() > 0 ) {
		KMFListViewItem *udpPorts = new KMFListViewItem( this, 0, protocol() );
		udpPorts->loadNetfilterObject( protocol() );
		udpPorts->setText( 0, i18n("UDP Ports:") );
		udpPorts->setText( 1, protocol()->udpPortsList() );
	}
	
/*	while ( it.current() ) {
	}*/
}


void KMFListViewItem::setupProtocolCategoryView() {
	while( firstChild() ) {
		delete firstChild();
	}
	
	setPixmap(0, KGlobal::iconLoader()->loadIcon( "folder" , KIcon::Small ) );
	setText( 0, protocolCategory()->name() );
	setText( 1, protocolCategory()->description() );

	TQValueList< KMFProtocol* >& prots = protocolCategory()->protocols();
	TQValueList< KMFProtocol* >::iterator it;
	for( it = prots.begin(); it != prots.end(); ++it ) {
		KMFListViewItem *prot =  new KMFListViewItem( this, 0, (*it) );
		prot->setupProtocolView();
	}
}

void KMFListViewItem::setupTargetView() {
// 	if ( target()->isCurrentTarget() ) {
// 		setFont( TQFont::Bold );
// 	} else {
// 		setFont( TQFont::Bold );
// 	}
	if ( target()->isCurrentTarget() ) {
		setPixmap(0, KGlobal:: iconLoader()->loadIcon("kmyfirewall", KIcon::Small ) );
	} else {
		setPixmap(0, KGlobal:: iconLoader()->loadIcon("enhanced_browsing", KIcon::Small ) );
	}
	setText( 0, target()->guiName() );
	setText( 1,"[" +  target()->address()->toString() + "]" );
	setText( 2, target()->config()->oS() );
	setText( 3, target()->config()->backend() );	
	setText( 4, target()->description() );
}

void KMFListViewItem::setupNetHostView() {
	setPixmap(0, KGlobal:: iconLoader()->loadIcon("home_white", KIcon::Small ) );
	setText( 0, host()->guiName() );
	setText( 1,"[" +  host()->address()->toString() + "]" );
		
	if ( host()->name().startsWith("incoming_world") ) {
		setText( 2,"" +  i18n("%1 -> Localhost").arg( host()->guiName() ) );
	}
	if ( host()->name().startsWith("outgoing_world") ) {
		setText( 2, i18n("Localhost -> %1").arg( host()->guiName() ) );
	}
}



void KMFListViewItem::setupZoneView() {
	kdDebug() << "void KMFListViewItem::setupZoneView()" << endl;
	if ( type() != NetfilterObject::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() ) );
	
/*	setText( 2,"" +  i18n("%1 -> Localhost").arg( m_zone->guiName() ) );*/
	setText( 4,"" +  m_zone->description() );
	
	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() ) );
		
	}

	TQPtrListIterator<KMFNetZone> it ( m_zone->zones() );
	while ( it.current() ) {
		KMFListViewItem *item = new KMFListViewItem( this, 0, it.current() );
		item->loadNetfilterObject( it.current() );
		item->setupZoneView();
		// item->setRenameEnabled( 0, true );
		setOpen(true);
		++it;
	}
	
	TQPtrListIterator<KMFTarget> it2 ( m_zone->hosts() );
	while ( it2.current() ) {
		if ( it2.current()->type() == NetfilterObject::NETHOST ) {
			KMFNetHost *host = dynamic_cast<KMFNetHost*>( it2.current() );
			KMFListViewItem *item = new KMFListViewItem( this, 0,  host );
			item->loadNetfilterObject( host );
			item->setupNetHostView();
			setOpen(true);
		} else if ( it2.current()->type() == NetfilterObject::KMFTARGET ) {
			KMFTarget* target = dynamic_cast<KMFTarget*>( it2.current() );
			kdDebug() << "Added KMFTarget" << endl;
			KMFListViewItem *item = new KMFListViewItem( this, 0,  target );
			item->loadNetfilterObject( target );
			item->setupTargetView();
			// item->setRenameEnabled( 0, true );
			setOpen(true);
		}
		
		
		
		/*
		if ( KMFTarget* target = dynamic_cast<KMFTarget*>( it2.current() ) ){
			kdDebug() << "Added KMFTarget" << endl;
			KMFListViewItem *item = new KMFListViewItem( this, 0,  target );
			item->loadNetfilterObject( target );
			item->setupTargetView();
			// item->setRenameEnabled( 0, true );
			setOpen(true);
		} else if ( KMFNetHost *host = dynamic_cast<KMFNetHost*>( it2.current() ) ) {
			kdDebug() << "Added KMFNetHost" << endl;
			KMFListViewItem *item = new KMFListViewItem( this, 0,  host );
			item->loadNetfilterObject( host );
			// item->setRenameEnabled( 0, true );
			item->setupNetHostView();*/

/*			item->setPixmap(0, loader->loadIcon("home_white", KIcon::Small ) );
			item->setText( 0, host->guiName() );
			item->setText( 1,"[" +  host->address()->toString() + "]" );
		
			if ( host->name().startsWith("incoming_world") ) {
				item->setText( 2,"" +  i18n("%1 -> Localhost").arg( host->guiName() ) );
			}
			if ( host->name().startsWith("outgoing_world") ) {
				item->setText( 2, i18n("Localhost -> %1").arg( host->guiName() ) );
			}*/
// 			setOpen(true);
// 			// ++it2;
// 		}  
		
		
		
		
		
// 		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;
		
	}
}

TQString KMFListViewItem::key( int column, bool ascending ) const {
// 	kdDebug() << "TQString KMFListViewItem::key( int column, bool ascending )" << endl;
	if ( ! m_object ) {
		return TQListViewItem::key( column, ascending );
	}
	
	if ( m_object->type() ==  NetfilterObject::TABLE ) {
		if ( text(0) == i18n("Documentation:") ) {
			return "0000";
		}
	} else if (  m_object->type() ==  NetfilterObject::CHAIN ) {
		if ( text(0) == i18n("Documentation:") ||  text(2) == Constants::InputChain_Name ) {
			return "0000";
		} else if ( text(0) == i18n("Chain logging:")  || text(2) == Constants::OutputChain_Name  ) {
			return "1111";
		} else if ( text(0) == i18n("Chain Feeds:")   || text(2) ==  Constants::ForwardChain_Name  ) {
			return "2222";
		} else if ( text(0) == i18n("Chain forwards:")  || text(2) ==  Constants::PreRoutingChain_Name ) {
			return "3333";
		} else if ( text(0) == i18n("Rule(s):") || text(2) ==  Constants::PostRoutingChain_Name ) {
			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 );
			TQString ret = "";
			return ret.setNum( 5555 + index );
		}
	} else if (  m_object->type() ==  NetfilterObject::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 {
			TQString ret = "";
			ret = ret.setNum( m_rule->ruleNum() );
			while ( ret.length() < 5 ) {
				ret.prepend("0");
			}
			return ret;
		}
	} else if (  m_object->type() ==  NetfilterObject::RULEOPTION ) {
		TQPtrList<TQString>* types = IPTRuleOption::getAvailableOptionTypes();
		TQPtrListIterator< TQString > it ( *types );
		int i = 0;
		int index = -1;
		bool finished = false;
		while ( it.current() && ! finished ) {
			TQString type = *it.current();
			++it;
// 			kdDebug() << "Checking type: " << type << endl;
			if ( type == m_option->getOptionType() ) {
				index = i;
				finished = true;
			}
			i++;
		}
		TQString ret = "";
// 		kdDebug() << "TQString KMFListViewItem::key(...) returnd: " << ret << " for ruleoption type: " <<  m_option->getOptionType() <<  endl;
		return ret.setNum( 5555 + index );
	} else if (  m_object->type() ==  NetfilterObject::NETZONE ) {
		if ( m_zone ) {
			//return "0000";
			return "0000" + m_zone->guiName();
		}
	} else if (  m_object->type() == NetfilterObject::NETHOST ) {
		if ( m_host ) {
			// return "1111";
			return "1111" + m_host->guiName();
		}
	} else if (  m_object->type() == NetfilterObject::KMFTARGET ) {
		if ( m_host ) {
			// return "1111";
			return "1111" + m_target->guiName();
		}
	}


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

}
