//
//
// C++ Implementation: $MODULE$
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@irrsinnig.org>, (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 "kmfgenericinterfacehost.h"

// QT includes
#include <tqstring.h>
#include <tqcheckbox.h>
#include <tqtextedit.h>
#include <tqlabel.h>
#include <tqtimer.h>

// KDE includes
#include <klocale.h>
#include <kdebug.h>
#include <klistview.h>
#include <kpopupmenu.h>
#include <kpushbutton.h>
#include <kiconloader.h>
#include <knuminput.h>
#include <kmessagebox.h>
#include <kstdguiitem.h>

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

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

namespace KMF {
KMFGenericInterfaceHost::KMFGenericInterfaceHost( TQWidget *parent, const char *name, WFlags f )
		: KMyFirewallGenericInterfaceHostWidget( parent, name, f ) {
	m_lv_zones->setFullWidth( true );
	m_contextMenu = new KPopupMenu( this, "Popup" );
	m_contextMenu->hide();
	loadIcons();
	connect( m_lv_zones, TQT_SIGNAL( pressed( TQListViewItem* ) ) ,
	         this, TQT_SLOT( slotNewItemSelected( TQListViewItem* ) ) );
	connect( m_lv_zones, TQT_SIGNAL( contextMenuRequested ( TQListViewItem*, const TQPoint&, int ) ),
	         this, TQT_SLOT( slotZoneRBM( TQListViewItem*, const TQPoint&, int ) ) );
	connect( m_lv_zones, TQT_SIGNAL( itemRenamed ( TQListViewItem *, int, const TQString & ) ) ,
	         this, TQT_SLOT( slotHostRenamed( TQListViewItem*, int , const TQString  & ) ) );

	connect( m_sb_host_1, TQT_SIGNAL( valueChanged( const TQString& ) ),
		this, TQT_SLOT( slotAddressChanged( const TQString& ) ) );
	connect( m_sb_host_2, TQT_SIGNAL( valueChanged( const TQString& ) ),
		this, TQT_SLOT( slotAddressChanged( const TQString& ) ) );
	connect( m_sb_host_3, TQT_SIGNAL( valueChanged( const TQString& ) ),
		this, TQT_SLOT( slotAddressChanged( const TQString& ) ) );
	connect( m_sb_host_4, TQT_SIGNAL( valueChanged( const TQString& ) ),
		this, TQT_SLOT( slotAddressChanged( const TQString& ) ) );

	connect( m_host_desc, TQT_SIGNAL( textChanged() ),
		this, TQT_SLOT( slotHostDescChanged() ) );
	
	connect( c_log_in, TQT_SIGNAL( toggled( bool ) ),
		this, TQT_SLOT( slotLoggingChanged( bool ) ) );
	connect( c_log_out, TQT_SIGNAL( toggled( bool ) ),
		this, TQT_SLOT( slotLoggingChanged( bool ) ) );
	
	b_newHost->setIconSet( icon_new );
	b_delHost->setIconSet( icon_del );

	connect( b_newHost, TQT_SIGNAL( clicked() ),
		this, TQT_SLOT( slotNewHost() ) );

	connect( b_delHost, TQT_SIGNAL( clicked() ),
		this, TQT_SLOT( slotDelHost() ) );
}


KMFGenericInterfaceHost::~KMFGenericInterfaceHost() {}

// void KMFGenericInterfaceHost::slotDisable() {
// }

void KMFGenericInterfaceHost::slotUpdateView( NetfilterObject* ) {
	kdDebug() << "KMFGenericInterfaceHost::slotUpdateView( NetfilterObject* )" << endl;
	if ( ! m_doc ) {
		kdDebug() << "WRINING: m_doc == 0" << endl;
		return;
	}
	slotUpdateView();
}

void KMFGenericInterfaceHost::slotUpdateView() {
	kdDebug() << "KMFGenericInterfaceHost::slotUpdateView()" << endl;
	if ( ! m_doc ) {
		kdDebug() << "WRINING: m_doc == 0" << endl;
		return;
	}
	
	m_lv_zones->clear();
	itemTrustedHosts = new KMFListViewItem( m_lv_zones, 0, m_doc->currentDocAsGenericDoc()-> trustedHostsZone() );
	itemMaliciousHosts = new KMFListViewItem( m_lv_zones, 0, m_doc->currentDocAsGenericDoc()->maliciousHostsZone() );
	itemBadServers = new KMFListViewItem( m_lv_zones, 0, m_doc->currentDocAsGenericDoc()->badServersHostsZone() );
	itemBadClients = new KMFListViewItem( m_lv_zones, 0, m_doc->currentDocAsGenericDoc()->badClientsHostsZone() );

	itemTrustedHosts->deleteChildren();
	itemTrustedHosts->setupZoneView();

	itemMaliciousHosts->deleteChildren();
	itemMaliciousHosts->setupZoneView();

	itemBadServers->deleteChildren();
	itemBadServers->setupZoneView();

	itemBadClients->deleteChildren();
	itemBadClients->setupZoneView();

	KMFListViewItem* it = 0;
	if ( m_host ) {
		it = findKMFItem( m_host->uuid() );
	} else if ( m_zone ) {
		it = findKMFItem( m_zone->uuid() );
	}
	if ( it ) {
		m_lv_zones->setSelected( it, true );
		slotNewItemSelected( it );
	}
}

/*!
    \fn KMFGenericInterfaceHost::loadDoc( KMFGenericDoc* )
 */
void KMFGenericInterfaceHost::loadDoc( KMFNetwork* doc ) {
	kdDebug() << "void KMFGenericInterfaceHost::loadDoc( KMFGenericDoc* )" << endl;
	m_doc = doc;
	slotUpdateView();
}

/*!
    \fn KMFGenericInterfaceHost::slotAddHost()
 */
void KMFGenericInterfaceHost::slotNewHost() {
	kdDebug() << "void KMFGenericInterfaceHost::slotNewHost()" << endl;
	if ( m_zone ) {
		
		KMFUndoEngine::instance()->startTransaction(
			m_zone,
			i18n( "Add new host to zone: %1." ).arg( m_zone->guiName() )
		);
		KMFNetHost * host = m_zone->addNetHost( i18n("New Host"),  *(new TQDomDocument() ) );
		if ( host ) {
			host->setGuiName( i18n("New Host") );
			KMFListViewItem* it = findKMFItem( i18n("New Host"), host->uuid() );
			if ( it ) {
				it->setRenameEnabled( 0, true );
				it->startRename( 0 );
			}
			m_host = host;
			m_zone = host->zone();
			KMFUndoEngine::instance()->endTransaction();
			slotUpdateView();
		} else {
			KMFUndoEngine::instance()->abortTransaction();
		}	
	}
}

/*!
    \fn KMFGenericInterfaceHost::slotDelHost()
 */
void KMFGenericInterfaceHost::slotDelHost() {
	kdDebug() << "void KMFGenericInterfaceHost::slotDelHost()" << endl;
	if ( ! m_host || ! m_zone )
		return;
	if ( KMessageBox::questionYesNo(this, i18n("<qt>Are you sure that you want to delete host "
														"<b>%1</b> from <b>%2</b>?</qt>").arg(m_host->guiName() ).arg( m_zone->guiName() ),
														 i18n("Are you sure?"), KStdGuiItem::yes(), KStdGuiItem::cancel(),
														 "genericgui_hostpage_hostdelete") == KMessageBox::Yes ) {
		KMFUndoEngine::instance()->startTransaction(
			m_zone,
			i18n( "Delete host: %1 from zone: %2." ).arg( m_host->guiName() ).arg( m_zone->guiName() )
		);
		m_zone->delHost( m_host );
		m_host = 0;
		KMFUndoEngine::instance()->endTransaction();
		slotUpdateView();
	}
}

/*!
    \fn KMFGenericInterfaceHost::slotNewItemSelected( TQListViewItem* )
 */
void KMFGenericInterfaceHost::slotNewItemSelected( TQListViewItem* item ){
	kdDebug() << "void KMFGenericInterfaceHost::slotNewItemSelected( TQListViewItem* )" << endl;
	if ( ! item )
		return ;
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::NETZONE ) {
		m_host = 0;
		m_zone = kmfitem->zone();
		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 );
		c_log_in->setEnabled(false);
		c_log_out->setEnabled(false);
		c_log_in->setChecked( false );
		c_log_out->setChecked( false );
		m_host_desc->clear();
	} else if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::NETHOST ) {
		m_host = kmfitem->host();
		m_zone = kmfitem->host()->zone();
		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_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_host_desc->setText( m_host->description() );
		m_host_desc->setReadOnly( false );
		c_log_in->setEnabled(true);
		c_log_out->setEnabled(true);
		c_log_in->setChecked( m_host->logIncoming() );
		c_log_out->setChecked( m_host->logOutgoing() );
		l_currHost->setText( i18n( "Host: %1").arg( m_host->guiName() ) );

	} else {
		kdDebug() << "KMFGenericInterfaceHost::slotNewItemSelected( TQListViewItem* item ): WARNING unknown ListView Type!!!" << endl;
	}

}

/*!
    \fn KMFGenericInterfaceHost::slotRenameHost()
 */
void KMFGenericInterfaceHost::slotRenameHost() {
	kdDebug() << "void KMFGenericInterfaceHost::slotRenameHost()" << endl;
	if ( m_host ) {
		KMFListViewItem* it = findKMFItem(  m_host->guiName(), m_host->uuid() );
		if ( it ) {
			it->setRenameEnabled( 0, true );
			it->startRename( 0 );
		}
	}
}

void KMFGenericInterfaceHost::slotHostRenamed( TQListViewItem* item, int , const TQString& text ) {
	kdDebug() << "void KMFGenericInterfaceHost::slotHostRenamed( TQListViewItem* item, int , const TQString& text )" << endl;
	
	if ( ! item || text.isNull() )
		return ;
		
	TQString newName = text.simplifyWhiteSpace();	
	
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::NETHOST ) {
		m_host = kmfitem->host();
		m_zone = kmfitem->host()->zone();
		if ( newName == m_host->guiName() ) {
			return;
		}
		KMFUndoEngine::instance()->startTransaction(
			m_host,
			i18n( "Rename host: %1 to %2." ).arg( m_host->guiName() ).arg( newName )
		);
		m_host->setGuiName( newName );
		KMFUndoEngine::instance()->endTransaction();
		kdDebug() << "Setting GuiName: " << m_host->guiName() << "\ninternal Name: " << m_host->name() << endl;
		slotUpdateView();
	}

}
void KMFGenericInterfaceHost::slotAddressChanged( const TQString& ) {
	kdDebug() << "void KMFGenericInterfaceProtocol::slotAddressChanged( const TQString& )" << endl;
	if ( ! m_host )
		return;

	TQString address  = "[" + m_sb_host_1->text() + "." +
									 m_sb_host_2->text() + "." +
									 m_sb_host_3->text() + "." +
									  m_sb_host_4->text()  + "]";
	
	if ( address == m_host->address()->toString() ) {
		return;
	}
	KMFUndoEngine::instance()->startTransaction(
		m_host,
		i18n( "Change address of host: %1." ).arg( m_host->guiName() )
	);
	m_host->address()->setAddress( m_sb_host_1->text() +"."+
													m_sb_host_2->text()+"."+
													m_sb_host_3->text()+"."+
													m_sb_host_4->text() );
	KMFUndoEngine::instance()->endTransaction();
	
	KMFListViewItem *it = findKMFItem( m_host->guiName(), m_host->uuid() );
	if ( it ) {
		it->setText( 1 , "[" + address +"]" );
	}
}

void KMFGenericInterfaceHost::slotHostDescChanged() {
	kdDebug() << "void KMFGenericInterfaceHost::slotHostDescChanged()" << endl;
	if ( ! m_host ) {
		return;
	}
	if ( m_host_desc->text().simplifyWhiteSpace() == m_host->description() ) {
		return;
	}
	KMFUndoEngine::instance()->startTransaction(
		m_host,
		i18n( "Edit documentation of host: %1" ).arg( m_host->guiName() )
	);
		m_host->setDescription( m_host_desc->text().simplifyWhiteSpace() );
	KMFUndoEngine::instance()->endTransaction();
	
}

void KMFGenericInterfaceHost::slotLoggingChanged( bool ) {
	kdDebug() << "void KMFGenericInterfaceHost::slotLoggingChanged( bool )" << endl;
	if ( ! m_host ) {
		return;
	}
	if ( c_log_in->isChecked() != m_host->logIncoming() ) {
		KMFUndoEngine::instance()->startTransaction(
			m_host,
			i18n( "Edit logging option of host: %1" ).arg( m_host->guiName() )
		);
		m_host->setLogIncoming( c_log_in->isChecked() );
		KMFUndoEngine::instance()->endTransaction();
	}
	if ( m_host->logOutgoing()  != c_log_out->isChecked() ) {
		KMFUndoEngine::instance()->startTransaction(
			m_host,
			i18n( "Edit logging option of host: %1" ).arg( m_host->guiName() )
		);
		m_host->setLogOutgoing( c_log_out->isChecked() );
		KMFUndoEngine::instance()->endTransaction();
	}
	
}

/*!
    \fn KMFGenericInterfaceHost::slotRBM( TQListViewItem*, const TQPoint&, int )
 */
void KMFGenericInterfaceHost::slotZoneRBM( TQListViewItem* item, const TQPoint& point, int ){
	kdDebug() << "void KMFGenericInterfaceHost::slotRBM( TQListViewItem*, const TQPoint&, int )" << endl;
	if ( ! item )
		return ;
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::NETZONE ) {
		kdDebug() << "Setting up Zone RBM:" << endl;
		m_host = 0;
		m_zone = 0;
		m_zone = kmfitem->zone();
		if ( m_zone ) {
			m_contextMenu->clear();
			TQString name = m_zone->name();
			TQString lab_str = i18n("Special Host Type: %1").arg( m_zone->guiName() );
			m_contextMenu->insertTitle( icon_chain, lab_str );
			m_contextMenu->insertItem( icon_new, i18n( "New Host..." ), this, TQT_SLOT( slotNewHost() ) );
			m_contextMenu->popup( point );
		}
	} else if (  kmfitem != 0  && kmfitem->type() == NetfilterObject::NETHOST ) {
		m_host = 0;
		m_zone = 0;
		m_host = kmfitem->host();
		m_zone = kmfitem->host()->zone();
		if ( m_host ) {
			m_contextMenu->clear();
			TQString name = m_zone->name();
			TQString lab_str = i18n("Special Host: %1").arg( m_host->guiName() );
			m_contextMenu->insertTitle( icon_chain, lab_str );
			m_contextMenu->insertItem( icon_new, i18n( "New Host..." ), this, TQT_SLOT( slotNewHost() ) );
			m_contextMenu->insertItem( icon_rename, i18n( "Rename Host..." ), this, TQT_SLOT( slotRenameHost() ) );
			m_contextMenu->insertSeparator();
			m_contextMenu->insertItem( icon_del, i18n( "Delete Host" ), this, TQT_SLOT( slotDelHost() ) );

			m_contextMenu->popup( point );

		}
	}
}

KMFListViewItem* KMFGenericInterfaceHost::findKMFItem( const TQString& text, const TQUuid& obj_id ) {
	if ( obj_id.isNull() )
		return 0;
	TQListViewItemIterator it( m_lv_zones );
	while ( it.current() ) {
		TQListViewItem * qitem = it.current();
		++it;
		KMFListViewItem * item = 0;
		item = dynamic_cast<KMFListViewItem*> ( qitem );
		if ( item ) {
			if ( item->text( 0 ) == text && item->uuid() == obj_id )
			return item;
		} else {
			kdDebug() << "CAST ERROR: Item not of type KMFListViewItem" << endl;
		}
	}
// 	kdDebug() << "Couldn't find Item " << text << "  column: " << column << ", int obj_id: " << obj_id << endl;
	return 0;
}
KMFListViewItem* KMFGenericInterfaceHost::findKMFItem( const TQUuid& obj_id ) {
	if ( obj_id.isNull() )
		return 0;
	TQListViewItemIterator it( m_lv_zones );
	while ( it.current() ) {
		TQListViewItem * qitem = it.current();
		++it;
		KMFListViewItem * item = 0;
		item = dynamic_cast<KMFListViewItem*> ( qitem );
		if ( item ) {
			if ( item->uuid() == obj_id )
			return item;
		} else {
			kdDebug() << "CAST ERROR: Item not of type KMFListViewItem" << endl;
		}
	}
// 	kdDebug() << "Couldn't find Item " << text << "  column: " << column << ", int obj_id: " << obj_id << endl;
	return 0;
}

void KMFGenericInterfaceHost::loadIcons() {
	kdDebug() << "void KMFGenericInterfa::loadIcons()" << endl;
	KIconLoader *loader = KGlobal:: iconLoader();
	TQString 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::User );

	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 "kmfgenericinterfacehost.moc"
