#include <QtGui>
#include "qiph.h"

#ifndef VERSION
#define VERSION 0.2.1
#endif

#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#define VERSIONSTRING STR(VERSION)

qXiph::qXiph(QWidget* parent)
  : Ui::QXiphMainWindow()
{
  setupUi(this);
	edited_mount = false;
	edited_title = false;

	connect(toolButton_file, SIGNAL(clicked()), this, SLOT(open_file()));
	connect(pushButton_doit, SIGNAL(toggled(bool)), this, SLOT(do_stream(bool)));
	connect(toolButton_about, SIGNAL(clicked()), this, SLOT(show_about()));
 //connect(actionQuit, SIGNAL(triggered()), this, SLOT(quit_triggered()));

	ftf = new QProcess();
	connect(ftf, SIGNAL(readyReadStandardOutput()), this, SLOT(ftfReadFromStdout()));
	connect(ftf, SIGNAL(readyReadStandardError()), this, SLOT(ftfReadFromStderr()));
	connect(ftf, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(ftfFinished()));

	connect(lineEdit_title, SIGNAL(editingFinished()), this, SLOT(custom_edit_title()));
	connect(lineEdit_icmount, SIGNAL(editingFinished()), this, SLOT(custom_edit_mount()));

	connect(lineEdit_file, SIGNAL(editingFinished()), this, SLOT(update_titles()));

	lineEdit_ifps->setValidator(new QIntValidator(1,1000,lineEdit_ifps));
	//lineEdit_ifps->setValidator(new QRegExpValidator(QRegExp("[0-9.:]*"), lineEdit_ifps));
	lineEdit_ofps->setValidator(new QIntValidator(1,1000,lineEdit_ofps));
	lineEdit_sw->setValidator(new QIntValidator(32,8192,lineEdit_sw));
	lineEdit_sh->setValidator(new QIntValidator(32,8192,lineEdit_sh));
	lineEdit_icport->setValidator(new QIntValidator(1,65536,lineEdit_icport));
	lineEdit_icmount->setValidator(new QRegExpValidator(QRegExp("[a-zA-Z0-9\\._-]*"), lineEdit_icmount));

#ifdef VERSION
	label_copy->setText("qiph " VERSIONSTRING " - (C) 2011 GPL <robin@gareus.org>");
#else
	label_copy->setText("qiph - (C) 2011 GPL <robin@gareus.org>");
#endif
	update_onair(false);
}

qXiph::~qXiph()
{
  ;
}

void qXiph::quit_triggered() 
{
  close();
}

void qXiph::show_about() 
{
  QMessageBox about;
	about.setWindowTitle("qiph");
	about.setTextFormat(Qt::PlainText);
	about.setWindowModality(Qt::ApplicationModal);
#ifdef __APPLE__
	about.setFont(QFont("Times New Roman", 11, -1, false));
#endif
	about.setText(
		"qiph - QT GUI for XIPH codecs\n\n"
		"qiph is a wrapper around ffmpeg2theora and oggfwd;\n"
		"in other words: A cross-platform front-end to transcode audio/video\n"
		"and send it to an icecast or shoutcast server.\n"
		"\n"
		"Many thanks to Jan Gerber <j@v2v.cc> - author of ffmpeg2theora and\n"
		"oggfwd - and kudos to the XIPH foundation.\n"
		"\n"
		"http://gareus.org/oss/qiph/\n"
		"(C) 2011 Robin Gareus <robin@gareus.org>\n"
		"\n"
    "This program is free software; you can redistribute it and/or modify\n"
    "it under the terms of the GNU General Public License as published by\n"
    "the Free Software Foundation; either version 2 of the License, or\n"
    "(at your option) any later version.\n"
		"\n"
    "This program is distributed in the hope that it will be useful,\n"
    "but without any warranty; without even the implied warranty of\n"
    "merchantability or fitness for a particular purpose.  See the\n"
    "GNU General Public License for more details.\n"
	);
	about.exec();
}

void qXiph::custom_edit_title() 
{
 edited_title= true;
}

void qXiph::custom_edit_mount() 
{
 edited_mount= true;
}

void qXiph::open_file() 
{
	static QString prevdir = "";
	QString s = QFileDialog::getOpenFileName(this, tr("Choose audio or video file"), prevdir, 0);
	if(!s.isNull()) {
		QFileInfo fi(s);
		lineEdit_file->setText(s);
		update_titles();
		prevdir=fi.absolutePath();
	}
}

void qXiph::update_titles() 
{
	QString s = lineEdit_file->text();
	if (s.isEmpty()) return;
	QFileInfo fi(s);
	QString bn = fi.baseName();
	if (!edited_title) 
		lineEdit_title->setText(bn);
	if (!edited_mount) {
		bn.replace(QRegExp("[^a-zA-Z0-9\\._-]"), "_");
		lineEdit_icmount->setText(bn.append(".ogg"));
	}
}

void qXiph::do_stream(bool en) 
{
	if (en) {
		launch_ftf();
	} else {
		ftf->close();
	}

}

#ifdef __APPLE__
# define FTF_SCRIPT QApplication::applicationDirPath() + "/../Resources/fftheofwd.sh"
#elif (defined WIN32)
# define FTF_SCRIPT QApplication::applicationDirPath() + "\\fftheofwd.bat"
#elif (defined PREFIX)
# define FTF_SCRIPT PREFIX "/share/qiph/fftheofwd.sh"
#else
# define FTF_SCRIPT QApplication::applicationDirPath() + "/misc/fftheofwd.sh"
#endif

void qXiph::launch_ftf() 
{
  logmsg->setText("");

	groupBox_1->setEnabled(false);
	groupBox_2->setEnabled(false);
	tabWidget->setEnabled(false);

	QStringList args;
	args << lineEdit_file->text();
	args << lineEdit_title->text();
	args << lineEdit_author->text();
	args << lineEdit_desc->text();
	args << QString::number(horizontalSlider_vq->value());
	args << QString::number(horizontalSlider_vs->value());
	args << QString::number(horizontalSlider_aq->value());
	args << lineEdit_ichost->text();
	args << lineEdit_icport->text();
	args << lineEdit_icpass->text();
	args << lineEdit_icmount->text();
	if (checkBox_pub->isChecked()) { args << "-p"; } else { args << " "; }

	args << lineEdit_xmo->text(); // organization
	args << lineEdit_xmd->text(); // date
	args << lineEdit_xml->text(); // location
	args << lineEdit_xmg->text(); // genre
	args << lineEdit_xmc->text(); // copyright
	args << lineEdit_xme->text(); // contact
	args << lineEdit_xmi->text(); // license

	if (checkBox_ifps->isChecked()) { 
		args << "--inputfps"; 
		args << lineEdit_ifps->text();
	} 
	if (checkBox_ofps->isChecked()) { 
		args << "-F"; 
		args << lineEdit_ofps->text();
	} 
	if (checkBox_sw->isChecked()) { 
		args << "-x"; 
		args << lineEdit_sw->text();
	}
	if (checkBox_sh->isChecked()) { 
		args << "-y"; 
		args << lineEdit_sh->text();
	}

	args.replaceInStrings("\"", "_");
	args.replaceInStrings("\n", "_");
	args.replaceInStrings("\r", "_");

	ftf->start(FTF_SCRIPT, args, QIODevice::ReadOnly);
	ftf->waitForStarted();
	if (ftf->state() != QProcess::Running) {
		update_onair(false);
		ftfFinished();
	} else {
		update_onair(true);
	}
}

void qXiph::update_onair(bool onair)
{
	if (onair) {
		label_onair->setText("ON-AIR");
		pushButton_doit->setText("Stop Streaming");
	} else {
		label_onair->setText("");
	  pushButton_doit->setChecked(false);
		pushButton_doit->setText("Encode and Stream");
	}
}

void qXiph::ftfReadFromStdout() 
{
  while(ftf->canReadLine()) {
		QString response = ftf->readLine().replace("\r","\n").trimmed();
		qDebug(QString("ResponseLine: '" + response+ "'").toAscii().data());
		if (!response.isEmpty())
			logmsg->setText(response);
	}
}

void qXiph::ftfReadFromStderr() 
{
	QByteArray err = ftf->readAllStandardError().replace("\r","\n").trimmed();
	if (!err.isEmpty())
		logmsg->setText(err);
}

void qXiph::ftfFinished() 
{
	ftf->terminate();
	ftf->kill();

	groupBox_1->setEnabled(true);
	groupBox_2->setEnabled(true);
	tabWidget->setEnabled(true);
	if (checkBox_loop->isChecked() && pushButton_doit->isChecked()) {
		launch_ftf();
	} else {
		update_onair(false);
	}
}
