//
// C++ Implementation: 
//
// Description: 
//
//
// Author: Christian Hubinger <chubinger@irrsinnig.org>, (C) 2006
//
// Copyright: See COPYING file that comes with this distribution
//
//


#include "kmfmynetworkwidget.h"

// QT includes
#include <tqstring.h>
#include <tqframe.h>
#include <tqpixmap.h>
#include <tqwidgetstack.h>
#include <tqtextedit.h>
#include <tqlabel.h>
#include <tqlayout.h>

// KDe Includes
#include <ktabwidget.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kglobal.h>
#include <kmessagebox.h>
#include <kdebug.h>
#include <kpopupmenu.h>
#include <kinputdialog.h>

// Project includes
#include "kmfhostwidget.h"
#include "kmfinterfacewidget.h"
#include "kmfsystemsettingslinux.h"
#include "kmfnetworkwidget.h"

#include "../core/kmfnetzone.h"
#include "../core/kmfdoc.h"
#include "../core/kmfnetwork.h"
#include "../core/kmftarget.h"
#include "../core/kmftargetconfig.h"
#include "../core/kmferror.h"
#include "../kmfwidgets/kmflistviewitem.h"

namespace KMF {
KMFMyNetworkWidget::KMFMyNetworkWidget(TQWidget* parent, const char* name, WFlags fl)
: KMyFirewallMyNetworkWidget(parent,name,fl)
{
	kdDebug() << "Contructor: KMFMyNetworkWidget::KMFMyNetworkWidget(TQWidget* parent, const char* name, WFlags fl)" << endl;
	m_network = 0;
	m_contextMenu = new KPopupMenu( this, "m_contextMenu" );

	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( pressed( TQListViewItem* ) ) ,
			 this, TQT_SLOT( slotNewItemSelected( TQListViewItem* ) ) );
	
	connect( m_lv_zones, TQT_SIGNAL( itemRenamed ( TQListViewItem *, int, const TQString & ) ) ,
			 this, TQT_SLOT( slotRenameItem( TQListViewItem *, int, const TQString & ) ) );

	
	
	loadIcons();
	setupPropertiesView();
}

void KMFMyNetworkWidget::saveConfig() {
	kdDebug() << "KMFMyNetworkWidget::saveConfig()" << endl;
	m_network->exportXMLRuleset( false, false );
	// m_network->saveConfig();
}

void KMFMyNetworkWidget::setNetwork( KMFNetwork* net ) {
// 	if ( ! m_network ) {
// 		m_network = net;
// 		
// 	} else {
		m_network = net;
		m_lv_zones->clear();
		KMFListViewItem *it = new KMFListViewItem( m_lv_zones, 0, m_network->netzone() );
		it->setupZoneView();
// 	}
// 	m_lv_zones->clear();
// 	KMFListViewItem *it = new KMFListViewItem( m_lv_zones, 0, m_network->netzone() );
// 	it->setupZoneView();
}

void KMFMyNetworkWidget::setupPropertiesView() {
	kdDebug() << "void KMFMyNetworkWidget::setupPropertiesView()" << endl;
	m_hostProperties = new KMFHostWidget( this, "host widget" );
	kt_hostProperties->addTab( m_hostProperties, i18n( "General" ) );
	connect( m_hostProperties, TQT_SIGNAL( sigTargetChanged() ),
			 this, TQT_SLOT( slotTargetChanged() ) );
			 
	m_hostProperties->InitGUI();
	
	m_hostInterfaces = new KMFInterfaceWidget(  this, "interface widget" );
	kt_hostProperties->addTab( m_hostInterfaces, i18n( "Interfaces" ) );
	
	m_hostSettingsLinux = new KMFSystemSettingsLinux(  this, "system settings widget" );
	kt_hostProperties->addTab( m_hostSettingsLinux, i18n( "System Settings" ) );

	
//	TQWidget *zonePropsWidget = new TQWidget( this, "ads" );
	
	
// 	TQLabel *desc = new TQLabel( i18n("<qt>Define your network zone here by defining the Networks IP and netmask.</qt>") , zonePropsWidget, "ad" );
// 	
// 	TQLabel *desc2 = new TQLabel( i18n("Zone Documentation:") , zonePropsWidget, "ad" );
// 	
// 	m_zone_desc = new TQTextEdit( zonePropsWidget, "adf" );
// 	m_zone_desc->setReadOnly( false );
// 	TQGridLayout *grid = new TQGridLayout( zonePropsWidget, 3,2);

	m_network_widget = new KMFNetworkWidget( this, "m_network_widget" );
	
	connect( m_network_widget,TQT_SIGNAL( sigZoneChanged( KMFNetZone* ) ),
		this,TQT_SLOT( slotZoneChanged( KMFNetZone* ) ) );

// 	grid->addWidget( m_network_widget, 0,0 );
// 	grid->addWidget( m_network_widget, 1,0 );
// 	grid->addWidget( desc2,0,1 );
// 	grid->addMultiCellWidget( m_zone_desc, 1,2,1,1);

	kt_zoneProperties->addTab( m_network_widget, i18n( "General" ) );

	
}

KMFMyNetworkWidget::~KMFMyNetworkWidget() {
}


void KMFMyNetworkWidget::slotNewItemSelected( TQListViewItem* item ) {
	kdDebug() << "void KMFMyNetworkWidget::slotNewItemSelected( TQListViewItem* item )" << endl;
	if ( ! item )
		return ;
	m_zone = 0;
	m_target = 0;
	
	m_lv_zones->blockSignals( true );
	m_lv_zones->clearSelection();
	m_lv_zones->setSelected( item, true );
	m_lv_zones->blockSignals( false );
	
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	
	if ( ! kmfitem ) {
		kdDebug() << "No Item Selected!" << endl;	
		return;
	}
	
	m_hostProperties->setEnabled( false );
	if ( kmfitem != 0 && kmfitem->netfilterObject()->type() == NetfilterObject::NETZONE ) {
		kdDebug() << "Selected NETZONE" << endl;
 		m_wsEdit->raiseWidget( ws_pageZoneProperties );
		// kt_hostProperties->showPage( m_hostProperties );
		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_network_widget->loadZone( m_zone );
			if (  m_zone->readOnly() ) {
				m_network_widget->allowEdit( false );
			} else {
				m_network_widget->allowEdit( true );
			}

		}
	} else if ( kmfitem != 0 && kmfitem->netfilterObject()->type() == NetfilterObject::KMFTARGET ) {
		kdDebug() << "Selected KMFTARGET" << endl;
		m_wsEdit->raiseWidget( ws_pageHostProperties );
		// kt_hostProperties->showPage( m_hostProperties );
		m_target = kmfitem->target();
		if ( m_target ) {
// 			kdDebug() << "kmfitem->target() pointer is valid" << endl;
			m_zone = m_target->zone();
			m_hostProperties->loadHost( m_target );
			m_hostProperties->setEnabled( true );
			
			m_hostInterfaces->loadTarget( m_target );
			
			if ( m_target->config()->oS() == "linux" ) {
				kt_hostProperties->setTabEnabled( m_hostSettingsLinux, true );
				m_hostSettingsLinux->loadTarget( m_target );
			} else {
				kt_hostProperties->setTabEnabled( m_hostSettingsLinux, false );
			}
			
			kmfitem->setupTargetView();
		}
	} else if ( kmfitem != 0 && kmfitem->netfilterObject()->type() == NetfilterObject::NETHOST ) {
		kdDebug() << "Selected NETHOST" << endl;
	}
	kdDebug() << "Laving slotNewItemSelected()" << endl;
}

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

	
	m_lv_zones->clear();
	KMFListViewItem *it = new KMFListViewItem( m_lv_zones, 0, m_network->netzone() );
	it->setupZoneView();

	if ( KMFListViewItem *item = findItem( m_zone->uuid() ) ) {
		slotNewItemSelected( item );
	}
}



void KMFMyNetworkWidget::slotZoneRBM( TQListViewItem* item, const TQPoint& point, int ) {
	if ( ! item )
		return ;
	KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item );
	if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::NETZONE ) {
		kdDebug() << "Setting up Zone RBM:" << endl;
		m_target = 0;
		m_zone = 0;
		m_zone = kmfitem->zone();
		if ( m_zone ) {
			m_contextMenu->clear();
			TQString name = m_zone->name();
			TQString 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, TQT_SLOT( slotAddHost() ) );

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

			m_contextMenu->popup( point );
		}
	} else if ( kmfitem != 0  && kmfitem->type() == NetfilterObject::KMFTARGET ) {
		kdDebug() << "Setting up Host RBM:" << endl;
		m_target = 0;
		m_target = kmfitem->target();
		if ( m_target ) {
			m_contextMenu->clear();
			TQString name = m_target->name();
			TQString lab_str = i18n("Host: %1").arg( m_target->guiName() );
			m_contextMenu->insertTitle( icon_chain, lab_str );
			if ( ! m_target->readOnly() ) {
				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() ) );
			}
			if ( ! m_target->isCurrentTarget() ) {
				m_contextMenu->insertSeparator();
				m_contextMenu->insertItem( KGlobal::iconLoader()->loadIcon( "kmyfirewall", KIcon::Small ), i18n( "Make Active Target..." ), this, TQT_SLOT( slotSetActiveTarget() ) );
			}
			
			m_contextMenu->popup( point );
		}
	}
}

void KMFMyNetworkWidget::slotSetActiveTarget() {
	if( ! m_target ) {
		return;
	}
	m_network->setCurrentTarget( m_target );
	slotUpdateView();
	emit sigActiveTargetChanged();
}

void KMFMyNetworkWidget::slotAddHost() {
	kdDebug() << "void KMFMyNetworkWidget::slotAddHost()" << endl;
	bool ok;
	TQString name = KInputDialog::getText( i18n("New Host"), i18n("Host Name"),i18n("New Host"), &ok, this );
	if ( !ok )
		return;
	
	if ( m_zone ) {
		KMFUndoEngine::instance()->startTransaction( 
			m_network->netzone(),
			i18n("Add Target: %1 to Zone: %2").arg( name ).arg( m_zone->guiName() ) 
		);
		TQString s = "";
		s = s.setNum( m_zone->hosts().count() );
		KMFTarget * host = m_zone->addTarget( "" + m_zone->name() + "_h_" + s,  * (new TQDomDocument() ) );
		if ( host ) {
			host->setGuiName( name );
			m_target = host;
			m_network->netzone()->refreshNetworkTree();
			// m_network->netzone()->changed();
			KMFUndoEngine::instance()->endTransaction();
		} else {
			KMFUndoEngine::instance()->abortTransaction();
		}
		
	}
	slotUpdateView();
}

void KMFMyNetworkWidget::slotDelHost() {
	kdDebug() << "void KMFMyNetworkWidget::slotDelHost()" << endl;
	if ( ! m_zone || ! m_target )
		return;
 	KMFUndoEngine::instance()->startTransaction( 
 		m_zone,
 		i18n("Delete Target: %1 from Zone: %2").arg( m_target->guiName() ).arg( m_zone->guiName() ) 
 	);
	m_zone->delHost( m_target );
    KMFUndoEngine::instance()->endTransaction();
	m_target = 0;
	slotUpdateView();
}


void KMFMyNetworkWidget::slotAddZone() {
	kdDebug() << "void KMFMyNetworkWidget::slotAddZone()" << endl;
	bool ok;
	TQString name = KInputDialog::getText(i18n("New Zone"), i18n("Zone Name"),i18n("NewZone"), &ok, this );
	if ( !ok )
		return;
	
	TQString s = "";
	s = s.setNum( m_network->netzone()->zones().count() );
	
	KMFUndoEngine::instance()->startTransaction( 
		m_network->netzone(),
		i18n("Add Zone: %1 to Zone: %2").arg( name ).arg( m_network->netzone()->guiName() ) 
	);
	
	KMFNetZone * zone = m_network->netzone()->addZone( "",  new KMFError() );
	if ( zone ) {
		zone->setGuiName( name );
		
		m_zone = zone;
		m_target = 0;
		m_network->netzone()->refreshNetworkTree();
		slotUpdateView();
		KMFUndoEngine::instance()->endTransaction();
	} else {
		KMFUndoEngine::instance()->abortTransaction();
	}
}

void KMFMyNetworkWidget::slotDelZone() {
	kdDebug() << "void KMFMyNetworkWidget::slotDelZone()" << endl;
	if ( ! m_zone )
		return;
	if ( m_zone->name() != i18n("world")  ) {
		KMFUndoEngine::instance()->startTransaction( 
			m_zone->zone(),
			i18n("Delete Zone: %1 from Zone: %2").arg( m_zone->guiName() ).arg( m_zone->zone()->guiName() ) 
		);
		m_zone->zone()->delZone( m_zone );
		m_zone = 0;
		slotUpdateView();
		KMFUndoEngine::instance()->endTransaction();
	}
}

void KMFMyNetworkWidget::slotRenameItem( TQListViewItem* item, int, const TQString& name ) {
	kdDebug() << "void KMFMyNetworkWidget::slotRenameItem( TQListViewItem* item, int, const TQString& name )" << endl;
	if ( ! item )
		return;

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

	if ( KMFListViewItem *kmfitem = dynamic_cast<KMFListViewItem*> (item) ) {
		if ( kmfitem->type() == NetfilterObject::NETZONE ) {
			KMFUndoEngine::instance()->startTransaction( 
				kmfitem->zone(),
				i18n("Rename Zone: %1 to %3").arg( m_zone->guiName() ).arg( name ) 
			);
			
			kmfitem->zone()->setGuiName( name );
			kdDebug() << "Renaming Zone: " << kmfitem->zone()->name() << endl;
			slotUpdateView();
			KMFUndoEngine::instance()->endTransaction();
			return;
		}
		if ( kmfitem->type() == NetfilterObject::KMFTARGET ) {
			KMFUndoEngine::instance()->startTransaction( 
				kmfitem->target(),
				i18n("Rename Host: %1 to %3").arg( m_zone->guiName() ).arg( name ) 
			);
			kmfitem->target()->setGuiName( name );
			kdDebug() << "Renaming Host: " << kmfitem->target()->name() << endl;
			slotUpdateView();
			KMFUndoEngine::instance()->endTransaction();
			return;
		}
	}
}

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

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

void KMFMyNetworkWidget::slotUpdateView( NetfilterObject* ) {
	kdDebug() << "void KMFMyNetworkWidget::slotUpdateView()" << endl;
	if ( ! m_network ) {
		kdDebug() << "WARNING: m_network == 0" << endl;
		return;
	}
	slotUpdateView();
}

void KMFMyNetworkWidget::slotUpdateView() {
	kdDebug() << "void KMFMyNetworkWidget::slotUpdateView()" << endl;
	if ( ! m_network ) {
		kdDebug() << "WARNING: m_network == 0" << endl;
		return;
	}
	
	
	m_lv_zones->clear();
	KMFListViewItem *it = new KMFListViewItem( m_lv_zones, 0, m_network->netzone() );
	it->setupZoneView();
	
	m_lv_zones->setEnabled( true );
	if ( m_target ) {
		if ( KMFListViewItem *item = findItem( m_target->uuid() ) ) {
			m_lv_zones->setSelected( item, true );
			slotNewItemSelected( item );
		}
		
		
	} else if ( m_zone ) {
		if ( KMFListViewItem *item = findItem( m_zone->uuid() ) ) {
			
			m_lv_zones->setSelected( item, true );
			slotNewItemSelected( item );
		}
	}
	m_lv_zones->setSorting( 0 , false );
}

void KMFMyNetworkWidget::slotTargetChanged() {
	kdDebug() << "KMFMyNetworkWidget::slotTargetChanged()" << endl;
	if ( ! m_target ) {
		kdDebug() << "m_target == 0" << endl;
		return;
	}
	// m_network->netzone()->placeHostInZone( m_target );
	
	m_network->netzone()->refreshNetworkTree();
	
	m_lv_zones->clear();
	KMFListViewItem *it = new KMFListViewItem( m_lv_zones, 0, m_network->netzone() );
	it->setupZoneView();

	if ( KMFListViewItem *item = findItem( m_target->uuid() ) ) {
		slotNewItemSelected( item );
	}
	emit sigActiveTargetChanged();
}

KMFListViewItem* KMFMyNetworkWidget::findItem( const TQUuid& obj_id ) {
	// kdDebug() << "KMFListViewItem* KMFMyNetworkWidget::findItem( int obj_id )" << endl;
	TQListViewItem* root = m_lv_zones->firstChild();
	if ( ! root )
		return 0;
	TQListViewItem* item = root->firstChild();
	while ( item ) {
		if ( KMFListViewItem* kmfitem = dynamic_cast<KMFListViewItem*> ( item ) ) {
			// kdDebug() << "\nkmfitem->uuid(): " << kmfitem->uuid() <<
			//		" obj_id: " << obj_id << endl;
			
			if ( kmfitem->uuid() == obj_id ) {
			//	kdDebug() << "MATCHED" << endl;
				return kmfitem;
			}
		}
		item = item->itemBelow();
	}
	return 0;
}



/*$SPECIALIZATION$*/
void KMFMyNetworkWidget::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::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 "kmfmynetworkwidget.moc"

