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


#include "kmfhostwidget.h"

// TQt includes
#include <tqtextedit.h>
#include <tqpushbutton.h>
#include <tqcolor.h>
#include <tqlabel.h>

// KDE includes
#include <kled.h>
#include <kcombobox.h>
#include <knuminput.h>
#include <kdebug.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <tdeio/netaccess.h>
#include <tdeapplication.h>
#include <ktrader.h>
#include <tdeparts/part.h>
#include <tdeparts/plugin.h>
#include <tdeparts/factory.h>


// Project includes
#include "../core/kmferror.h"
#include "../core/kmferrorhandler.h"
#include "../core/xmlnames.h"
#include "../core/kmftarget.h"
#include "../core/kmftargetconfig.h"
#include "../core/kmfundoengine.h"
#include "../core/kmfcompilerinterface.h"
#include "../core/kmfinstallerinterface.h"
namespace KMF {
KMFHostWidget::KMFHostWidget(TQWidget* parent, const char* name, WFlags fl )
	: KMyFirewallHostWidget(parent, name, fl )
{
	kdDebug() << "KMFHostWidget::KMFHostWidget(TQWidget* parent, const char* name, WFlags fl)" << endl;
	connect( m_sb_host_0, TQ_SIGNAL( valueChanged ( int ) ), 
			 this, TQ_SLOT( slotAddressChanged( int ) ) );
	connect( m_sb_host_1, TQ_SIGNAL( valueChanged ( int ) ), 
			 this, TQ_SLOT( slotAddressChanged( int ) ) );
	connect( m_sb_host_2, TQ_SIGNAL( valueChanged ( int ) ), 
			 this, TQ_SLOT( slotAddressChanged( int ) ) );
	connect( m_sb_host_3, TQ_SIGNAL( valueChanged ( int ) ), 
			 this, TQ_SLOT( slotAddressChanged( int ) ) );
	
	connect( m_sb_host_sshPort, TQ_SIGNAL( valueChanged ( int ) ), 
			 this, TQ_SLOT( slotSSHPortChanged( int ) ) );
	
	
	connect( m_cb_backend, TQ_SIGNAL( activated( const TQString& ) ),
			 this, TQ_SLOT( slotBackaendChanged( const TQString& ) ) );
	connect( m_cb_os, TQ_SIGNAL( activated( const TQString& ) ),
			 this, TQ_SLOT( slotOSChanged( const TQString& ) ) );
	
	connect( m_host_desc, TQ_SIGNAL( textChanged() ),
			 this, TQ_SLOT( slotDescriptionChanged() ) );
	
	connect( m_cmd_testSSH, TQ_SIGNAL( clicked() ),
			 this, TQ_SLOT( slotTestConnection() ) );
	connect( m_cmd_autoConf, TQ_SIGNAL( clicked() ),
			 this, TQ_SLOT( slotTryAutoConfiguration() ) );
}

KMFHostWidget::~KMFHostWidget()
{
	
	
}

void KMFHostWidget::InitGUI() {
	kdDebug() << "KMFHostWidget::InitGUI()" << endl;
	m_cb_backend->blockSignals( true );
	m_cb_os->blockSignals( true );
	m_cb_backend->clear();
	m_cb_os->clear();
	
	
	// kdDebug() << "Start query" << endl;
	TDETrader::OfferList offers = TDETrader::self()->query( "KMyFirewall/Compiler");
	// kdDebug() << "Query performed for KMyFirewall/Installer" << endl;
	TDETrader::OfferList::iterator it;
	if ( offers.empty() ) {
		kdDebug() << "ERROR: NO MATCHING PLUGIN FOUND" << endl;
	}
	for ( it = offers.begin(); it != offers.end(); ++it ) {
		KService::Ptr ptr = *it;
		KLibFactory *factory = KLibLoader::self()->factory( ptr->library().local8Bit().data() );
		kdDebug() << KLibLoader::self()->lastErrorMessage() << endl;
		if ( !factory ) {
			KMessageBox::error( 0, i18n("<qt><b>Compiler plugin could not be loaded.</b></qt>") );
			kdDebug() << "Couldn't load plugin: "  <<  ptr->name() << endl;
		}
		
		if ( KMFCompilerInterface *compiler = dynamic_cast<KMFCompilerInterface*> ( factory->create( this , "KMFCompilerInterface") ) ) {
			m_cb_os->insertItem( compiler->osGUIName() );
		}
	}
	slotOSChanged( m_cb_os->currentText() );
	m_cb_backend->blockSignals( false );
	m_cb_os->blockSignals( false );
}

/*$SPECIALIZATION$*/
void KMFHostWidget::loadHost( KMFTarget *target ) {
	kdDebug() << "KMFHostWidget::loadHost( KMFTarget * " + target->guiName() + " )" << endl;
	m_target = target;
	
	
	updateView();
}


void KMFHostWidget::updateView() {
	kdDebug() << "KMFHostWidget::updateView()" << endl;
	m_sb_host_0->blockSignals( true );
	m_sb_host_1->blockSignals( true );
	m_sb_host_2->blockSignals( true );
	m_sb_host_3->blockSignals( true );
	m_sb_host_sshPort->blockSignals( true );
	m_cb_backend->blockSignals( true );
	m_cb_os->blockSignals( true );
	m_host_desc->blockSignals( true );
	m_cmd_testSSH->blockSignals( true );
	m_led_configStatus->off();
	if ( m_target ) {
		m_led_configStatus->on();
		if ( m_target->config()->isValid() ) {
			m_led_configStatus->setColor( TQt::green );
			m_lbl_configStatus->setText( i18n( "Config Ok" ) );
		} else {
			m_led_configStatus->setColor( TQt::red );
			m_lbl_configStatus->setText( i18n( "Invalid Config!" ) );
		}
		
		
		m_cb_backend->setEnabled( true );
		m_cb_os->setEnabled( true );
		m_host_desc->setEnabled( true );
		m_cmd_testSSH->setEnabled( true );
		m_sb_host_sshPort->setEnabled( true );
		m_cb_backend->setEnabled( true );
		m_cb_os->setEnabled( true );
		m_sb_host_0->setEnabled( true );
		m_sb_host_1->setEnabled( true );
		m_sb_host_2->setEnabled( true );
		m_sb_host_3->setEnabled( true );
		m_cmd_autoConf->setEnabled( true );
		m_host_desc->setEnabled( true );
		m_host_desc->setReadOnly( false );
		if ( m_target->installer() ) {
			for( int i = 0; i < m_cb_os->count(); i++ ) {
				if ( m_cb_os->text( i ).lower() == m_target->installer()->osGUIName().lower() ) {
					m_cb_os->setCurrentItem( i );
					break;
				}
			}
			
			m_cb_backend->clear();
			TQValueList<KMFCompilerInterface*> *comps = m_target->installer()->compilers();
			TQValueList<KMFCompilerInterface*>::iterator it;
			
			for ( it = comps->begin(); it != comps->end(); ++it ) {
				kdDebug() << "Found Compiler: " << (*it)->backendGUIName() << endl;
				m_cb_backend->insertItem( (*it)->backendGUIName() );
			}
		
			for( int i = 0; i < m_cb_backend->count(); i++ ) {
				if ( m_cb_backend->text( i ).lower() == m_target->compiler()->backendGUIName().lower() ) {
					m_cb_backend->setCurrentItem( i );
					break;
				}
			}
		}
		
		if ( m_target->isLocalhost() ) {
//			m_cmd_testSSH->setEnabled( false );
//			m_sb_host_sshPort->setEnabled( false );
			m_sb_host_0->setEnabled( false );
			m_sb_host_1->setEnabled( false );
			m_sb_host_2->setEnabled( false );
			m_sb_host_3->setEnabled( false );
			m_host_desc->setReadOnly( true );
		}
		
	
		IPAddress * addr = m_target->address();
		m_sb_host_0->setValue( addr->getDigit( 0 ) );
		m_sb_host_1->setValue( addr->getDigit( 1 ) );
		m_sb_host_2->setValue( addr->getDigit( 2 ) );
		m_sb_host_3->setValue( addr->getDigit( 3 ) );
		
		m_sb_host_sshPort->setValue( m_target->sshPort() );
		
/*		m_cb_backend->setCurrentItem( m_target->config()->backend(), false );
		m_cb_os->setCurrentItem( m_target->config()->oS(), false );*/
		
		if ( m_host_desc->text().simplifyWhiteSpace() != m_target->description() ) {
			m_host_desc->setText( m_target->description() );
		}
		
	} else {
		m_sb_host_0->setEnabled( false );
		m_sb_host_1->setEnabled( false );
		m_sb_host_2->setEnabled( false );
		m_sb_host_3->setEnabled( false );
		m_cb_backend->setEnabled( false );
		m_cb_os->setEnabled( false );
		m_sb_host_sshPort->setEnabled( false );
		m_cmd_testSSH->setEnabled( false );
		m_host_desc->setEnabled( false );
		m_cmd_autoConf->setEnabled( false );
		m_host_desc->setReadOnly( true );
	}
	
	m_sb_host_0->blockSignals( false );
	m_sb_host_1->blockSignals( false );
	m_sb_host_2->blockSignals( false );
	m_sb_host_3->blockSignals( false );
	m_cb_backend->blockSignals( false );
	m_cb_os->blockSignals( false );
	m_host_desc->blockSignals( false );
	m_sb_host_sshPort->blockSignals( false );
	m_cmd_testSSH->blockSignals( false );
}

void KMFHostWidget::slotTestConnection() {
	if ( ! m_target ) {
		return;
	}
	if ( TDEIO::NetAccess::fish_execute( m_target->getFishUrl(), "ls /",
                    TDEApplication::kApplication()->mainWidget() )  != 0) {
		KMessageBox::information( this, i18n("Conneted successfully to: %1").arg( m_target->toFriendlyString() ) );
	} else {
		KMessageBox::error( this, i18n("Connetion to: %1 failed!").arg( m_target->toFriendlyString() ) );
	}
}
void KMFHostWidget::slotTryAutoConfiguration(){
	kdDebug() << "KMFHostWidget::slotTryAutoConfiguration())" << endl;
	if ( ! m_target ) {
		return;
	}
	KMFError* err = m_target->tryAutoConfiguration();
	KMFErrorHandler* errH = new KMFErrorHandler( i18n("Auto Confguration of: %1").arg( m_target->toFriendlyString() ) ); 
	if ( ! errH->showError( err ) ) {
		return;
	}
	if ( ! m_target->config()->isValid() ) {
		KMessageBox::error( this, i18n("<qt><p>Auto Confguration of: %1 could not determinate all needed setting. You'll need to configure the mmissing settings.</p></qt>").arg( m_target->toFriendlyString() ) );
	} else {
		KMessageBox::information( this, i18n("<qt><p>Auto Confguration of: %1 finished successfully.</p></qt>").arg( m_target->toFriendlyString() ) );
	}
	emit sigTargetChanged();
}

void KMFHostWidget::slotTryAutoConfiguration_Callback( KMFTarget* ) {
	disconnect( m_target, TQ_SIGNAL( sigTargetChanged( KMFTarget* ) ),
		this,TQ_SLOT( slotTryAutoConfiguration_Callback( KMFTarget* ) ) );
	if ( ! m_target->config()->isValid() ) {
		KMessageBox::error( 0, i18n("<qt><p>Auto Confguration of: %1 could not determinate all needed setting. You'll need to configure the mmissing settings.</p></qt>").arg( m_target->toFriendlyString() ) );
	} else {
		KMessageBox::information( this, i18n("<qt><p>Auto Confguration of: %1 finished successfully.</p></qt>").arg( m_target->toFriendlyString() ) );
	}
	emit sigTargetChanged();
}

void KMFHostWidget::slotAddressChanged( int val ) {
	kdDebug() << "KMFHostWidget::slotAddressChanged( int " << val << " )" << endl;
	KMFUndoEngine::instance()->startTransaction(
		m_target,
		i18n( "Edit address of target: %1.").arg( m_target->guiName() )
	);	
	m_target->address()->setAddress( 
			m_sb_host_0->value(),
			m_sb_host_1->value(),
			m_sb_host_2->value(),
			m_sb_host_3->value() );
	KMFUndoEngine::instance()->endTransaction();
	emit sigTargetChanged();
	
}

void KMFHostWidget::slotSSHPortChanged( int val ) {
	kdDebug() << "KMFHostWidget:::slotSSHPortChanged(  int " <<  val << " )" << endl;
	KMFUndoEngine::instance()->startTransaction(
		m_target,
		i18n( "Edit SSH port of target: %1.").arg( m_target->guiName() )
	);	
	m_target->setSSHPort( val );
	KMFUndoEngine::instance()->endTransaction();
	emit sigTargetChanged();
}



void KMFHostWidget::slotOSChanged( const TQString& val ) {
	kdDebug() << "KMFHostWidget:::slotOSChanged(  const TQString& " <<  val << " )" << endl;
	if ( ! m_target ) {
		return;
	}
	KMFUndoEngine::instance()->startTransaction(
		m_target->config(),
		i18n( "Edit operation system setting of target: %1.").arg( m_target->guiName() )
	);
	m_target->config()->setOS( val.lower() );
	
	m_cb_backend->blockSignals( true );
	m_cb_backend->clear();
	TQValueList<KMFCompilerInterface*> *comps = m_target->installer()->compilers();
	TQValueList<KMFCompilerInterface*>::iterator it;
	
	for ( it = comps->begin(); it != comps->end(); ++it ) {
		kdDebug() << "Found Compiler: " << (*it)->backendGUIName() << endl;
		m_cb_backend->insertItem( (*it)->backendGUIName() );
	}
	m_cb_backend->blockSignals( false );
	slotBackaendChanged( m_cb_backend->currentText() );
	
	KMFUndoEngine::instance()->endTransaction();
	emit sigTargetChanged();
}

void KMFHostWidget::slotBackaendChanged( const TQString& val ) {
	kdDebug() << "KMFHostWidget::slotBackaendChanged(  const TQString& " <<  val << " )" << endl;
	KMFUndoEngine::instance()->startTransaction(
		m_target->config(),
		i18n( "Edit backend setting of target: %1.").arg( m_target->guiName() )
	);
	m_target->config()->setBackend( val.lower() );
	
	
	
	KMFUndoEngine::instance()->endTransaction();
	emit sigTargetChanged();
}

void KMFHostWidget::slotDescriptionChanged() {
	kdDebug() << "KMFHostWidget::slotDescriptionChanged()" << endl;
	if (  m_host_desc->text() == m_target->description() ) {
		kdDebug() << "Description Unchanged" << endl;
		return;
	}
	KMFUndoEngine::instance()->startTransaction(
		m_target,
		i18n( "Edit documentation of target: %1.").arg( m_target->guiName() )
	);
	m_target->setDescription( m_host_desc->text().simplifyWhiteSpace() );
	KMFUndoEngine::instance()->endTransaction();
	emit sigTargetChanged();
}

}

#include "kmfhostwidget.moc"

