//
//
// C++ Implementation: $MODULE$
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@gmail.com>, (C) 2003
//
// Copyright: See COPYING file that comes with this distribution
//
//
/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/


#include "kmfgenericinterfaceprotocol.h"

// QT includes
#include <qlistview.h>
#include <qcheckbox.h>
#include <qspinbox.h>
#include <qcombobox.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qgroupbox.h>
#include <qwidgetstack.h>
#include <qtextedit.h>
#include <qtimer.h>


// KDE includes
#include <kdebug.h>
#include <klocale.h>
#include <klistview.h>
#include <kcombobox.h>
#include <kpopupmenu.h>
#include <kiconloader.h>
#include <kinputdialog.h>
#include <knuminput.h>

// Project includes
#include "../core/kmfgenericdoc.h"
#include "../core/kmfprotocol.h"
#include "../core/kmfnetzone.h"
#include "../core/kmfnethost.h"
#include "../core/kmferror.h"

#include "../kmfwidgets/kmflistviewitem.h"
#include "../kmfwidgets/kmfchecklistitem.h"
#include "../kmfwidgets/kmfnetworkwidget.h"

KMFGenericInterfaceProtocol::KMFGenericInterfaceProtocol( QWidget *parent, const char *name, WFlags f ) : KMyFirewallGenericInterfaceProtocolWidget( parent, name, f ) {
	loadIcons();
	m_contextMenu = new KPopupMenu( this, "m_contextMenu" );
	m_lv_protocols->setFullWidth( true );

	m_zoneOptions = new QWidget( m_widgetStack, "ads" );
	QLabel *desc = new QLabel( i18n("<qt>Define your network zone here by defining the Networks IP and netmask.</qt>") , m_zoneOptions, "ad" );
	
	QLabel *desc2 = new QLabel( i18n("Zone Documentation:") , m_zoneOptions, "ad" );
//	m_cb_dead_end = new QCheckBox( i18n("Do not inherit Access Rules"), m_zoneOptions, "ad" );
	m_zone_desc = new QTextEdit( m_zoneOptions, "adf" );
	m_zone_desc->setReadOnly( false );
	QGridLayout *grid = new QGridLayout( m_zoneOptions, 3,2);
	m_network_widget = new KMFNetworkWidget( m_zoneOptions, "af" );
	
// 	grid->addMultiCellWidget( desc, 0,1,0,0 );
	grid->addWidget( desc, 0,0 );
//	grid->addWidget( m_cb_dead_end,2,0);
	grid->addWidget( m_network_widget, 1,0 );
	grid->addWidget( desc2,0,1 );
	grid->addMultiCellWidget( m_zone_desc, 1,2,1,1);
	m_widgetStack->addWidget( m_zoneOptions );
	
	// Zone view
	connect( m_lv_zones, SIGNAL( pressed( QListViewItem* ) ) ,
		this, SLOT( slotNewItemSelected( QListViewItem* ) ) );
		
	connect( m_lv_zones, SIGNAL( contextMenuRequested ( QListViewItem*, const QPoint&, int ) ),
		this, SLOT( slotZoneRBM( QListViewItem*, const QPoint&, int ) ) );
	
	connect( m_lv_zones, SIGNAL( itemRenamed ( QListViewItem *, int, const QString & ) ) ,
		this, SLOT( slotRenameItem( QListViewItem *, int, const QString & ) ) );
		
	connect( m_lv_protocols, SIGNAL( pressed( QListViewItem* ) ),
		this, SLOT( slotNewProtocolSelected( QListViewItem* ) ) );

	
	// Protocol edit
	connect( m_cb_limit, SIGNAL( toggled( bool ) ),
		this, SLOT( slotEnableProtocolLimit( bool ) ) );
				
	connect( m_sb_limit_rate, SIGNAL( valueChanged( int ) ),
		this, SLOT( slotSetProtocolLimitRate( int ) ) );
	
	connect( m_cb_limit_interval, SIGNAL( highlighted( const QString& ) ), 	this, SLOT( slotSetProtocolLimitInterval( const QString& ) ) );

	connect( m_cb_log, SIGNAL( toggled( bool ) ),
		this, SLOT( slotEnableProtocolLogging( bool ) ) );
	
	// Zone Edit
	connect( m_network_widget,SIGNAL( sigZoneChanged( KMFNetZone* ) ),
		this,SLOT( slotZoneChanged( KMFNetZone* ) ) );
	
// 	connect( m_cb_dead_end, SIGNAL( toggled( bool ) ),
// 		this, SLOT( slotZoneDeadEnd( bool ) ) );

		
	// Host Edit
	connect( m_cb_host_limit, SIGNAL( toggled( bool ) ), 
		this, SLOT( slotHostLimitToggled( bool ) ) );	
	
	connect( m_sb_host_rate, SIGNAL( valueChanged( int ) ),
		this, SLOT( slotHostLimitValueChanged( int ) ) );
	
	connect( m_cb_limit_host_interval, SIGNAL( activated( int ) ),
		this, SLOT( slotHostLimitScaleChanged( int ) ) );
	
	connect( m_cb_host_log, SIGNAL( toggled( bool ) ),
		this, SLOT( slotHostLogToggled( bool ) ) );
		
	connect( m_sb_host_1, SIGNAL( valueChanged( const QString& ) ),
		this, SLOT( slotAddressChanged( const QString& ) ) );
	connect( m_sb_host_2, SIGNAL( valueChanged( const QString& ) ),
		this, SLOT( slotAddressChanged( const QString& ) ) );
	connect( m_sb_host_3, SIGNAL( valueChanged( const QString& ) ),
		this, SLOT( slotAddressChanged( const QString& ) ) );
	connect( m_sb_host_4, SIGNAL( valueChanged( const QString& ) ),
		this, SLOT( slotAddressChanged( const QString& ) ) );

	

	// Main win
	connect( m_c_restrictOutgoing, SIGNAL( clicked() ),
		this, SLOT( slotRestrictionChanged() ) );
	
	connect( m_c_allowIncoming, SIGNAL( clicked() ),
		this, SLOT( slotRestrictionChanged() ) );
	
	connect( m_zoneSelect, SIGNAL( activated( const QString& ) ),
		this, SLOT( slotCurrentZoneChanged( const QString& ) ) );	
		
	QTimer *timer = new QTimer( this );
	connect( timer, SIGNAL( timeout() ),
		this, SLOT( slotTimerShot() ) );
	timer->start( 1000, FALSE );
	
	m_zone = 0;
	m_type = -1;
	m_protocol = 0;
}


KMFGenericInterfaceProtocol::~KMFGenericInterfaceProtocol() {}

void KMFGenericInterfaceProtocol::loadDoc( KMFGenericDoc* doc ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::loadDoc( KMFGenericDoc* doc )" << endl;
	m_doc = doc;
	m_incoming_root_zone = m_doc->incomingZone();
	m_outgoing_root_zone = m_doc->outgoingZone();
	m_zoneSelect->clear();
	m_zoneSelect->insertItem( i18n("Incoming Zone") );
	m_zoneSelect->insertItem( i18n("Outgoing Zone") );
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::setType( int type ) {
	if ( type == INCOMING ) {
/*		m_l_page_desc->setText( i18n( "<qt>If you provide any kind of service on your computer "
		                              "(if your computer is a server for others) and you want"
		                              "other hosts to be able to use them, you have to enable "
		                              "the protocols you wish to provide.<br>"
		                              "Click \"Allow Incoming Connections\" to setup the rules you need.</qt>" ) );
		m_cb_enable_config->setText( i18n( "Allow Incoming Connections" ) );*/
		m_type = INCOMING;
	} else if ( type == OUTGOING ) {
/*		m_l_page_desc->setText( i18n( "<qt>By allowing only a few services you can prevent users "
		                              "from using services you don't want them to use (e.g. FTP). "
		                              "Per default all connections to the internet are permitted and "
		                              "all incoming connections are denied.<br>"
		                              "Click \"Restrict Outgoing Connections\" to setup the rules you need.</qt>" ) );
		m_cb_enable_config->setText( i18n( "Restrict Outgoing Connections" ) );*/
		m_type = OUTGOING;
	}
}

void KMFGenericInterfaceProtocol::slotUpdateView() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotUpdateView()" << endl;
	m_lv_protocols->clear();
	m_lv_zones->clear();
	
	m_available_protocols = m_doc->protocolLibrary();
	m_c_allowIncoming->blockSignals( true );
	m_c_restrictOutgoing->blockSignals( true );
	m_c_allowIncoming->setChecked( m_doc->allowIncomingConnections() );
	m_c_restrictOutgoing->setChecked( m_doc->restrictOutgoingConnections() );
	m_c_allowIncoming->blockSignals( false );
	m_c_restrictOutgoing->blockSignals( false );
	
	QString zone = m_zoneSelect->currentText();
	if ( zone == i18n("Incoming Zone") ) {
		kdDebug() << "Showing Incoming Zone" << endl;
		KMFListViewItem *item = new KMFListViewItem( m_lv_zones, 0, m_incoming_root_zone );
		item->setupZoneView();
	} else if ( zone == i18n("Outgoing Zone") ) {
		kdDebug() << "Showing Outgoing Zone" << endl;
		KMFListViewItem *item2 = new KMFListViewItem( m_lv_zones, 0, m_outgoing_root_zone );
		item2->setupZoneView();
	}

	if ( ! m_doc->allowIncomingConnections() && ! m_doc->restrictOutgoingConnections() ) {
		m_lv_zones->setEnabled( false );
		m_lv_protocols->setEnabled( false );
		m_widgetStack->setEnabled( false );
		return;
	}
	
	m_lv_zones->setEnabled( true );
	m_lv_protocols->setEnabled( true );
	m_widgetStack->setEnabled( true );

	m_gb_protocol_option->setEnabled( false );
	m_l_protocol_desc->setEnabled( false );
	if ( m_host ) {
		if ( KMFListViewItem *item = findItem( m_host->objectID() ) ) {
			// slotNewZoneSelected( item );
			m_lv_zones->setSelected( item, true );
		}
	} else if ( m_zone ) {
		if ( KMFListViewItem *item = findItem( m_zone->objectID() ) ) {
			// slotNewZoneSelected( item );
			m_lv_zones->setSelected( item, true );
		}
	}
	m_lv_zones->setSorting( 0 , false );
}

void KMFGenericInterfaceProtocol::slotRestrictionChanged() {
	m_doc->setRestrictOutgoingConnections( m_c_restrictOutgoing->isChecked() );
	m_doc->setAllowIncomingConnections( m_c_allowIncoming->isChecked() );
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::slotCurrentZoneChanged( const QString& ) {
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::slotNewItemSelected( QListViewItem* item ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotNewItemSelected( QListViewItem* item )" << endl;
	if ( ! item )
		return ;
	m_gb_protocol_option->setEnabled( false );
	m_l_protocol_desc->setEnabled( false );
	m_protocol = 0;
	m_zone = 0;
	m_host = 0;

	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0 && kmfitem->type() == KMFListViewItem::NETZONE ) {
		kdDebug() << "Selected NETZONE" << endl;
		m_widgetStack->raiseWidget( m_zoneOptions );
		m_zone = kmfitem->zone();
		if ( m_zone ) {
			kdDebug() << "kmfitem->zone() pointer is valid" << endl;
			kmfitem->setText( 0,m_zone->guiName() );
			kmfitem->setText( 1, "[" + m_zone->address()->toString() + i18n("/%1]").arg( m_zone->maskLength() ) );

			m_lv_protocols->clear();
			QPtrListIterator<KMFProtocol> it( m_available_protocols );
			while ( it.current() ) {
				KMFProtocol * prot = it.current();
				++it;
				KMFCheckListItem *item = new KMFCheckListItem( m_lv_protocols, 0 , prot->name() , QCheckListItem::CheckBox, prot );
				item->setText( 0, prot->name() );
				if ( m_zone->findProtocol( prot->name() ) ) {
					item->setOn( true );
				}
				if ( m_zone->protocolInherited( prot->name() ) ) {
					item->setOn( true );
					item->setEnabled( false );
				}
				if ( ! m_zone->findProtocol( prot->name() )  && ! m_zone->protocolInherited( prot->name() ) ) {
					item->setOn( false );
				}
			}
			m_zone_desc->setText( m_zone->description() );
			m_network_widget->loadZone( m_zone );
			
			if ( m_zone->name() == "incoming_world" || m_zone->name() == "outgoing_world" ) {
				m_network_widget->allowEdit( false );
// 				m_cb_dead_end->setEnabled( false );
				m_zone_desc->setReadOnly( true );
			} else {
				m_network_widget->allowEdit( true );
// 				m_cb_dead_end->setEnabled( true );
				m_zone_desc->setReadOnly( false );
			}
			 
// 			m_cb_dead_end->setChecked( m_zone->deadEnd() );
		} /*else {
			m_cb_dead_end->setEnabled( false );
			m_zone_desc->setReadOnly( true );
			m_network_widget->loadZone( m_zone );
		}*/
	} else if ( kmfitem != 0 && kmfitem->type() == KMFListViewItem::NETHOST ) {
		kdDebug() << "Selected NETHOST" << endl;
		m_widgetStack->raiseWidget( m_hostOptions );
		m_host = kmfitem->host();
		m_zone = m_host->zone();
		if ( m_host ) {
			kdDebug() << "kmfitem->host() pointer is valid" << endl;
			m_sb_host_1->setEnabled( true );
			m_sb_host_2->setEnabled( true );
			m_sb_host_3->setEnabled( true );
			m_sb_host_4->setEnabled( true );
			m_host_desc->setReadOnly( false );
			m_sb_host_1->blockSignals( true );
			m_sb_host_2->blockSignals( true );
			m_sb_host_3->blockSignals( true );
			m_sb_host_4->blockSignals( true );
			m_sb_host_1->setValue( m_host->address()->getDigit(0) );
			m_sb_host_2->setValue( m_host->address()->getDigit(1) );
			m_sb_host_3->setValue( m_host->address()->getDigit(2) );
			m_sb_host_4->setValue( m_host->address()->getDigit(3) );
			m_sb_host_1->blockSignals( false );
			m_sb_host_2->blockSignals( false );
			m_sb_host_3->blockSignals( false );
			m_sb_host_4->blockSignals( false );

			m_lv_protocols->clear();
			QPtrListIterator<KMFProtocol> it( m_available_protocols );
			m_host_desc->setText( m_host->description() );
			if ( m_zoneSelect->currentText() == i18n("Incoming Zone") ) {
				m_cb_host_log->setChecked( m_host->logIncoming() );
			} else if ( m_zoneSelect->currentText() == i18n("Outgoing Zone") ) {
				m_cb_host_log->setChecked( m_host->logOutgoing() );
			}
			
			if (  m_host->limit() ) {
				m_cb_host_limit->setChecked( true );
				m_sb_host_rate->setEnabled( true );
				m_cb_limit_host_interval->setEnabled( true );
				m_sb_host_rate->setValue( m_host->limitRate() );
				kdDebug() << "Found host log scale: " << m_host->limitScale() << endl;
				
				m_cb_limit_host_interval->blockSignals( true );
				if (  m_host->limitScale() == "second" ) {
					m_cb_limit_host_interval->setCurrentItem( 0 );
				} else if ( m_host->limitScale() == "minute" ) {
					m_cb_limit_host_interval->setCurrentItem( 1 );
				} else if ( m_host->limitScale() == "hour" ) {
					m_cb_limit_host_interval->setCurrentItem( 2 );
				} else {
					kdDebug() << "Found illefal value: " << m_host->limitScale() << endl;
				}
				m_cb_limit_host_interval->blockSignals( false );
				
			} else {
				m_cb_host_limit->setChecked( false );
				m_sb_host_rate->setEnabled( false );
				m_cb_limit_host_interval->setEnabled( false );
			}
			
			
			while ( it.current() ) {
				KMFProtocol * prot = it.current();
				// kdDebug() << "Adding protocol: " << prot->name() << " to list." << endl;
				++it;
				KMFCheckListItem *item = new KMFCheckListItem( m_lv_protocols, 0 , prot->name() , QCheckListItem::CheckBox, prot );
				item->setText( 0, prot->name() );
				if ( m_host->findProtocol( prot->name() ) ) {
					item->setOn( true );
				}
				if ( m_host->protocolInherited( prot->name() ) ) {
					item->setOn( true );
					item->setEnabled( false );
				}
				if ( ! m_host->findProtocol( prot->name() )  && ! m_host->protocolInherited( prot->name() ) ) {
					item->setOn( false );
				}
			}
			
			
		} else {
			m_sb_host_1->setEnabled( false );
			m_sb_host_2->setEnabled( false );
			m_sb_host_3->setEnabled( false );
			m_sb_host_4->setEnabled( false );
			m_host_desc->setReadOnly( true );
		}
	}
	kdDebug() << "Laving slotNewItemSelected()" << endl;
	// slotUpdateView()
	// slotAddressChanged("");

}

void KMFGenericInterfaceProtocol::slotZoneRBM( QListViewItem* item, const QPoint& point, int ) {
	if ( ! item )
		return ;
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0  && kmfitem->type() == KMFListViewItem::NETZONE ) {
		kdDebug() << "Setting up Zone RBM:" << endl;
		m_host = 0;
		m_zone = 0;
		m_zone = kmfitem->zone();
		if ( m_zone ) {
			m_contextMenu->clear();
			QString name = m_zone->name();
			QString lab_str = i18n("Zone: %1").arg( m_zone->guiName() );
			m_contextMenu->insertTitle( icon_chain, lab_str );
			m_contextMenu->insertItem( icon_new, i18n( "Add Host..." ), this, SLOT( slotAddHost() ) );

			
				m_contextMenu->insertSeparator();
				m_contextMenu->insertItem( icon_new, i18n( "Add Zone..." ), this, SLOT( slotAddZone() ) );
			if ( m_zone->name() != "incoming_world" && m_zone->name() != "outgoing_world" ) {
				m_contextMenu->insertItem( icon_rename, i18n( "Rename Zone..." ), this, SLOT( slotRenameZone() ) );
				m_contextMenu->insertSeparator();
				m_contextMenu->insertItem( icon_del, i18n( "Delete Zone" ), this, SLOT( slotDelZone() ) );
			}

			m_contextMenu->popup( point );
		}
	} else if ( kmfitem != 0  && kmfitem->type() == KMFListViewItem::NETHOST ) {
		kdDebug() << "Setting up Host RBM:" << endl;
		m_host = 0;
		m_host = kmfitem->host();
		if ( m_host ) {
			m_contextMenu->clear();
			QString name = m_host->name();
			QString lab_str = i18n("Host: %1").arg( m_host->guiName() );
			m_contextMenu->insertTitle( icon_chain, lab_str );
			m_contextMenu->insertItem( icon_rename, i18n( "Rename Host..." ), this, SLOT( slotRenameHost() ) );
			m_contextMenu->insertItem( icon_rename, i18n( "Delete Host..." ), this, SLOT( slotDelHost() ) );
			m_contextMenu->popup( point );
		}
	}
}



void KMFGenericInterfaceProtocol::slotNewProtocolSelected( QListViewItem* item ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotNewProtocolSelected( QListViewItem* )" << endl;
	if ( ! item || ! m_zone ) {
		kdDebug() << "WARNING: no item selected" << endl;
		return ;
	}
	m_widgetStack->raiseWidget( m_protocolOptions );
	if ( KMFCheckListItem * it = dynamic_cast<KMFCheckListItem*> ( item ) ) {
		m_l_protocol_desc->setEnabled( true );
		QString text = i18n( "<qt><b>Description: </b>%1<br>" ).arg( it->protocol() ->description() );
		QStringList tcpports = it->protocol() ->tcpPorts();
		QStringList udpports = it->protocol() ->udpPorts();
		if ( tcpports.count() > 0 ) {
			text += i18n( "<b>Affected TCP ports: </b>" );
			for ( QStringList::Iterator iterator = tcpports.begin(); iterator != tcpports.end(); ++iterator ) {
				text += *iterator + ",";
			}
			if ( text.endsWith( "," ) )
				text = text.left( text.length() - 1 );

			text +="<br>";
		}
		if ( udpports.count() > 0 ) {
			text += i18n( "<b>Affected UDP ports: </b>" );
			for ( QStringList::Iterator iterator = udpports.begin(); iterator != udpports.end(); ++iterator ) {
				text += *iterator + ",";
			}
			if ( text.endsWith( "," ) )
				text = text.left( text.length() - 1 );
		}
		text += "</qt>";
		m_l_protocol_desc->setText( text );

		if ( m_zone && ! m_host ) {
			if ( it->isOn() ) {
				if ( KMFProtocol * pro = m_zone->addProtocol( it->protocol() ->name(), it->protocol() ->getDOMTree() ) ) {
					kdDebug() << "Added Protocol to zone: " << m_zone-> name()  << endl;
					m_protocol = pro;
				} else if ( KMFProtocol* pro = m_zone->findProtocol( it->protocol()->name() ) ) {
					m_protocol = pro;
				} else {
					m_protocol = 0;
				}
				m_gb_protocol_option->setEnabled( true );
				if ( m_protocol ) {
					m_cb_log->setChecked( m_protocol ->logging() );
					if ( m_protocol ->limit() > 0 ) {
						m_cb_limit->setChecked( true );
						m_sb_limit_rate->setValue( m_protocol ->limit() );
						if ( m_protocol ->limitInterval() == "second" )
							m_cb_limit_interval->setCurrentItem( 0 );
						if ( m_protocol ->limitInterval() == "minute" )
							m_cb_limit_interval->setCurrentItem( 1 );
						if ( m_protocol ->limitInterval() == "hour" )
							m_cb_limit_interval->setCurrentItem( 2 );
					} else {
						m_cb_limit->setChecked( false );
					}
				}
			} else {
				m_gb_protocol_option->setEnabled( false );
				m_zone->delProtocol( it->protocol() );
			}
		} else if ( m_host ) {
			if ( it->isOn() ) {
				if ( KMFProtocol * pro = m_host->addProtocol( it->protocol() ->name(), it->protocol() ->getDOMTree() ) ) {
					kdDebug() << "Added Protocol to host: " << m_host-> name()  << endl;
					m_protocol = pro;
				} else if ( KMFProtocol* pro = m_host->findProtocol( it->protocol()->name() ) ) {
					m_protocol = pro;
				} else {
					m_protocol = 0;
				}
				m_gb_protocol_option->setEnabled( true );
				if ( m_protocol ) {
					m_cb_log->setChecked( m_protocol ->logging() );
					if ( m_protocol ->limit() > 0 ) {
						m_cb_limit->setChecked( true );
						m_sb_limit_rate->setValue( m_protocol ->limit() );
						if ( m_protocol ->limitInterval() == "second" )
							m_cb_limit_interval->setCurrentItem( 0 );
						if ( m_protocol ->limitInterval() == "minute" )
							m_cb_limit_interval->setCurrentItem( 1 );
						if ( m_protocol ->limitInterval() == "hour" )
							m_cb_limit_interval->setCurrentItem( 2 );
					} else {
						m_cb_limit->setChecked( false );
					}
				}
			} else {
				m_gb_protocol_option->setEnabled( false );
				m_host->delProtocol( it->protocol() );
			}
		}

	} else {
		m_protocol = 0;
		kdDebug() << "ERROR: Casting to KMFCheckListItem failed" << endl;
	}
}

void KMFGenericInterfaceProtocol::slotEnableProtocolLimit( bool onoff ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotEnableProtocolLimit( bool )" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "WARNING: No Current Protocol activated" << endl;
		return;
	}
	if ( onoff ) {
		m_protocol->setLimit( m_sb_limit_rate->value() );
		m_protocol->setLimitInterval( m_cb_limit_interval->currentText() );
	} else {
		m_protocol->setLimit( -1 );
	}
}
void KMFGenericInterfaceProtocol::slotSetProtocolLimitRate( int rate ){
	kdDebug() << "void KMFGenericInterfaceProtocol::slotSetProtocolLimitRate( int )" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "WARNING: No Current Protocol activated" << endl;
		return;
	}
	m_protocol->setLimit( rate );
}

void KMFGenericInterfaceProtocol::slotSetProtocolLimitInterval( const QString& interval ){
	kdDebug() << "void KMFGenericInterfaceProtocol::slotSetProtocolLimitInterval( const QString& )" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "WARNING: No Current Protocol activated" << endl;
		return;
	}
	if ( ! interval.isEmpty() )
		m_protocol->setLimitInterval( interval );
}
void KMFGenericInterfaceProtocol::slotEnableProtocolLogging( bool onoff ){
	kdDebug() << "void KMFGenericInterfaceProtocol::slotEnableProtocolLogging( bool )" << endl;
	if ( ! m_protocol ) {
		kdDebug() << "WARNING: No Current Protocol activated" << endl;
		return;
	}
	m_protocol->setLogging( onoff );
}

void KMFGenericInterfaceProtocol::slotHostLogToggled( bool ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotHostLogToggled( bool )" << endl;
	if ( ! m_host )
		return;
	 kdDebug() << "Changing host: " << m_host->guiName() << endl;		
	if ( m_zoneSelect->currentText() == i18n("Incoming Zone") ) {
		m_host->setLogIncoming( m_cb_host_log->isChecked() );
	} else if (  m_zoneSelect->currentText() == i18n("Outgoing Zone") ) {
		m_host->setLogOutgoing( m_cb_host_log->isChecked() );
	}
}

void KMFGenericInterfaceProtocol::slotHostLimitToggled( bool on ){
	kdDebug() << "void KMFGenericInterfaceProtocol::slotHostLimitToggled( bool " << on << " )" << endl;
	if ( ! m_host )
		return;
	kdDebug() << "Changing host: " << m_host->guiName() << endl;
	if ( on ) {
		m_host->setLimit( m_sb_host_rate->value(),  m_cb_limit_host_interval->currentText() );
	} else {
		m_host->setLimit( -1, m_cb_limit_host_interval->currentText() );
	}
}

void KMFGenericInterfaceProtocol::slotHostLimitValueChanged( int ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotHostLimitValueChanged( int )" << endl;
	if ( ! m_host )
		return;
	kdDebug() << "Changing host: " << m_host->guiName() << endl;	
	if ( m_cb_host_limit->isChecked() ) {
		m_host->setLimit( m_sb_host_rate->value(),  m_cb_limit_host_interval->currentText() );
	} else {
		m_host->setLimit( -1, m_cb_limit_host_interval->currentText() );
	}
}

void KMFGenericInterfaceProtocol::slotHostLimitScaleChanged( int ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotHostLimitValueChanged( int )" << endl;
	if ( ! m_host )
		return;
	kdDebug() << "Changing host: " << m_host->guiName() << endl;	
	if ( m_cb_host_limit->isChecked() ) {
		m_host->setLimit( m_sb_host_rate->value(),  m_cb_limit_host_interval->currentText() );
	} else {
		m_host->setLimit( -1, "" );
	}
}

void KMFGenericInterfaceProtocol::slotAddZone() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotAddZone()" << endl;
	bool ok;
	QString name = KInputDialog::getText(i18n("New Zone"), i18n("Zone Name"),i18n("NewZone"), &ok, this );
	if ( !ok )
		return;
	m_doc->startTransaction();
	
	if ( m_zoneSelect->currentText() == i18n("Incoming Zone") ) {
		QString s = "";
		s = s.setNum( m_doc->incomingZone()->zones().count() );
		KMFNetZone * zone = m_doc->incomingZone()->addZone( "" + m_doc->incomingZone()->name() + "_z_" + s,  new KMFError() );
		if ( zone ) {
			zone->setGuiName( name );
		}
	} else if ( m_zoneSelect->currentText() == i18n("Outgoing Zone") ) {
		QString s = "";
		s = s.setNum( m_doc->outgoingZone()->zones().count() );
		KMFNetZone * zone = m_doc->outgoingZone()->addZone( "" + m_doc->outgoingZone()->name() + "_z_" + s,  new KMFError() );
		if ( zone ) {
			zone->setGuiName( name );
		}
	}
	m_doc->endTransaction();
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::slotDelZone() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotDelZone()" << endl;
	if ( ! m_zone )
		return;
	if ( m_zone->name() != "incoming_world" || m_zone->name() != "outgoing_world" ) {
		m_zone->zone()->delZone( m_zone );
		m_zone = 0;
		slotUpdateView();
	}
}

void KMFGenericInterfaceProtocol::slotAddHost() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotAddHost()" << endl;
	bool ok;
	QString name = KInputDialog::getText( i18n("New Host"), i18n("Host Name"),i18n("New Host"), &ok, this );
	if ( !ok )
		return;
	m_doc->startTransaction();
	if ( m_zone ) {
		QString s = "";
		s = s.setNum( m_zone->hosts().count() );
		KMFNetHost * host = m_zone->addHost( "" + m_zone->name() + "_h_" + s,  * (new QDomDocument() ) );
		if ( host ) {
			host->setGuiName( name );
		}
	}
	m_doc->endTransaction();
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::slotDelHost() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotDelHost()" << endl;
	if ( ! m_zone || ! m_host )
		return;
// 	m_doc->startTransaction();
	m_zone->delHost( m_host );
// 	m_doc->endTransaction();
	m_host = 0;
	slotUpdateView();
}

void KMFGenericInterfaceProtocol::slotTimerShot() {
	if ( m_zone ) {

		if ( m_zone->name() != "incoming_world"  ||
				m_zone->name() != "outgoing_world" )  {
			if ( m_zone->description() != m_zone_desc->text() ) {
				kdDebug() << "Upadationg Zone Description to: "  << m_zone_desc->text() << endl;
				m_zone->setDescription( m_zone_desc->text() );
			}
		}	
	}
	if ( m_host ) {
		if ( m_host->description() != m_host_desc->text() ) {
			kdDebug() << "Upadationg Host Description to: "  << m_host_desc->text() << endl;
			m_host->setDescription( m_host_desc->text() );
		}
	}
}
KMFListViewItem* KMFGenericInterfaceProtocol::findItem( int obj_id ) {
	kdDebug() << "KMFListViewItem* KMFGenericInterfaceProtocol::findItem( int obj_id )" << endl;
	QListViewItem* root = m_lv_zones->firstChild();
	if ( ! root )
		return 0;
	QListViewItem* item = root->firstChild();
	while ( item ) {
// 		item->setText( 0, item->text(0) +"_searched" );
		if ( KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item ) ) {
			kdDebug() << "\nkmfitem->objectID(): " << kmfitem->objectID() <<
				" obj_id: " << obj_id << endl;
			
			if ( kmfitem->objectID() == obj_id ) {
				kdDebug() << "MATCHED" << endl;
				return kmfitem;
			}
		}
		item = item->itemBelow();
	}
	return 0;
}

void KMFGenericInterfaceProtocol::slotAddressChanged( const QString& ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotAddressChanged( const QString& )" << endl;
	if ( ! m_doc || ! m_zone )
		return;
	if ( m_host && m_widgetStack->visibleWidget() == m_hostOptions ) {
		m_host->address()->setAddress( m_sb_host_1->text() +"."+
														m_sb_host_2->text() +"."+
														m_sb_host_3->text() +"."+
														m_sb_host_4->text() );
		if ( m_zoneSelect->currentText() == i18n("Incoming Zone") ) {
			m_doc->incomingZone()->placeHostInZone( m_host );
		} else if ( m_zoneSelect->currentText() == i18n("Outgoing Zone") ) {
			m_doc->outgoingZone()->placeHostInZone( m_host );
		}
		slotUpdateView();
		
		if ( KMFListViewItem *item = findItem( m_host->objectID() ) )
			item->setText( 1, "[" + m_host->address()->toString() + "]" );
	}
}

void KMFGenericInterfaceProtocol::slotZoneChanged( KMFNetZone* z ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotZoneChanged( KMFNetZone* z )" << endl;
	if ( KMFListViewItem *item = findItem( z->objectID() ) ) {
		kdDebug() << "Updating item" << endl;
				item->setText( 1, "[" + z->address()->toString() + i18n("/%1]").arg( z->maskLength() ) );	
	}
}


void KMFGenericInterfaceProtocol::slotRenameZone() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotRenameZone()" << endl;
	if ( ! m_zone )
		return;
	if ( KMFListViewItem* item = findItem( m_zone->objectID() ) ) {
		item->setRenameEnabled( 0 ,true );
		item->startRename(0);
	}
}

void KMFGenericInterfaceProtocol::slotRenameHost() {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotRenameHost()" << endl;
	if ( ! m_host )
		return;
	if ( KMFListViewItem* item = findItem( m_host->objectID() ) ) {
		item->setRenameEnabled( 0 ,true );
		item->startRename(0);
	}
}

void KMFGenericInterfaceProtocol::slotRenameItem( QListViewItem* item, int, const QString& name ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotRenameItem( QListViewItem* item, int, const QString& name )" << endl;
	if ( ! item )
		return;

	if ( name.isEmpty() ) {
		slotUpdateView();
		return;
	}

	if ( KMFListViewItem *kmfitem = dynamic_cast<KMFListViewItem*> (item) ) {
		if ( kmfitem->type() == KMFListViewItem::NETZONE ) {
			kmfitem->zone()->setGuiName( name );
			kdDebug() << "Renaming Zone: " << kmfitem->zone()->name() << endl;
			slotUpdateView();
			return;
		}
	}
	
	if ( KMFListViewItem *kmfitem = dynamic_cast<KMFListViewItem*> (item) ) {
		if ( kmfitem->type() == KMFListViewItem::NETHOST ) {
			kmfitem->host()->setGuiName( name );
			kdDebug() << "Renaming Host: " << kmfitem->host()->name() << endl;
			slotUpdateView();
			return;
		}
	}
	
}
 


 
// void KMFGenericInterfaceProtocol::slotRenameHost( QListViewItem* item, int, const QString& name ) {
// 	kdDebug() << "void KMFGenericInterfaceProtocol::slotRenameHost( QListViewItem* item, int, const QString& name )" << endl;
// 	if ( ! item ) {
// 		kdDebug() << "Item == 0" << endl;
// 		return;
// 	} 
// 
// 	if ( name.isEmpty() ) {
// 		slotUpdateView();
// 		return;
// 	}
// 
// 	if ( KMFListViewItem *kmfitem = dynamic_cast<KMFListViewItem*> (item) ) {
// 		if ( kmfitem->type() == KMFListViewItem::NETHOST ) {
// 			kmfitem->host()->setGuiName( name );
// 			kdDebug() << "Renaming item" << kmfitem->host()->name() << endl;
// 			slotUpdateView();
// 		}
// 	}
// }

// // void KMFGenericInterfaceProtocol::slotZoneDeadEnd( bool onoff ) {
// // 	kdDebug() << "void KMFGenericInterfaceProtocol::slotZoneeadEnd( bool onoff )" << endl;
// // 	if ( ! m_zone )
// // 		return;
// // 	m_zone->setDeadEnd( onoff );
// // }

void KMFGenericInterfaceProtocol::loadIcons() {
	kdDebug() << "void KMFGenericInterfa::loadIcons()" << endl;
	KIconLoader *loader = KGlobal:: iconLoader();
	QString icon_name;

	icon_name = "up";
	icon_up = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "down";
	icon_down = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "editdelete";
	icon_del = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "filenew";
	icon_new = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "edit";
	icon_edit = loader->loadIcon( icon_name, KIcon::Small );


	icon_name = "filter";
	icon_filter = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "text";
	icon_rename = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "rule-22";
	icon_rule = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "view_tree";
	icon_chain = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "reject";
	icon_reject = loader->loadIcon( icon_name, KIcon::User );

	icon_name = "target";
	icon_target = loader->loadIcon( icon_name, KIcon::User );

	icon_name = "stop";
	icon_drop = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "button_ok";
	icon_accept = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "filesaveas";
	icon_log = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "undo";
	icon_return = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "editclear";
	icon_cmd = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "filter";
	icon_filter = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "pipe";
	icon_queue = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "editcopy";
	icon_copy = loader->loadIcon( icon_name, KIcon::Small );

	icon_name = "forward";
	icon_move = loader->loadIcon( icon_name, KIcon::Small );

}


#include "kmfgenericinterfaceprotocol.moc"
