/*
 * Cueplot: a GUI front-end to gnuplot
 * Copyright (C) 2007 Muneyuki Noguchi
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "Process.h"
#include "ConsoleDialog.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QSettings>
#include <QtCore/QTextCodec>
#include <QtGui/QFileDialog>
#include <QtGui/QMessageBox>

const QString Process::FILE_NAME =
#ifdef Q_OS_WIN32
		// Windows の場合は、pgnuplot.exe を介して wgnuplot.exe を起動
		"pgnuplot.exe";
#else
		// それ以外は実行可能ファイル gnuplot を起動
		"gnuplot";
#endif

Process::Process(QObject *parent)
: QObject(parent), process(new QProcess)
{
	if (!startProcess()) {
		QMessageBox::critical(0, QCoreApplication::applicationName(),
				tr("Gnuplot could not be started"));
		exit(1);
	}
	connect(process, SIGNAL(readyReadStandardError()),
			this, SLOT(readStandardError()));

	consoleDialog = new ConsoleDialog;
}

bool Process::startProcess()
{
	// 設定ファイルから gnuplot のバスを読み込むことを試みる
	QSettings settings;
	settings.beginGroup("Process");
	QString path = settings.value("path").toString();
	settings.endGroup();

	// 1st attempt
	if (!path.isEmpty() && canStart(path)) {
		return true;
	}

	path = FILE_NAME;

	// 2nd attempt
	if (canStart(path)) {
		return true;
	}

	// ユーザにダイアログで gnuplot の場所を指定させる
	path = QFileDialog::getOpenFileName(0, 
			tr("Open gnuplot") + " - "
			+ QCoreApplication::applicationName(), QString(),
			"gnuplot (" + path + ")");

	// 3rd attempt
	if (path.isNull()) {
		return false;
	}
	return canStart(path);
}

bool Process::canStart(const QString &path)
{
	process->start(path, QStringList());
	if (process->waitForStarted()) {
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
		// 標準入力が端末ではないとき x11 マウスのサポートはオフにされるので
		// 起動直後にオンにする
		process->write("set mouse\n");
#endif
		// 起動に成功したらパスを設定ファイルに保存
		QSettings settings;
		settings.beginGroup("Process");
		if (path != settings.value("path").toString()) {
			settings.setValue("path", path);
		}
		settings.endGroup();
		return true;
	} 
	return false;
}

void Process::execute(const QString &command)
{
	// コマンドに改行文字を追加し、日本語などが使えるように
	// デフォルトエンコーディングに変換して実行する
	process->write(QTextCodec::codecForLocale()
			->fromUnicode(command).append('\n'));
	consoleDialog->execute(command);
}

void Process::readStandardError()
{
	// エラーが出力された場合は
	// エラーメッセージを表示するダイアログをユーザに見せる
	consoleDialog->show();
	consoleDialog->raise();
	consoleDialog->activateWindow();
	consoleDialog->readStandardError(process->readAllStandardError());
}

void Process::closeDialog()
{
	consoleDialog->close();
}

void Process::setDialogVisible(bool visible)
{
	consoleDialog->setVisible(visible);
}

bool Process::isDialogVisible()
{
	return consoleDialog->isVisible();
}
