/***************************************************************************
                          netmoswiz.cpp  -  description
                             -------------------
    begin                : Mon Apr 29 2002
    copyright            : (C) 2002 by Argo Vessmann (ARTEC Design)
    email                : 
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "netmoswiz.h"

#include "../config.h"

#include <iostream.h>

#include <qlabel.h>
#include <qradiobutton.h>
#include <qmultilineedit.h>
#include <qtextview.h>
#include <qlistview.h>
#include <qheader.h>
#include <qgroupbox.h>
#include <qcombobox.h>
#include <qprogressbar.h>
#include <qcheckbox.h>
#include <qpushbutton.h>

#include <serialport.h>

Netmoswiz::Netmoswiz(QWidget *parent, const char *name ) : netmoswizbase(parent,name)
{
	removePage( PgError );
/*	setAppropriate( PgError, FALSE ); */
	setFinishEnabled( PgError, TRUE );
	setBackEnabled( PgWelcome, FALSE );
}

Netmoswiz::~Netmoswiz()
{
}

/** Reimplemented showPage */
void Netmoswiz::showPage( QWidget *page)
{
	QPushButton *b = helpButton();
	b->hide();
	if ( page == PgInfo ) {

		SerialPortList *slist;
		slist = Distro.ExistingSerialPorts();
#if ( QT_VERSION >= 300 )
		SerialPortList::iterator it;
#else
		SerialPortList::Iterator it;
#endif
		ExistingSerials->clear();
		for( it=slist->begin(); it != slist->end(); ++it ) {
			if ( (*it).isDetected() && (*it).baud != -1 )
				(*it).newListViewItem( ExistingSerials );
		}
		NetmosCardList *nlist = Distro.ExistingNetmosCards();
		if ( nlist->isEmpty() ) {
			ErrorNoCards();
			return;
		}
		ExistingNetmos->clear();
#if ( QT_VERSION >= 300 )
		NetmosCardList::iterator nit;
#else
		NetmosCardList::Iterator nit;
#endif
		for( nit=nlist->begin(); nit != nlist->end(); ++nit ) {
			(*nit).newListViewItem( ExistingNetmos );
		}
		QHeader *htmp = ExistingNetmos->header();
		htmp->hide();

		ExistingNetmos->setSorting( -1 );

		currentcard=nlist->begin();
	}

	QWizard::showPage(page);

	if ( page == PgWelcome ) {
		QString s;
		s.sprintf( "Version: %s", VERSION );
		versionlabel->setText( s );
		if ( Distro.SupportedDistribution() )
			setAppropriate( PgIdentDistro, FALSE );
		welcomeinfo->setText( Distro.README() );
	} else if ( page == PgConfirm ) {
#if ( QT_VERSION >= 300 )
		NetmosCardList::iterator nit;
#else
		NetmosCardList::Iterator nit;
#endif
		QString info;
		NetmosCardList *nlist = Distro.ExistingNetmosCards();
		for( nit=nlist->begin(); nit != nlist->end(); ++nit ) {
			(*nit).sprintConfiguration( &info );
		}
		dispconfiguration->setText( info );
	} else if ( page == PgCardConf ) {
		fillPgCardConf( page );
		serDevChanged();
	} else if ( page == PgIdentDistro ) {
		Distro.setDistroType(DISTRO_TYPE_SUSE73);
		CdSuSE->setDown( TRUE );
//		addPage( PgError, "Blah viga" );
//		showPage( PgError );
	} else if ( page == PgError ) {
		setFinishEnabled( PgError, TRUE );
		setBackEnabled( PgError, FALSE );
	} else if ( page == PgFinish ) {
		if ( Distro.saveConf() )
			progresscomment->setText( Distro.saveOkMsg() );
		else
			SysError();
		setFinishEnabled( PgFinish, TRUE );
		setBackEnabled( PgFinish, FALSE );
		QPushButton *b = nextButton();
		b->hide();
	}
		
}

/** New closest distro is selected. */
void Netmoswiz::newClosestDistro(int d)
{

	if ( CdMandrake->isChecked() )
		Distro.setDistroType(DISTRO_TYPE_MANDRAKE82 );
	if ( CdSuSE->isChecked() )
		Distro.setDistroType(DISTRO_TYPE_SUSE73 );
	if ( CdRedHat->isChecked() )
		Distro.setDistroType(DISTRO_TYPE_REDHAT72 );
	
}

/** Show error message that we don't have netmos cards. */
void Netmoswiz::ErrorNoCards()
{
	addPage( PgError, "Error" );
	QString msg = "No NetMos cards found\n\n"
		"System cannot detect any NetMos cards. Please check the card. "
		"If the card is inserted correctly but still not responding, "
		"try inserting it into some other PCI slot.";
	ErrorMsg->setText( "Ei leia yhtki kaart\n" );
	showPage( PgError );
}

/** When back is clicked */
void Netmoswiz::back()
{
	QWidget *tmp = currentPage();
	if ( tmp == PgCardConf ) {
		readCurrentConf();
		NetmosCardList *nlist = Distro.ExistingNetmosCards();
		if ( currentcard != nlist->begin() ) {
			currentcard--;
			(*currentcard).setFixedConf( FALSE );
			showPage( PgCardConf );
			return;
		}
	} else if ( tmp == PgConfirm )
		currentcard--;
	QWizard::back();
}

/** When next is clicked */
void Netmoswiz::next()
{
	QWidget *page = currentPage();
	if ( page == PgCardConf ) {
		readCurrentConf();
		(*currentcard).setFixedConf( TRUE );
		NetmosCardList *nlist = Distro.ExistingNetmosCards();
		++currentcard;
		if ( currentcard != nlist->end() ) {
			currentcard--;
			(*currentcard).debug();
			currentcard++;
			showPage( PgCardConf );
			return;
		}		
	} else if ( page == PgWelcome ) {
		if ( !Distro.testSystem() ) {
			SysError();
			return;
		}
	}

	QWizard::next();
}

/** Enables/Disables second serial port configuration. */
void Netmoswiz::enableSecondSerial( bool t )
{
	serlabel2_1->setEnabled( t );
	serlabel2_2->setEnabled( t );
	serdev2->setEnabled( t );
	serspeed2->setEnabled( t );
}

/** Fills a wizards page for configuration. */
void Netmoswiz::fillPgCardConf( QWidget *page )
{
	QString ptitle;
//        ptitle.sprintf( "Configuring card %s", (const char *)(*currentcard).CardName() );
	cardname->setText( (*currentcard).CardName() );
	cardid->setText( (*currentcard).CardID() );
	QStringList vserials = Distro.ValidSerials();
	serdev1->clear();
	serdev2->clear();
	for ( QStringList::Iterator it = vserials.begin(); it != vserials.end(); ++it ) {
		serdev1->insertItem( *it );
		serdev2->insertItem( *it );
	}
	if ( (*currentcard).hasSerials() ){
		serialconf->setEnabled( TRUE );
		if ( (*currentcard).isSerialConfigured( 0 ) ) {
			fillSerialValues( 0, serdev1, serspeed1 );
		}
	} else
		serialconf->setEnabled( FALSE );
	if ( (*currentcard).has2SerialPorts() ) {
		if ( (*currentcard).isSerialConfigured( 1 ) )
			fillSerialValues( 1, serdev2, serspeed2 );
		if ( serdev1->currentText() == serdev2->currentText() ) {
			int nextitem = serdev2->currentItem()+1;
			if ( nextitem == serdev2->count() )
				nextitem = 0;
			serdev2->setCurrentItem( nextitem );
		}
		enableSecondSerial( TRUE );
	} else
		enableSecondSerial( FALSE );

/** Parallel ports */
	if ( (*currentcard).hasParallel( 0 ) )
		parallelconf->setEnabled( TRUE );
	else
		parallelconf->setEnabled( FALSE );

	QCheckBox *parenabled[2], *parecp[2];
	parenabled[0] = par1enabled;
	parenabled[1] = par2enabled;
	parecp[0] = par1ecp;
	parecp[1] = par2ecp;
	
	for( int i=0;i<2;i++ ) {
		parenabled[i]->setChecked( FALSE );
		parecp[i]->setChecked( FALSE );
		if ( (*currentcard).hasParallel( i ) ) {
			parenabled[i]->setEnabled( TRUE );
			if ( (*currentcard).parallelenabled( i ) ) {
				parenabled[i]->setChecked( TRUE );
				if ( (*currentcard).parallelECP( i ) )
					parecp[i]->setChecked( TRUE );
			} else
				parenabled[i]->setChecked( FALSE );
		} else
			parenabled[i]->setEnabled( FALSE );
	}
		
}

/** Fills already configured serial values. */
void Netmoswiz::fillSerialValues( int nr, QComboBox *dev, QComboBox *sp )
{
	QString cdevname = (*currentcard).serialDevName( nr );
	for( int i=0;i<dev->count();i++ )
		if ( cdevname == dev->text( i ) ) {
			dev->setCurrentItem( i );
			break;
		}
	int cspeed = (*currentcard).serialDevSpeed( nr );
	for( int i=0;i<sp->count();i++ )
		if ( cspeed == sp->text(i).toInt() ) {
			sp->setCurrentItem( i );
			break;
		}
}

/** Serial device has changed on either of serial configurations. */
void Netmoswiz::serDevChanged()
{
	if ( !(*currentcard).has2SerialPorts() )
		return;
	if ( serdev1->currentText() == serdev2->currentText() )
		setNextEnabled( currentPage(), FALSE );
	else
		setNextEnabled( currentPage(), TRUE );
}

/** Read current configuration */
void Netmoswiz::readCurrentConf()
{
	if ( (*currentcard).hasSerials() ){ // Serial 1
		readOneSerialConf(0, serdev1, serspeed1 );
	}
	if ( (*currentcard).has2SerialPorts() ) { // Serial 2
		readOneSerialConf( 1, serdev2, serspeed2 );
	}
	if ( (*currentcard).hasParallel( 0 ) )
		readOneParallelConf( 0, par1enabled, par1ecp );
	if ( (*currentcard).hasParallel( 1 ) )
		readOneParallelConf( 1, par2enabled, par2ecp );
			
}

/** Read given configuration of one serial port. */
void Netmoswiz::readOneSerialConf( int nr, QComboBox *dev, QComboBox *sp)
{
	SerialPortList *slist = Distro.ExistingSerialPorts();
#if ( QT_VERSION >= 300 )
	SerialPortList::iterator it;
#else
	SerialPortList::Iterator it;
#endif
	for( it=slist->begin(); it != slist->end(); ++it ) {
		if ( (*it).DevName() == dev->currentText() )
			break;
	}
	if ( it == slist->end() ) {
		SerialPort po;
		po.clean();
		QString tmp = dev->currentText().mid( 9, 2 );
		po.port = tmp.toInt();
		it = slist->append( po );
	}
	(*it).setSpeed( sp->currentText().toInt() );
	(*currentcard).setSerial( nr, &(*it) );
}

/** Reads parameters of one parallel port. */
void Netmoswiz::readOneParallelConf( int nr, QCheckBox *enab, QCheckBox *ecp )
{
	if ( enab->isChecked() ) {
		(*currentcard).setParallel( nr, TRUE );
		if ( ecp->isChecked() )
			(*currentcard).setParallelECP( nr, TRUE );
		else
			(*currentcard).setParallelECP( nr, FALSE );
	} else {
		(*currentcard).setParallel( nr, FALSE );
		(*currentcard).setParallelECP( nr, FALSE );
	}
}

/** Tests if the system has all parts we are needinig */
void Netmoswiz::SysError( void )
{
	addPage( PgError, "Error" );
	ErrorMsg->setText( Distro.ErrorMsg() );
	showPage( PgError );
}
