
#include <qlistbox.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qcombobox.h>
#include <qpushbutton.h>
#include <qradiobutton.h>

#include <cpuinfo.h>
#include <configfile.h>

#include "genctl.h"
#include "recwnd.h"
#include "codecconf.h"
#include "audc.h"
#include "conf.h"

#include <iostream.h>
using namespace std;
using namespace Registry;

/*
 *  Constructs a QtRecompressorCtl which is a child of 'parent', with the 
 *  name 'name' and widget flags set to 'f' 
 */
QtRecompressorCtl::QtRecompressorCtl( QWidget* parent )
    : QtRecompressor( parent, "Qt recompressor", 0 )
{
    kernel=new RecKernel;
    wnd=0;
    ictl=0;
    no_recurs=0;

    connect(_lbFilters, SIGNAL(doubleClicked( QListBoxItem * )), this, SLOT(config_filter_clicked()));
    
    connect(_lineLowFrames, SIGNAL(textChanged(const QString&)), this, SLOT(lo_fr_changed(const QString&)));
    connect(_lineHighFrames, SIGNAL(textChanged(const QString&)), this, SLOT(hi_fr_changed(const QString&)));
    connect(_lineLowSec, SIGNAL(textChanged(const QString&)), this, SLOT(lo_sec_changed(const QString&)));
    connect(_lineHighSec, SIGNAL(textChanged(const QString&)), this, SLOT(hi_sec_changed(const QString&)));
    updateFilters();
}

/*  
 *  Destroys the object and frees any allocated resources
 */
QtRecompressorCtl::~QtRecompressorCtl()
{
    //cout << "QtRecompressorCtl::~QtRecompressorCtl()" << endl;
    delete kernel;
    delete wnd;
    // no need to delete child widgets, Qt does it all for us
}

/* 
 * public slot
 */
void QtRecompressorCtl::about_filter_clicked()
{
    Filter* fi=kernel->getFilter(_lbAllFilters->currentItem());
    if(!fi)return;
    fi->about();
    fi->release();
}
/* 
 * public slot
 */

void QtRecompressorCtl::updateFilters()
{
    _lbFilters->clear();
    _lbAllFilters->clear();
    int i;
    for(i=0;;i++)
    {
	Filter* fi=kernel->getFilter(i);
	if(!fi)break;
	_lbAllFilters->insertItem(fi->name().c_str());
	fi->release();
    }
    for(i=0;;i++)
    {
	Filter* fi=kernel->getFilterAt(i);
	if(!fi)break;
	_lbFilters->insertItem(fi->fullname().c_str());
	fi->release();
    }    
}
void QtRecompressorCtl::add_filter_clicked()
{
    Filter* fi=kernel->getFilter(_lbAllFilters->currentItem());
    if(!fi)return;
    int id=kernel->addFilter(fi);
    fi->release();
    updateFilters();
}
/* 
 * public slot
 */
void QtRecompressorCtl::config_filter_clicked()
{
    Filter* fi=(*kernel)[_lbFilters->currentItem()];
    if(!fi)return;
    fi->config();
    fi->release();
    updateFilters();
}
/* 
 * public slot
 */
void QtRecompressorCtl::dest_file_clicked()
{
    QString result=QFileDialog::getSaveFileName(Registry::ReadString("QtRecomp", "SaveFile", "./dest.avi").c_str());
    if(result.isNull())
	return;
    if(kernel->setDestFile(result.ascii())!=0)
	return;
    Registry::WriteString("QtRecomp", "SaveFile", result.ascii());
    _txtDst->setText(result);
}
/* 
 * public slot
 */
void QtRecompressorCtl::details_clicked()
{
    string details=kernel->aboutStream(_comboStreams->currentItem());
    QMessageBox::information(this, "About stream", details.c_str());
}
/* 
 * public slot
 */
void QtRecompressorCtl::down_filter_clicked()
{
    kernel->moveDownFilter(_lbFilters->currentItem());
    updateFilters();
}
/* 
 * public slot
 */
void QtRecompressorCtl::load_config_clicked()
{
    QString result=QFileDialog::getOpenFileName(Registry::ReadString("QtRecomp", "OpenConf", "./test.conf").c_str());
    if(result.isNull())return;
    try
    {
	kernel->loadConfig(result.ascii());
	Registry::WriteString("QtRecomp", "OpenConf", result.ascii());
	
	_txtSrc->setText(kernel->getSrcFile());
	_txtDst->setText(kernel->getDestFile());
	_txtConfig->setText(result.ascii());

        _comboStreams->clear();
	for(unsigned i = 0; i < kernel->getStreamCount(); i++)
	    _comboStreams->insertItem(kernel->getStreamName(i).c_str());
        stream_selected(0);
//    kernel->setStreamMode(
        _comboStreams->setCurrentItem(0);
	RecKernel::KernelMode mode;
	if (kernel->getStreamMode(0, mode) == 0)
	    stream_mode_changed(mode);
	updateFilters();
/*   switch(mode)
	    {
	    case Ignore:
		RadioButton55->setChecked(true);
		break;
	    case Copy:
		RadioButton55_2->setChecked(true);
		break;
	    case Recompress:
		RadioButton55_3->setChecked(true);
		break;
	    }
	}    */
        RadioButton5->setChecked(true);
        stream_limit_mode_changed(0);
//	stream_mode_changed(0);
        if(!wnd)
        {
	    ictl=new QImageControl(0);
	    ictl->show();
	    kernel->setImageControl(ictl);
    	    wnd=new SourceControlWnd(0, kernel);
	    wnd->show();
	}	
	else
	{
	    kernel->setImageControl(ictl);
	    wnd->update_size();
	}
    }
    catch(FatalError& e)
    {
	QMessageBox::information(this, e.GetModule(), e.GetDesc());
    }
}
/* 
 * public slot
 */
void QtRecompressorCtl::remove_filter_clicked()
{
    kernel->removeFilter(_lbFilters->currentItem());
    updateFilters();
}
/* 
 * public slot
 */
void QtRecompressorCtl::save_config_clicked()
{
    QString result=QFileDialog::getSaveFileName(Registry::ReadString("QtRecomp", "OpenConf", "./test.conf").c_str());
    if(result.isNull())return;
    try
    {
	kernel->saveConfig(result.ascii());
	Registry::WriteString("QtRecomp", "OpenConf", result.ascii());
         _txtConfig->setText(result.ascii());
    }
    catch(FatalError& e)
    {
	QMessageBox::information(this, e.GetModule(), e.GetDesc());
    }
}
/* 
 * public slot
 */
void QtRecompressorCtl::src_file_clicked()
{
    QString result=QFileDialog::getOpenFileName(Registry::ReadString("QtRecomp", "OpenFile", "./movie.avi").c_str());
    if(result.isNull())
	return;
    if(kernel->openFile(result.ascii())!=0)
	return;
    Registry::WriteString("QtRecomp", "OpenFile", result.ascii());
    _txtSrc->setText(result);
    
    _comboStreams->clear();
    for(unsigned i = 0; i < kernel->getStreamCount(); i++)
	_comboStreams->insertItem(kernel->getStreamName(i).c_str());
    stream_selected(0);
//    kernel->setStreamMode(
    _comboStreams->setCurrentItem(0);
    RadioButton55->setChecked(true);
    RadioButton5->setChecked(true);
    stream_limit_mode_changed(0);
    stream_mode_changed(0);
//    if(vs)
//    {
//	try
//	{
//	    v_str[0].stream->StartStreaming();
//	    v_str[0].stream->ReadFrame();	
	    if(!wnd)
	    {
    		ictl=new QImageControl(0);
	        ictl->show();
		kernel->setImageControl(ictl);
    		wnd=new SourceControlWnd(0, kernel);
	        wnd->show();
	    }	
	    else
	    {
		kernel->setImageControl(ictl);
	        wnd->update_size();
	    }
//	}
//	catch(FatalError& e)
//	{
//	    e.Print();
//	    kernel->setImageControl(0);
//	}
//    }		
}
/* 
 * public slot
 */
void QtRecompressorCtl::stream_format_clicked()
{
    int stream=_comboStreams->currentItem();
    VideoEncoderInfo info;
    AudioEncoderInfo ainfo;
    WAVEFORMATEX wfmtx;
    CodecConfig* config;
    AudioCodecConfig* ac;
    if(!kernel->isStream(stream))
	return;
    switch(kernel->stream_type(stream))
    {
    case AviStream::Video:
	if (kernel->getCompress(stream, info) != 0)
	    return;//shouldn't happen.
	config = new CodecConfig(this, info);
	if (config->exec() == QDialog::Accepted)
	    kernel->setCompress(stream, config->GetInfo());
	delete config;
	break;
    case AviStream::Audio:
	if (kernel->getAudioCompress(stream, ainfo) != 0)
	    return;//shouldn't happen.
	ac = new AudioCodecConfig(this, ainfo);
	if (ac->exec() == QDialog::Accepted)
	    kernel->setAudioCompress(stream, ac->GetInfo());
	delete ac;
        break;
    default:
        cout << "QtRecompressorCtl::stream_format_clicked() unsupported stream type" << endl;
    }
}
/* 
 * public slot
 */
void QtRecompressorCtl::stream_limit_mode_changed(int)
{
    if(RadioButton5->isChecked())
    {
	_lineLowSec->setEnabled(true);
	_lineHighSec->setEnabled(true);
	_lineLowFrames->setEnabled(false);
	_lineHighFrames->setEnabled(false);
    }
    else
    {
    	_lineLowSec->setEnabled(false);
	_lineHighSec->setEnabled(false);
	_lineLowFrames->setEnabled(true);
	_lineHighFrames->setEnabled(true);
    }
}
/* 
 * public slot
 */
void QtRecompressorCtl::stream_mode_changed(int)
{
    int stream=_comboStreams->currentItem();
    if(!kernel->isStream(stream))
	return;
    if(RadioButton55->isChecked())
    {
	_pushFormat->setEnabled(false);
	kernel->setStreamMode(stream, RecKernel::Remove);
	RadioButton5->setEnabled(false);
	RadioButton5_2->setEnabled(false);
	_lineLowSec->setEnabled(false);
	_lineHighSec->setEnabled(false);
	_lineLowFrames->setEnabled(false);
	_lineHighFrames->setEnabled(false);
    }	
    else
    if(RadioButton55_2->isChecked())
    {
    	_pushFormat->setEnabled(false);
	kernel->setStreamMode(stream, RecKernel::Copy);
	RadioButton5->setEnabled(true);
	RadioButton5_2->setEnabled(true);
	stream_limit_mode_changed(0);
    }	
    else
    {
    	_pushFormat->setEnabled(true);
	kernel->setStreamMode(stream, RecKernel::Recompress);
	RadioButton5->setEnabled(true);
	RadioButton5_2->setEnabled(true);
	stream_limit_mode_changed(0);
    }	
}
/* 
 * public slot
 */
void QtRecompressorCtl::stream_selected(int s)
{
    RecKernel::KernelMode mode;
    if(kernel->getStreamMode(s, mode)!=0)
	return;
    double start, end;
    switch(mode)
    {
	case RecKernel::Remove:
	    RadioButton55->setChecked(true);
	    break;
	case RecKernel::Copy:
	    RadioButton55_2->setChecked(true);
	    break;
	case RecKernel::Recompress:
	    RadioButton55_3->setChecked(true);
	    break;
    }
    stream_mode_changed(/*unused*/0);
    kernel->getSelection(s, start, end);
    char str[256];
    sprintf(str, "%d", int(start/kernel->getFrameTime(s)));
    _lineLowFrames->setText(str);
    sprintf(str, "%d", int(end/kernel->getFrameTime(s)));
    _lineHighFrames->setText(str);
    sprintf(str, "%.3f", start);
    _lineLowSec->setText(str);
    sprintf(str, "%.3f", end);
    _lineHighSec->setText(str);
}
/* 
 * public slot
 */
void QtRecompressorCtl::up_filter_clicked()
{
    kernel->moveUpFilter(_lbFilters->currentItem());
    updateFilters();
}

void QtRecompressorCtl::start_recompress()
{
    if (!wnd)
	return;
    wnd->hide();
    hide();
    RecWindow w(this, kernel);
    w.exec();
    cerr<<"Recompress finished"<<endl;
    wnd->show();
    show();
}

void QtRecompressorCtl::lo_fr_changed(const QString& s)
{
    if(no_recurs)return;
    int stream=_comboStreams->currentItem();
    if(!kernel->isStream(stream))
	return;
    char q[128];
    sprintf(q, "%f", atoi(s.ascii())*kernel->getFrameTime(stream));
    no_recurs=1;
    _lineLowSec->setText(q);
    no_recurs=0;
    kernel->setSelectionStart(stream, atoi(s.ascii())*kernel->getFrameTime(stream));
} 
void QtRecompressorCtl::hi_fr_changed(const QString& s)
{
    if(no_recurs)return;
    int stream=_comboStreams->currentItem();
    if(!kernel->isStream(stream))
	return;
    char q[128];
    sprintf(q, "%f", atoi(s.ascii())*kernel->getFrameTime(stream));
    no_recurs=1;
    _lineHighSec->setText(q);
    no_recurs=0;
    kernel->setSelectionEnd(stream, atoi(s.ascii())*kernel->getFrameTime(stream));
}
void QtRecompressorCtl::lo_sec_changed(const QString& s)
{
    if(no_recurs)return;
    int stream=_comboStreams->currentItem();
    if(!kernel->isStream(stream))
	return;
    if(kernel->getFrameTime(stream)==0)return;
    int start;
    char q[128];
    sprintf(q, "%d", start=int(atof(s.ascii())/kernel->getFrameTime(stream)));
    no_recurs=1;
    _lineLowFrames->setText(q);
    no_recurs=0;
    kernel->setSelectionStart(stream, atof(s.ascii()));
}
void QtRecompressorCtl::hi_sec_changed(const QString& s)
{
    if(no_recurs)return;
    int stream=_comboStreams->currentItem();
    if(!kernel->isStream(stream))
	return;
    if(kernel->getFrameTime(stream)==0)return;
    int end;
    char q[128];
    sprintf(q, "%d", end=int(atof(s.ascii())/kernel->getFrameTime(stream)));
    no_recurs=1;
    _lineHighFrames->setText(q);
    no_recurs=0;
    kernel->setSelectionEnd(stream, atof(s.ascii()));
}

#include "genctl.moc"
#include "genctl_p.moc"
