/*****************************************************************************
 *
 *  miniconsolewidget.cpp -- Mini console for command line task output.
 * 
 *  Copyright (C) 2010 Starbuck <starbuck@labdv.com>
 *  All rights reserved.
 *
 *  This file is part of the Gui4 module of the DVDx 4 application.
 *
 *  GNU Lesser General Public License Usage
 *  This file may be used under the terms of the GNU Lesser General
 *  Public License version 2.1 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.LGPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU Lesser General Public License version 2.1 requirements
 *  will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 *  GNU General Public License Usage
 *  Alternatively, this file may be used under the terms of the GNU
 *  General Public License version 3.0 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.GPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU General Public License version 3.0 requirements will be
 *  met: http://www.gnu.org/copyleft/gpl.html.
 *
 *****************************************************************************/

#include "miniconsolewidget.h"
#include "infoboxdialog.h"

MiniConsoleWidget::MiniConsoleWidget(ConsoleDialog *console, QWidget *parent)
	: QWidget(parent),
	task(0), noStateDisplay(false), totalTime(0.0), removable(false)
{
	QString name = console->getName();
	QString title = console->getTitle();
	QString engine = console->getEngine();
	int pid = console->getPidNumber();

	this->console = console;
	task = console->getTask();

	miniConsoleGroup = new QWidget;
	miniConsoleLayout = new QHBoxLayout(miniConsoleGroup);

	miniConsoleGroup->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );

	stateDisplay = new QPushButton;
	showConsoleButton = new QPushButton;
	taskTitle = new QLabel;
	progress = new QProgressBar;

	progress->setRange(0,100);

	stateDisplay->setIcon(QIcon(":/gui4/images/running.png"));
	stateDisplay->setFlat(true);

	taskTitle->setText( tr("%1").arg(name) );
	taskTitle->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );

	showConsoleButton->setIcon(QIcon(":/gui4/images/console.png"));
	showConsoleButton->setToolTip( tr("Show/Hide process console") );
	showConsoleButton->setFlat(true);
	
	if ( pid != 0 )
	{
		taskTitle->setToolTip( tr("%1 running with PID %2").arg(engine).arg(pid) );
		stateDisplay->setDisabled(false);
		stateDisplay->setToolTip( tr("Running, click to abort") );
		showConsoleButton->setDisabled(false);
	}
	else
	{

		taskTitle->setToolTip( tr("Waiting") );
		stateDisplay->setDisabled(true);
		stateDisplay->setToolTip( tr("Waiting") );
		showConsoleButton->setDisabled(true);

	}

	miniConsoleLayout->addWidget(stateDisplay);
	miniConsoleLayout->addWidget(taskTitle);
	miniConsoleLayout->addWidget(progress);
	miniConsoleLayout->addWidget(showConsoleButton);
	
	connect( stateDisplay, SIGNAL(clicked()), this, SLOT(clickProcess()) );
	connect( showConsoleButton, SIGNAL(clicked(bool)), this, SLOT(showConsole(bool)) );
	connect( console, SIGNAL(progressUpdated(int, double, int, int)),
		this, SLOT(displayProgress(int, double, int, int)) );
	connect( console, SIGNAL(progressUpdated()), this, SLOT(displayProgress()) );

	QHBoxLayout *mainLayout = new QHBoxLayout(this);
	//mainLayout->setContentsMargins(2,2,2,2);
	mainLayout->setContentsMargins(0,0,0,0);
	mainLayout->addWidget(miniConsoleGroup);

	//setContentsMargins(2,2,2,2);
	setContentsMargins(0,0,0,0);
}

MiniConsoleWidget::~MiniConsoleWidget()
{
	if (console) delete(console);
}

void MiniConsoleWidget::setNoStateDisplay(bool readOnly) 
{ 
	noStateDisplay = readOnly; 

	if ( readOnly )
	{
		disconnect( stateDisplay, SIGNAL(clicked()), 0, 0 );
		stateDisplay->setVisible(false);
	}
	else
	{
		disconnect( stateDisplay, SIGNAL(clicked()), 0, 0 );
		connect( stateDisplay, SIGNAL(clicked()), this, SLOT(clickProcess()) );
		stateDisplay->setVisible(true);
	}
}

void MiniConsoleWidget::setNoConsoleButton(bool noConsole) 
{ 
	showConsoleButton->setVisible(!noConsole);
}

void MiniConsoleWidget::showConsole(bool)
{
	console->setVisible( !console->isVisible() );
}

void MiniConsoleWidget::clickProcess()
{
	if ( task->getState() == Task::Running )
	{
		emit requestToAbort(this);
	}
	else if ( task->getState() != Task::Waiting )
	{
		emit requestToRemove(this);
	}
}

void MiniConsoleWidget::displayProgress(int frame, double time, int percent, int size)
{
	changeStateDisplay();

	if ( (frame > 0 || size > 0) && percent == -1 && totalSize > 0 ) 
	{
		double sizePercent = double(size) / double(totalSize) * 100.0 + 1.0; // round >99.0 to 100
		percent = (int)sizePercent;
		if (percent > 100) percent = 100;
		progress->setValue( percent );
	}
	else if ( frame > 0 && totalFrame > 0 ) 
	{
		double framePercent = double(frame) / double(totalFrame) * 100.0 + 1.0; // round >99.0 to 100
		percent = (int)framePercent;
		if (percent > 100) percent = 100;
		progress->setValue( percent );
	}
	else if ( (frame > 0 || size > 0) && percent == -1 && totalTime > 0.0 && time > 0.0 ) 
	{
		double timePercent = (time) / totalTime * 100.0 + 1.0; // round >99.0 to 100
		percent = (int)timePercent;
		if (percent > 100) percent = 100;
		progress->setValue( percent );
	}
	else if (percent > -1)
	{
		progress->setValue(percent);
	}
}

void MiniConsoleWidget::displayProgress()
{
	changeStateDisplay();
}

void MiniConsoleWidget::changeStateDisplay()
{
	Task::State state = task->getState();
	QString engine = ((ConsoleDialog *)task->getConsole())->getEngine();
	int pid = task->getPidNumber();

	switch (state)
	{
	case Task::Waiting:
		stateDisplay->setDisabled(true);
		stateDisplay->setIcon(QIcon(":/gui4/images/running.png"));
		stateDisplay->setToolTip( tr("Waiting") );
		taskTitle->setToolTip( tr("Waiting") );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(true);
		break;
	case Task::Running:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/running.png"));
		stateDisplay->setToolTip( tr("Running, click to abort") );
		if (pid) taskTitle->setToolTip( tr("%1 running with PID %2").arg(engine).arg(pid) );
		progress->setDisabled(false);
		showConsoleButton->setDisabled(false);
		break;
	case Task::Terminated:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/running.png"));
		stateDisplay->setToolTip( tr("Process terminated, click to remove") );
		taskTitle->setToolTip( tr("%1 process terminated").arg(engine) );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(false);
		break;
	case Task::Done:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/done.png"));
		stateDisplay->setToolTip( tr("Process completed, click to remove") );
		taskTitle->setToolTip( tr("%1 process completed").arg(engine) );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(false);
		break;
	case Task::StartFailure:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/aborted.png"));
		stateDisplay->setToolTip( tr("Failed to start, click to remove") );
		taskTitle->setToolTip( tr("%1 process failed to start").arg(engine) );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(true);
		break;
	case Task::Aborted:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/aborted.png"));
		stateDisplay->setToolTip( tr("Aborted, click to remove") );
		taskTitle->setToolTip( tr("%1 process aborted").arg(engine) );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(false);
		break;
	case Task::Cancelled:
		stateDisplay->setDisabled(false);
		stateDisplay->setIcon(QIcon(":/gui4/images/aborted.png"));
		stateDisplay->setToolTip( tr("Cancelled, click to remove") );
		taskTitle->setToolTip( tr("%1 process cancelled").arg(engine) );
		progress->setDisabled(true);
		showConsoleButton->setDisabled(true);
		break;
	}
}
