/***************************************************************************
                          DialogCntPnl.cpp  -  description
                             -------------------
    begin                : Thu May 31 2001
    copyright            : (C) 2001 by Alex Podolsky
    email                : alexpod@users.sourceforge.net
 ***************************************************************************/

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

#include <qframe.h>
#include <qgroupbox.h>
#include <qheader.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qvariant.h>
#include <qtooltip.h>
#include <qwhatsthis.h>
#include <qstringlist.h>
#include <qevent.h>
#include <qdatetime.h>
#include <qobject.h>
#include <qscrollbar.h>
#include <qtextstream.h>
#include <qdir.h>
#include <qfile.h>
#include <qpixmap.h>
#include <qregexp.h>
#include <qpainter.h>
#include <qregexp.h>

#include <kglobal.h>
#include <kiconloader.h>
#include <kfiledialog.h>
#include <klistview.h>
#include <kconfig.h>


#include "DialogCntPnl.h"
#include "DialogCntPnl.moc"
#include "../CdboDialogBase.h"

#define TYPE_COL 0
#define PROGRESS_COL 1

#define TOTAL_PROGRESS_OUT 100
#define PROGRESS_OUT 101

/*
 *  Constructs a DialogCntPnl which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'
 */
DialogCntPnl::DialogCntPnl( QWidget* parent,  const char* name, WFlags fl )
    : QWidget( parent, name, fl )
{
    if ( !name )
	setName( "DialogCntPnl" );
    resize( 749, 285 );
    setMinimumSize( QSize( 0, 285 ) );
    setMaximumSize( QSize( 32767, 285 ) );
    DialogCntPnlLayout = new QHBoxLayout( this );
    DialogCntPnlLayout->setSpacing( 0 );
    DialogCntPnlLayout->setMargin( 0 );

    mainFrm = new QFrame( this, "mainFrm" );
    mainFrm->setFrameShape( QFrame::StyledPanel );
    mainFrm->setFrameShadow( QFrame::Raised );
    mainFrmLayout = new QGridLayout( mainFrm );
    mainFrmLayout->setSpacing( 5 );
    mainFrmLayout->setMargin( 9 );

    GroupBox42_2 = new QGroupBox( mainFrm, "GroupBox42_2" );
    GroupBox42_2->setFrameShape( QGroupBox::Box );
    GroupBox42_2->setFrameShadow( QGroupBox::Sunken );
    GroupBox42_2->setLineWidth( 1 );
    GroupBox42_2->setMargin( 0 );
    GroupBox42_2->setTitle( i18n( "Process Output" ) );
    GroupBox42_2->setAlignment( int( QGroupBox::AlignTop | QGroupBox::AlignHCenter ) );
    GroupBox42_2->setColumnLayout(0, Qt::Vertical );
    GroupBox42_2->layout()->setSpacing( 0 );
    GroupBox42_2->layout()->setMargin( 0 );
    GroupBox42_2Layout = new QVBoxLayout( GroupBox42_2->layout() );
    GroupBox42_2Layout->setAlignment( Qt::AlignTop );
    GroupBox42_2Layout->setSpacing( 0 );
    GroupBox42_2Layout->setMargin( 6 );

    outputView = new KListView( GroupBox42_2, "outputView" );
    outputView->addColumn( i18n( "Type" ) );
    outputView->addColumn( i18n( "Message" ) );
    outputView->setFrameShape( QListView::Box );
    outputView->setFrameShadow( QListView::Plain );
    outputView->setLineWidth( 1 );
    outputView->setShowSortIndicator( false );

	outputView->setSorting(-1);
	//outputView->setColumnWidth(0,80);
	//outputView->setColumnWidth(1,462);

    QToolTip::add(  outputView, i18n( "Process output monitor" ) );
    QWhatsThis::add(  outputView, i18n( "Process output monitor" ) );
    GroupBox42_2Layout->addWidget( outputView );

    Frame11_2_2_2 = new QFrame( GroupBox42_2, "Frame11_2_2_2" );
    Frame11_2_2_2->setFrameShape( QFrame::StyledPanel );
    Frame11_2_2_2->setFrameShadow( QFrame::Raised );
    Frame11_2_2_2Layout = new QHBoxLayout( Frame11_2_2_2 );
    Frame11_2_2_2Layout->setSpacing( 1 );
    Frame11_2_2_2Layout->setMargin( 1 );

    statusLbl = new QLabel( Frame11_2_2_2, "statusLbl" );
    statusLbl->setMinimumSize( QSize( /*160*/292, 0 ) );
    statusLbl->setFrameShape( QLabel::Panel );
    statusLbl->setFrameShadow( QLabel::Sunken );
    statusLbl->setText( i18n( "No recording device!" ) );
    //statusLbl->setAlignment( int( QLabel::AlignCenter ) );
    Frame11_2_2_2Layout->addWidget( statusLbl );

    elapsedTimeLbl = new QLabel( Frame11_2_2_2, "elapsedTimeLbl" );
    elapsedTimeLbl->setMinimumSize( QSize( 112, 0 ) );
    elapsedTimeLbl->setMaximumSize( QSize( 120, 30 ) );
    elapsedTimeLbl->setFrameShape( QLabel::Panel );
    elapsedTimeLbl->setFrameShadow( QLabel::Sunken );
    elapsedTimeLbl->setText( i18n( "Elapsed Time:" ) );
    elapsedTimeLbl->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
    Frame11_2_2_2Layout->addWidget( elapsedTimeLbl );

    eTimeLbl = new QLabel( Frame11_2_2_2, "eTimeLbl" );
    eTimeLbl->setMaximumSize( QSize( 100, 32767 ) );
    eTimeLbl->setFrameShape( QLabel::Panel );
    eTimeLbl->setFrameShadow( QLabel::Sunken );
    eTimeLbl->setText( i18n( " 00 min" ) );
    eTimeLbl->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignLeft ) );
    Frame11_2_2_2Layout->addWidget( eTimeLbl );

    /*timeRemLbl = new QLabel( Frame11_2_2_2, "timeRemLbl" );
    timeRemLbl->setMinimumSize( QSize( 112, 0 ) );
    timeRemLbl->setFrameShape( QLabel::Panel );
    timeRemLbl->setFrameShadow( QLabel::Sunken );
    timeRemLbl->setText( i18n( "Time Remaining:" ) );
    timeRemLbl->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) );
    Frame11_2_2_2Layout->addWidget( timeRemLbl );

    rTimeLbl = new QLabel( Frame11_2_2_2, "rTimeLbl" );
    rTimeLbl->setMaximumSize( QSize( 90, 32767 ) );
    rTimeLbl->setFrameShape( QLabel::Panel );
    rTimeLbl->setFrameShadow( QLabel::Sunken );
    rTimeLbl->setText( i18n( " Unknown" ) );
    rTimeLbl->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignLeft ) );
    Frame11_2_2_2Layout->addWidget( rTimeLbl );*/

    GroupBox42_2Layout->addWidget( Frame11_2_2_2 );

    mainFrmLayout->addMultiCellWidget( GroupBox42_2, 0, 1, 0, 0 );

    controlPanel_2 = new QFrame( mainFrm, "controlPanel_2" );
    controlPanel_2->setMinimumSize( QSize( 0, 258 ) );
    controlPanel_2->setMaximumSize( QSize( 32767, 260 ) );
    controlPanel_2->setFrameShape( QFrame::Box );
    controlPanel_2->setFrameShadow( QFrame::Sunken );
    QWhatsThis::add(  controlPanel_2, i18n( "Control panel." ) );
    controlPanel_2Layout = new QVBoxLayout( controlPanel_2 );
    controlPanel_2Layout->setSpacing( 1 );
    controlPanel_2Layout->setMargin( 7 );

    startBtn = new QPushButton( controlPanel_2, "startBtn" );
    startBtn->setMinimumSize( QSize( 120, 40 ) );
    startBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont startBtn_font(  startBtn->font() );
    startBtn_font.setBold( TRUE );
    startBtn->setFont( startBtn_font );
    startBtn->setText( i18n( "Start!" ) );
    QToolTip::add(  startBtn, i18n( "Start erase!" ) );
    controlPanel_2Layout->addWidget( startBtn );

    cancelBtn = new QPushButton( controlPanel_2, "cancelBtn" );
    cancelBtn->setEnabled( FALSE );
    cancelBtn->setMinimumSize( QSize( 120, 40 ) );
    cancelBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont cancelBtn_font(  cancelBtn->font() );
    cancelBtn_font.setBold( TRUE );
    cancelBtn->setFont( cancelBtn_font );
    cancelBtn->setText( i18n( "&Cancel" ) );
    controlPanel_2Layout->addWidget( cancelBtn );

    settingsBtn = new QPushButton( controlPanel_2, "settingsBtn" );
    settingsBtn->setMinimumSize( QSize( 120, 40 ) );
    settingsBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont settingsBtn_font(  settingsBtn->font() );
    settingsBtn_font.setBold( TRUE );
    settingsBtn->setFont( settingsBtn_font );
    settingsBtn->setText( i18n( "&Settings" ) );
    QToolTip::add(  settingsBtn, i18n( "CD Bake Oven Settings" ) );
    controlPanel_2Layout->addWidget( settingsBtn );

    dumpBtn = new QPushButton( controlPanel_2, "dumpBtn" );
    dumpBtn->setMinimumSize( QSize( 120, 40 ) );
    dumpBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont dumpBtn_font(  dumpBtn->font() );
    dumpBtn_font.setBold( TRUE );
    dumpBtn->setFont( dumpBtn_font );
    dumpBtn->setText( i18n( "D&ump" ) );
    controlPanel_2Layout->addWidget( dumpBtn );

    helpBtn = new QPushButton( controlPanel_2, "helpBtn" );
    helpBtn->setMinimumSize( QSize( 120, 40 ) );
    helpBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont helpBtn_font(  helpBtn->font() );
    helpBtn_font.setBold( TRUE );
    helpBtn->setFont( helpBtn_font );
    helpBtn->setText( i18n( "&Help" ) );
    controlPanel_2Layout->addWidget( helpBtn );

    quitBtn = new QPushButton( controlPanel_2, "quitBtn" );
    quitBtn->setMinimumSize( QSize( 120, 40 ) );
    quitBtn->setMaximumSize( QSize( 120, 40 ) );
    QFont quitBtn_font(  quitBtn->font() );
    quitBtn_font.setBold( TRUE );
    quitBtn->setFont( quitBtn_font );
    quitBtn->setText( i18n( "C&lose" ) );
    quitBtn->setDefault( TRUE );
    QToolTip::add(  quitBtn, i18n( "Closes this dialog" ) );

    controlPanel_2Layout->addWidget( quitBtn );

    mainFrmLayout->addWidget( controlPanel_2, 1, 1 );
    QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
    mainFrmLayout->addItem( spacer, 0, 1 );
    DialogCntPnlLayout->addWidget( mainFrm );
	
	// signals and slots connections
    connect( dumpBtn, SIGNAL( clicked() ), this, SLOT( dumpSlot() ) );
    connect( helpBtn, SIGNAL( clicked() ), this, SLOT( helpSlot() ) );
	config = 0;
	clearOutput();
	initProcFunkArr();
	outputView->setFullWidth(true);
}

//======================================================
DialogCntPnl::~DialogCntPnl(){
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// OUTPUT    /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------------------------
void DialogCntPnl::clearOutput() {
	outputView->clear();
	processType = CdboDialogBase::unknownProcess;
	progressItem = 0;
	isoProgressItem = 0;
	processesDone = 1;
	totalToProcess = 1;
	percentDone = 0;
	firstMove = true;
	cddaDone = false;
	ignoreOutput = false;
	if(config)
		delete config;
	config = new KConfig("cdbakeovenrc");
}
//---------------------------------------------------------------------------------------------
void DialogCntPnl::output(int type, QString message){
	QStringList list(QStringList::split("\n",message));
	for(int i = 0; i < (int)list.count(); i++){
		if(list[i].isEmpty())
			continue;
		(*this.*procFunkArr[processType])(type, list[i].stripWhiteSpace());
    }
}
//============================================
void DialogCntPnl::initByType(int type, QString *mtype, QString *pixmap){
	switch(type){
		case CdboDialogBase::ErrorMessage:{
			*mtype = "Error: ";
			*pixmap = "error";
			break;
		}
		case CdboDialogBase::ProcessMessage:{
			*mtype = "Process: ";
			*pixmap = "process";
			break;
		}
		case CdboDialogBase::InfoMessage:{
			*mtype = "Info: ";
			*pixmap = "info";
			break;
		}
		case CdboDialogBase::StatusOkMessage:{
			*mtype = "Status: ";
			*pixmap = "ok";
			break;
		}
		case CdboDialogBase::StatusNotOkMessage:{
			*mtype = "Status: ";
			*pixmap = "remove";
			break;
		}
		case TOTAL_PROGRESS_OUT:{
			*mtype = "Total Progress: ";
			*pixmap = "color_line";
			break;
		}
		case PROGRESS_OUT:{
			*mtype = "Progress: ";
			*pixmap = "color_line";
			break;
		}
	}
        //*mtype = i18n(*mtype);
}
//=======================================
void DialogCntPnl::initProcFunkArr(){
	procFunkArr[CdboDialogBase::cdda2wavProcess] = &DialogCntPnl::processCdda2wavProcessMess;
	procFunkArr[CdboDialogBase::cdrecordProcess] = &DialogCntPnl::processCdrecordProcessMess;
	procFunkArr[CdboDialogBase::mkisofsProcess] = &DialogCntPnl::processMkisofsProcessMess;
	procFunkArr[CdboDialogBase::cdparanoiaProcess] = &DialogCntPnl::processCdparanoiaProcessMess;
	procFunkArr[CdboDialogBase::rippProcess] = &DialogCntPnl::processRippProcessMess;	
	procFunkArr[CdboDialogBase::oggMp3Process] = &DialogCntPnl::processOggMp3ProcessMess;
	procFunkArr[CdboDialogBase::unknownProcess] = &DialogCntPnl::processUnknownProcessMess;
}
//=======================================
void DialogCntPnl::processCdda2wavProcessMess(int type, QString message){	
	//cerr << "message = " << message << "\n\n===========\n\n";
	if(!cddaDone){
		int spot = message.find("%");
		if(spot !=-1){
			message = message.left(spot);
			message = (message.right(message.length() - message.findRev(" "))).stripWhiteSpace();
			//cerr << "message = '" << message << "'\n";
			int m = message.toInt();

			


			if(m == 100 && processesDone == totalToProcess){
				updateProgress(m, progressItem);
				cddaDone = true;
				progressItem = 0;
				ignoreOutput = false;
				return;
			}
			if(m == 100 && processesDone < totalToProcess){
				processesDone++;
				outputView->lastChild()->itemAbove()->setText(PROGRESS_COL, i18n(
				"Reading track %1 of %2. Percent complete:").arg(QString::number(processesDone)).arg(QString::number(totalToProcess)));
			}
			if(!progressItem){
				QString mtype, pixmap;
				initByType(PROGRESS_OUT,&mtype,&pixmap);
				progressItem = new QListViewItem(outputView, outputView->lastChild());
				progressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
				progressItem->setText( TYPE_COL, mtype);
				ignoreOutput = true;
			}
			if(progressItem->text(1) == QString::number(m) + "% ")
				return;
			updateProgress(m, progressItem);
			return;
		}
	}
	if(ignoreOutput || message.find("%") !=-1)
		return;
	if(message.find("overlap:min/max/cur") !=-1){
		type = CdboDialogBase::InfoMessage;
		message = "Reading track " + QString::number(processesDone) +
			" of " + QString::number(totalToProcess) + ", percent done:";
	}
//cerr << "message = " << message << "\n\n===========\n\n";
	QString mtype, pixmap;
	initByType(type,&mtype,&pixmap);
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}
//=======================================
void DialogCntPnl::processCdrecordProcessMess(int type, QString message){
//cerr << "message = " << message << "\n\n===========\n\n";
	QString mtype, pixmap, buff;
	if(message.find("seconds.") !=-1 && (message.find("Last") !=-1 ||  message.find("Operation") !=-1))
		type = CdboDialogBase::StatusOkMessage;
	initByType(type,&mtype,&pixmap);
	QListViewItem *par;
	if(isoProgressItem != 0)
		par = isoProgressItem->itemAbove()->itemAbove();
	else
		par = outputView->lastChild();
	if(message.find("seconds.") !=-1 && message.find("Last") ==-1){
		buff = par->text(PROGRESS_COL);
		if(buff.find("Last") !=-1  && message.find("Operation") ==-1){
			///This is the old way,
			// MY BRAINES ARE DEAD TODAY< MUST BE THE WEATHER :)
			//par->setText( PROGRESS_COL, message.remove(0,message.find(QRegExp("[0-9]{1,1}"))));
			buff = (buff.replace(QRegExp("seconds."), "")).simplifyWhiteSpace();
			buff = (buff.replace(QRegExp("[0-9]{1,1}"), ""));
			message = message.remove(0,message.find(QRegExp("[0-9]{1,1}")));
			par->setText( PROGRESS_COL, buff + message);
			return;
		}
		else
			message = message.remove(0,message.find(QRegExp("[0-9]{1,1}")));
	}
	

	if(message.find("done, estimate finish") !=-1){
		buff = message.left(message.find("."));
		message = (message.right(message.length() - message.findRev(","))).stripWhiteSpace();
		
		if(!isoProgressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			isoProgressItem = new QListViewItem(outputView, outputView->lastChild());
			isoProgressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			isoProgressItem->setText( TYPE_COL, mtype);
			QListViewItem * item = new QListViewItem(outputView, outputView->lastChild()->itemAbove());
			item->setPixmap( TYPE_COL, UserIcon("info", KIcon::SizeSmall ));
			item->setText( TYPE_COL, i18n("Info:"));
			item->setText( PROGRESS_COL, i18n("Creating ISO image, percent done:"));
		}
		int pr = buff.toInt();
		updateProgress(pr, isoProgressItem, " " + message);
		return;
	}
	if(message.find("Total translation") !=-1 && isoProgressItem != 0){
		updateProgress(100, isoProgressItem);
		isoProgressItem = 0;
	}
	if(message.find("Starting new") !=-1){
		if(!progressItem)
			return;
		processesDone++;
		if(processesDone < 10)
			buff = "0" + QString::number(processesDone);
		else
			buff = QString::number(processesDone);
		QListViewItem * item =  progressItem->itemAbove();
		item->setPixmap( TYPE_COL, UserIcon("info", KIcon::SizeSmall ));
		item->setText( TYPE_COL, i18n("Info:"));
		item->setText( PROGRESS_COL, i18n("Burning Track %1, percent done:").arg(buff));
		return;
	}
	if(message.find("MB written") !=-1){
		buff =  (message.right(message.length() - message.find(":") - 1)).stripWhiteSpace();
		//message =  (message.right(message.length() - message.find(":") - 1)).stripWhiteSpace();
		QStringList l = QStringList::split(" ", buff);
		float i = l[0].toFloat();
		float y = l[2].toFloat();
		if(y == 0){
			config->setGroup("Default Settings");
			y = config->readNumEntry("Image Size", 0);
		}
		i = i / (y / 100);
		if(i > 100 || y == 0)
			i = 100;
		
		if(!progressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			if(isoProgressItem != 0)
				par = isoProgressItem;
			else
				par = outputView->lastChild();
			progressItem = new QListViewItem(outputView, par);
			progressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			progressItem->setText( TYPE_COL, mtype);
			
			QListViewItem * item = new QListViewItem(outputView, progressItem->itemAbove());
			item->setPixmap( TYPE_COL, UserIcon("info", KIcon::SizeSmall ));
			item->setText( TYPE_COL, i18n("Info:"));
			message = message.left(message.find(":")).stripWhiteSpace();
		        item->setText( PROGRESS_COL, i18n("Burning Track %1, percent done:").arg(buff));
			processesDone = message.right(message.length() - message.find(" ")).stripWhiteSpace().toInt();
		}
		updateProgress((int)i, progressItem, ": " + buff);
		return;
	}
	
	QListViewItem * item = new QListViewItem(outputView, par);
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}
//=======================================
void DialogCntPnl::processMkisofsProcessMess(int type, QString message){
	QString mtype, pixmap, buff;
	initByType(type,&mtype,&pixmap);
	if(message.find("Starting create ISO process") !=-1){
 		outputView->verticalScrollBar()->setValue(outputView->verticalScrollBar()->maxValue());
		//return;
 	}
	if(message.find("done, estimate finish") !=-1){
		buff = message.left(message.find("."));
		message = (message.right(message.length() - message.findRev(","))).stripWhiteSpace();
		
		if(!isoProgressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			isoProgressItem = new QListViewItem(outputView, outputView->lastChild());
			isoProgressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			isoProgressItem->setText( TYPE_COL, mtype);
			QListViewItem * item = new QListViewItem(outputView, outputView->lastChild()->itemAbove());
			item->setPixmap( TYPE_COL, UserIcon("info", KIcon::SizeSmall ));
			item->setText( TYPE_COL, i18n("Info:"));
			item->setText( PROGRESS_COL, i18n("Creating ISO image, percent done:"));
		}
		updateProgress(buff.toInt(), isoProgressItem, " " + message);
		return;
	}
	
	//if(message.find("Excluded by match:") !=-1 || message.find("Using") !=-1 || message.find("Scanning") !=-1)
		//return;
	
	if(message.find("Total translation") !=-1){
		updateProgress(100, isoProgressItem);
		isoProgressItem = 0;
	}
	
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}
//=======================================
void DialogCntPnl::processCdparanoiaProcessMess(int type, QString message){
	//cerr << "message = " << message << "\n\n===========\n\n";
			
	/*if(message.find("Ripping from sector") !=-1){
		message = (message.replace(QRegExp("Ripping from sector"), "")).simplifyWhiteSpace();
		message = message.left(message.find(" "));
		procTimeId = message.stripWhiteSpace().toInt();
		//cerr << "procTimeId = '" << procTimeId << "'\n";
		
		type = CdboDialogBase::InfoMessage;
		message = "Reading track " + QString::number(processesDone) +
			" of " + QString::number(totalToProcess) + ", percent done:";
			
	}
	if(message.find("to sector") !=-1){
		message = (message.replace(QRegExp("to sector"), "")).simplifyWhiteSpace();
		message = message.left(message.find(" "));
		int tot = message.stripWhiteSpace().toInt();
		tot -= procTimeId;
		
		cerr << "tot / 148 * 10 = '" << tot / 148 * 10 << "'\n";
		if(!progressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			progressItem = new QListViewItem(outputView, outputView->lastChild());
			progressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			progressItem->setText( TYPE_COL, mtype);
			updateProgress(0, progressItem);
		}
		procTimeId = startTimer(tot / 148 * 10);
		return;
	}*/
	if(message.find("outputting to") !=-1)
		return;
		
	
	QString mtype, pixmap;
	initByType(type,&mtype,&pixmap);
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}//=======================================
void DialogCntPnl::processOggMp3ProcessMess(int type, QString message){
	//cerr << "\n\n===========\n\n" << "message = " << message << "\n\n===========\n\n";
	int pos = 0;
	if(message.find("Title") !=-1){
		QListViewItem * item;
		if(!progressItem)
			item = new QListViewItem(outputView, outputView->lastChild());
		else
			item = progressItem->itemAbove();
		item->setPixmap( TYPE_COL, UserIcon("info", KIcon::SizeSmall ));
		item->setText( TYPE_COL, i18n("Info:"));
		if(message.find("Title:") !=-1){
			message = message.replace(QRegExp("Title:"), "").stripWhiteSpace();
		}
		else{
			message = message.right(message.length() - message.find(":") - 1);
			message = message.left(message.find("Artist")).stripWhiteSpace();
		}
		item->setText( PROGRESS_COL, i18n("Decompressing '%1' (%2 of %3), percent done:").arg(message).arg(QString::number(processesDone)).arg(QString::number(totalToProcess)));
		processesDone++;
		return;
	}
	if((pos = message.find("Time:")) !=-1){
		message = message.right(message.length() - pos - 5);
		message = message.left(message.find("]")).stripWhiteSpace();
		QString buff = message.left(message.find(".")).stripWhiteSpace();
		message = message.replace(QRegExp(buff), "").stripWhiteSpace();
		message = message.right(message.length() - message.find("[") - 1);
		message = message.left(message.find(".")).stripWhiteSpace();

		float done = buff.left(buff.find(":")).toFloat() * 60 + buff.right(buff.length() - buff.find(":") -1).toFloat();

		float left = message.left(message.find(":")).toFloat() * 60 + message.right(message.length() - message.find(":") -1).toFloat();

		if(!progressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			progressItem = new QListViewItem(outputView, outputView->lastChild());
			progressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			progressItem->setText( TYPE_COL, mtype);
			updateProgress(0, progressItem);
		}
		int i = (int)( done / ((done + left) / 100));
		updateProgress(i, progressItem, "");
		return;
	}
	if((message.find("Decoding of") !=-1 && message.find("finished") !=-1) || message.find("Done") !=-1){
		updateProgress(100, progressItem);
		if(processesDone == totalToProcess)
			progressItem = 0;
		return;
	}
	if(type ==  CdboDialogBase::ProcessMessage)
		return;////////////////////////////////////////////////////////////////////////////////
	//if(message.find("%") !=-1)
	//	return;
	
	QString mtype, pixmap;
	initByType(type,&mtype,&pixmap);
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());

	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}
//=======================================
void DialogCntPnl::processRippProcessMess(int type, QString message){
	//cerr << "message = " << message << "\n\n===========\n\n";
			
	if(message.find("percent done:") !=-1){
		message = message.replace(QRegExp("percent done:"), "");
		message = message.stripWhiteSpace();
		//cerr << "message = '" << message << "'\n";
		
		if(!progressItem){
			QString mtype, pixmap;
			initByType(PROGRESS_OUT,&mtype,&pixmap);
			progressItem = new QListViewItem(outputView, outputView->lastChild());
			progressItem->setPixmap( TYPE_COL, SmallIcon(pixmap));
			progressItem->setText( TYPE_COL, mtype);
		}
		updateProgress(message.toInt(), progressItem);
		
		return;
	}
	
	if(message.find("show total") !=-1){
		type = CdboDialogBase::InfoMessage;
		message = i18n("Ripping track ") + QString::number(processesDone) +
			i18n(" of ") + QString::number(totalToProcess) + i18n(", percent done:");
	}
	if(message.find("processed files:") !=-1){
		processesDone++;
		outputView->lastChild()->itemAbove()->setText(PROGRESS_COL,
			i18n("Ripping track ") + QString::number(processesDone) +
			i18n(" of ") + QString::number(totalToProcess) + i18n(", percent done:"));
		return;
	}
	if(message.find("Operation completed successfully") !=-1){
		updateProgress(100, progressItem);
		outputView->lastChild()->itemAbove()->setText(PROGRESS_COL,
			i18n("Ripping track ") + QString::number(totalToProcess) +
			i18n(" of ") + QString::number(totalToProcess) + i18n(", percent done:"));
	}
	
	QString mtype, pixmap;
	initByType(type,&mtype,&pixmap);
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}
}
//=======================================
void DialogCntPnl::processUnknownProcessMess(int type, QString message){

	//cerr << "\n\n=++++++++++++++++++++++++++++++++=\n\n";
	//cerr << message;
	//cerr << "\n\n=++++++++++++++++++++++++++++++++=\n\n";
	QString mtype, pixmap, buff;
	initByType(type,&mtype,&pixmap);
	
	if(message.find("seconds.") !=-1 && message.find("Last") ==-1){
		buff = outputView->lastChild()->text(PROGRESS_COL);
		if(buff.find("Last") ==-1){
			outputView->lastChild()->setText( PROGRESS_COL, message.remove(0,message.find(QRegExp("[0-9]{1,1}"))));
			return;
		}
		else
			message = message.remove(0,message.find(QRegExp("[0-9]{1,1}")));
	}
	if(message.find("done, estimate finish") !=-1){//mkisofs
		buff = outputView->lastChild()->text(PROGRESS_COL);
		if(buff.find("done, estimate finish") !=-1){
			outputView->lastChild()->setText( PROGRESS_COL, message);
			return;
		}
		buff = outputView->lastChild()->itemAbove()->text(PROGRESS_COL);
		if(buff.find("done, estimate finish") !=-1){
			outputView->lastChild()->itemAbove()->setText( PROGRESS_COL, message);
			return;
		}
	}
	if(message.find("MB written") !=-1){//cdrecord
		buff = outputView->lastChild()->text(PROGRESS_COL);
		if(buff.find("MB written") !=-1){
			outputView->lastChild()->setText( PROGRESS_COL, message);
			return;
		}
		buff = outputView->lastChild()->itemAbove()->text(PROGRESS_COL);
		if(buff.find("MB written") !=-1){
			outputView->lastChild()->itemAbove()->setText( PROGRESS_COL, message);
			return;
		}
		
	}
	
	if(message.find("Excluded by match:") !=-1)//mkisofs
		return;
	
	if(message.find("%") !=-1 && message.find("/") > 1){//cdda2wav
		outputView->lastChild()->setText( PROGRESS_COL, message);
		return;
	}
	
	QListViewItem * item = new QListViewItem(outputView, outputView->lastChild());
	item->setPixmap( TYPE_COL, UserIcon(pixmap, KIcon::SizeSmall ));
	item->setText( TYPE_COL, mtype);
	item->setText( PROGRESS_COL, message);

	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(item);
	else{
		if(firstMove){
			outputView->ensureItemVisible(item);
			firstMove = false;
		}
	}

}
//=================================================
void DialogCntPnl::updateProgress(int percentDone, QListViewItem *thisItem, QString optMess){
	
		
	int h = outputView->fontMetrics().lineSpacing();
	if(h <= 0)
		return;

	int w = outputView->columnWidth(PROGRESS_COL)/2;
	if(w <= 0)
		return;
	if(w > 200)
		w = 200;
		
	QPixmap *pix = new QPixmap( w, h );
	if( pix == 0 )
		return;
	config->setGroup("Default Settings");
	pix->fill(config->readColorEntry("Process Left Color", &Qt::white));//out back color

	QPainter painter(pix);
	painter.setPen(black);
	
	painter.drawRect(0,0,w,h);
	
    	
	painter.setBrush(config->readColorEntry("Process Done Color", &Qt::darkGreen));//out done color
	painter.setPen(config->readColorEntry("Process Left Color", &Qt::white));//out left color

	painter.drawRect(1,1,(int)(((float)pix->width()-2)/ 100 * (percentDone)),pix->height()-2);
	thisItem->setPixmap ( PROGRESS_COL, *pix );
	thisItem->setText( PROGRESS_COL, QString::number(percentDone) + "% " + optMess);

	painter.end();
	delete pix;
	
	if(outputView->verticalScrollBar()->value() == outputView->verticalScrollBar()->maxValue())
		outputView->ensureItemVisible(thisItem);
	else{
		if(firstMove){
			outputView->ensureItemVisible(thisItem);
			firstMove = false;
		}
	}
	
/*	if(percentDone == 100 && processesDone < totalToProcess){
		processesDone++;
		outputView->lastChild()->itemAbove()->setText(PROGRESS_COL, i18n(
			"Reading track " + QString::number(processesDone) +
			" of " + QString::number(totalToProcess) + ", percent done:"));
	}*/
		
}
//=======================================

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// TIMER    /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//---------------------------------------------------------------------------------------------
void DialogCntPnl::startForwardTimer(){
	eTimeId = startTimer(1000);
	timer.start();
}
//---------------------------------------------------------------------------------------------
void DialogCntPnl::timerEvent(QTimerEvent *event){
	if(event->timerId() == eTimeId){
		int i = timer.elapsed() / 1000;
		if(i < 59)
			eTimeLbl->setText(" " + QString::number( i ) + i18n(" sec"));
		else
			eTimeLbl->setText(" " + QString::number( i / 60 ) + i18n(" min ") +
				QString::number( i % 60 ) + i18n(" sec"));
		return;
	}
	if(event->timerId() == staTimeId){
		QString msg = statusLbl->text();
		if(dotCount == 7){
			dotCount = 0;
			statusLbl->setText( msg.left(msg.length() - 7));
			return;
		}
		dotCount++;
		statusLbl->setText( msg + "." );
		return;
	}
	if(event->timerId() == procTimeId){
		percentDone++;
		updateProgress(percentDone, progressItem);
	}
}
//---------------------------------------------------------------------------------------------
void DialogCntPnl::status(QString msg) {
	if(msg.find(i18n("Ready")) == -1){
		if(msg.find("...", msg.length() - 3) != -1)
			msg = msg.left(msg.length() - 3) + " ";
		dotCount = 0;
		staTimeId = startTimer(400);
		timer.start();
	}
	else
		killTimer(staTimeId);
	statusLbl->setText( msg );
}
//---------------------------------------------------------------------------------------------
void DialogCntPnl::stopForwardTimer(){
	killTimer(eTimeId);
	killTimer(procTimeId);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// DUMP    /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//===============================================
void DialogCntPnl::dumpSlot(){
	if(!outputView->firstChild())
		return;
    QString fileToOpen = KFileDialog::getSaveFileName(QDir::homeDirPath(),
				"*|All files",
				this,
				i18n("Save Process Output As..."));
	if(!fileToOpen || fileToOpen == "")
		return;
	QFile file(fileToOpen);
	
	if(file.exists())
		file.remove();
	if(!file.open(IO_ReadWrite))
		return;
		
	QTextStream stream(&file);
	for(QListViewItem *i = outputView->firstChild(); i; i = i->nextSibling()){
		stream << i->text(PROGRESS_COL);
		stream << "\n";
	}
	file.close();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// SLOTS/EVENTS   /////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
 *  Main event handler. Reimplemented to handle application
 *  font changes
 */
bool DialogCntPnl::event( QEvent* ev )
{
    bool ret = QWidget::event( ev );
    if ( ev->type() == QEvent::ApplicationFontChange ) {
	QFont startBtn_font(  startBtn->font() );
	startBtn_font.setBold( TRUE );
	startBtn->setFont( startBtn_font );
	QFont cancelBtn_font(  cancelBtn->font() );
	cancelBtn_font.setBold( TRUE );
	cancelBtn->setFont( cancelBtn_font );
	QFont settingsBtn_font(  settingsBtn->font() );
	settingsBtn_font.setBold( TRUE );
	settingsBtn->setFont( settingsBtn_font );
	QFont dumpBtn_font(  dumpBtn->font() );
	dumpBtn_font.setBold( TRUE );
	dumpBtn->setFont( dumpBtn_font );
	QFont helpBtn_font(  helpBtn->font() );
	helpBtn_font.setBold( TRUE );
	helpBtn->setFont( helpBtn_font );
	QFont quitBtn_font(  quitBtn->font() );
	quitBtn_font.setBold( TRUE );
	quitBtn->setFont( quitBtn_font );
    }
    return ret;
}
/////////// SLOTS ////////////////////////////////////////////////////////////////////////////////
void DialogCntPnl::settingsSlot()
{
    qWarning( "DialogCntPnl::settingsSlot(): Not implemented yet!" );
}
//===============================================
void DialogCntPnl::cancelSlot(){
    qWarning( "DialogCntPnl::cancelSlot(): Not implemented yet!" );
}
//===============================================
void DialogCntPnl::helpSlot(){
    qWarning( "DialogCntPnl::helpSlot(): Not implemented yet!" );
}
//===============================================
void DialogCntPnl::quitSlot(){
    qWarning( "DialogCntPnl::quitSlot(): Not implemented yet!" );
}
//===============================================
void DialogCntPnl::startSlot(){
    qWarning( "DialogCntPnl::startSlot(): Not implemented yet!" );
}
