
#include <configfile.h>
#include <cstdio>

using namespace std;

#include <qcheckbox.h>
#include <qcombobox.h>
#include <qfont.h>
#include <qfontdialog.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qlistbox.h>
#include <qpushbutton.h>
#include <qslider.h>
#include <qspinbox.h>

#include "MyConfigImpl.h"
#include "mywidget.h"
#include <aviplay.h>

#include <math.h> //rint
extern MyWidget* m;
/*
 *  Constructs a MyConfigDialog_impl which is a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'
 *
 *  The dialog will by default be modeless, unless you set 'modal' to
 *  TRUE to construct a modal dialog.
 */
MyConfigDialog_impl::MyConfigDialog_impl( QWidget* parent,  const char* name, bool modal, WFlags fl )
    : MyConfigDialog( parent, name, modal, fl ), fontchange(false)
{
}

MyConfigDialog_impl::MyConfigDialog_impl()
    : MyConfigDialog(0, "Configuration", true), fontchange(false)
{
    IAviPlayer* p = m->GetPlayer();
    itemLast = 0;

    char* fs = 0;
    char* http_proxy = 0;
    float sub_async;
    int async_time_ms;
    int def_audio_stream;

    int audio_resampling_rate;
    int rate;
    bool audio_resampling;

    bool use_yuv;
    bool use_http_proxy;
    bool autorepeat;
    bool quality_auto;
    bool preserve_aspect;
    bool display_frame_pos;
    bool video_buffered;
    bool video_direct;
    bool video_dropping;


    p->Get(p->ASYNC_TIME_MS, &async_time_ms,
	   p->SUBTITLE_FONT, &fs,
	   p->SUBTITLE_ASYNC_TIME_MS, &sub_async,
	   p->DEFAULT_AUDIO_STREAM, &def_audio_stream,
	   p->HTTP_PROXY, &http_proxy,
	   p->USE_HTTP_PROXY, &use_http_proxy,
	   p->USE_YUV, &use_yuv,
	   p->AUDIO_RESAMPLING, &audio_resampling,
	   p->AUDIO_RESAMPLING_RATE, &audio_resampling_rate,
	   p->AUDIO_PLAYING_RATE, &rate,
	   p->AUTOREPEAT, &autorepeat,
	   p->VIDEO_QUALITY_AUTO, &quality_auto,
	   p->VIDEO_PRESERVE_ASPECT, &preserve_aspect,
	   p->DISPLAY_FRAME_POS, &display_frame_pos,
	   p->VIDEO_BUFFERED, &video_buffered,
	   p->VIDEO_DIRECT, &video_direct,
	   p->VIDEO_DROPPING, &video_dropping,
	   0);

    m_pAsyncSlider->setValue(int(m_fAsync*100.));
    onAsyncValChanged(0);

    if (fs)
    {
	m_defFont.setRawName(fs);
	free(fs);
    }


    string fname;
    if (!m_defFont.family().isNull())
	fname = m_defFont.family().ascii();

    char str[250];
    sprintf(str, "%s, %d pt%s%s",
	    fname.size() ? fname.c_str() : "default",
	    //m_defFont.family().ascii(),
	    m_defFont.pointSize(),
	    m_defFont.bold()?", bold":"",
	    m_defFont.italic()?", italic":"");

    m_pFontType->setText(str);
    m_pPreview->setFont(m_defFont);

    if (sub_async < 0)
    {
	m_pCheckBox->setChecked(true);
	sub_async*=-1;
    }
    else
	m_pCheckBox->setChecked(false);

    m_pSubAsyncMin->setValue(int(sub_async / 60));
    sub_async -= 60 * int(sub_async / 60);
    m_pSubAsyncSec->setValue(int(sub_async));

    m_pDefAudio->setValue(def_audio_stream);

    if (http_proxy)
    {
	if (strlen(http_proxy) > 0)
	    m_pProxyName->setText(http_proxy);
        free(http_proxy);
    }

    if (use_http_proxy)
    {
	m_pUseProxy->setChecked(true);
	m_pProxyName->setEnabled(true);
    }

    m_pHwaccel->setChecked(use_yuv);

    char b[50];
    sprintf(b, "%d", audio_resampling_rate);
    m_pAudioResamplingRate->lineEdit()->setText(b);

    for (int i = 0; frequencyList[i]; i++)
	if (frequencyList[i] == rate)
	    m_pAudioPlayingRate->setCurrentItem(i);

    m_pAudioResampling->setChecked(audio_resampling);
    onAudioResamplingToggled();

    m_pAutorepeat->setChecked(autorepeat);
    m_pQualityAuto->setChecked(quality_auto);
    m_pPreserveAspect->setChecked(preserve_aspect);
    m_pDisplayFramePos->setChecked(display_frame_pos);
    m_pVideoBuffered->setChecked(video_buffered);
    m_pVideoDirect->setChecked(video_direct);
    m_pVideoDropping->setChecked(video_dropping);


    int i = 0;
    std::vector<CodecInfo>::iterator it;
    int sel=0;
    m_pVideoList->clear();
    for(it = video_codecs.begin(); it != video_codecs.end(); it++)
    {
	if (it->direction & CodecInfo::Decode)
	{
	    m_pVideoList->insertItem(it->text.c_str());
	    //if (it->fourcc == info.compressor)
	    //    sel=i;
	    i++;
	}
    }

    i = 0;
    m_pAudioList->clear();
    for(it = audio_codecs.begin(); it != audio_codecs.end(); it++)
    {
	if (it->direction & CodecInfo::Decode)
	{
	    m_pAudioList->insertItem(it->text.c_str());
	    //if (it->fourcc == info.compressor)
	    //    sel=i;
	    i++;
	}
    }

    connect(m_pAsyncSlider, SIGNAL(valueChanged(int)), this, SLOT(onAsyncValChanged(int)));
    connect(m_pUseProxy, SIGNAL(clicked()), this, SLOT(onProxyToggled()));
    connect(m_pAudioResampling, SIGNAL(clicked()), this, SLOT(onAudioResamplingToggled()));
    connect(m_pFontButton, SIGNAL(clicked()), this, SLOT(onFont()));
    connect(m_pApply, SIGNAL(clicked()), this, SLOT(onApply()));
    connect(m_pOk, SIGNAL(clicked()), this, SLOT(onOk()));
    connect(m_pCancel, SIGNAL(clicked()), this, SLOT(onCancel()));

    connect(m_pVideoList, SIGNAL(selectionChanged(QListBoxItem*)), this, SLOT(onSelectionChanged(QListBoxItem*)));

    connect(m_pVideoList, SIGNAL(pressed(QListBoxItem*)), this, SLOT(onListPressed(QListBoxItem*)));
    connect(m_pVideoList, SIGNAL(clicked(QListBoxItem*)), this, SLOT(onListClicked(QListBoxItem*)));
    // 3.0
    //connect(m_pVideoList, SIGNAL(mouseButtonPressed(int, QListBoxItem*, const QPOint&)), this,
    //        SLOT(onMouseButtonPressed(int, QListBoxItem*, const QPOint& )));
}

/*
 *  Destroys the object and frees any allocated resources
 */
MyConfigDialog_impl::~MyConfigDialog_impl()
{
    // no need to delete child widgets, Qt does it all for us
}

void MyConfigDialog_impl::onSelectionChanged(QListBoxItem* item)
{
    if (!inswap && pressed && itemLast && itemLast != item)
    {
        inswap = true;
	QListBox* lb = item->listBox();
	string t = item->text().ascii();
        int i = lb->index(item);
	string tlast = itemLast->text().ascii();
        int ilast = lb->index(itemLast);
	if (i >= 0 && ilast >= 0)
	{
	    // swap two items
	    cout << "swap " << t << "   " << tlast << endl;
	    cout << "idx1 " << i << "  idx2 " << ilast << endl;
	    if (ilast < i)
	    {
		lb->removeItem(i);
		lb->insertItem(t.c_str(), ilast);
	    }
	    else
	    {
		lb->removeItem(ilast);
		lb->insertItem(tlast.c_str(), i);

	    }
	    itemLast = item;
	}
        inswap = false;
    }

}

void MyConfigDialog_impl::onListPressed(QListBoxItem* item)
{
    //cout << "Onpres " << item->text() << endl;
    pressed = true;
    inswap = false;
    //QListBox* b = item->listBox();
    itemLast = item;
}

void MyConfigDialog_impl::onListClicked(QListBoxItem* item)
{
    //cout << "Onclic " << item->text() << endl;
    pressed = false; // no item movment
}

void MyConfigDialog_impl::onMouseButtonPressed(int button, QListBoxItem* item, const QPoint& pos)
{
    cout << "Onmouse " << button << " " << item->text() << endl;
}

void MyConfigDialog_impl::onProxyToggled()
{
    m_pProxyName->setEnabled(m_pUseProxy->isChecked());
}

void MyConfigDialog_impl::onAudioResamplingToggled()
{
    bool s = m_pAudioResampling->isChecked();
    m_pAudioResamplingRate->setEnabled(s);
    m_pAudioPlayingRate->setEnabled(s);
}

void MyConfigDialog_impl::onApply()
{
    IAviPlayer* p = m->GetPlayer();

    p->Set(p->USE_YUV, m_pHwaccel->isChecked(), 0);

    float async = (float)m_pAsyncSlider->value();




    if (fontchange && m_defFont.rawName().ascii())
    {
	//cout << "WRITEFONT " << m_defFont.rawName().ascii() << endl;
	string fn = m_defFont.rawName().ascii();
        if (fn[fn.size() - 1] == '1')
	    fn[fn.size() - 1] = '*';
	//cout << fn[n] << "  (1):" << fn[n-1] << "  (2):" << fn[n-2] << endl;
	p->Set(IAviPlayer::SUBTITLE_FONT, fn.c_str(), 0);
    }
    float sub_async = m_pSubAsyncMin->value()*60 + m_pSubAsyncSec->value();
    if (m_pCheckBox->isChecked())
	sub_async*=-1;

    string vcodecs;
    string acodecs;

    for (unsigned i = 0; i < m_pVideoList->count(); i++)
    {
	if (vcodecs.size() > 0)
	    vcodecs += ",";
        vcodecs += m_pVideoList->text(i);
    }

    for (unsigned i = 0; i < m_pAudioList->count(); i++)
    {
	if (acodecs.size() > 0)
	    acodecs += ",";
        acodecs += m_pVideoList->text(i);
    }

    cout << "V: " << vcodecs << endl;
    cout << "A: " << acodecs << endl;

    p->Set(p->ASYNC_TIME_MS, int(async * 10),
	   p->SUBTITLE_ASYNC_TIME_MS, int(sub_async * 1000),
	   p->USE_YUV, m_pHwaccel->isChecked(),
	   p->DEFAULT_AUDIO_STREAM, m_pDefAudio->value(),
	   p->AUDIO_RESAMPLING, m_pAudioResampling->isChecked(),
	   p->AUDIO_RESAMPLING_RATE,
             atoi(m_pAudioResamplingRate->lineEdit()->text().ascii()),
	   p->AUDIO_PLAYING_RATE,
	     frequencyList[m_pAudioPlayingRate->currentItem()],
	   p->USE_HTTP_PROXY, m_pUseProxy->isChecked(),
	   p->HTTP_PROXY, m_pProxyName->text().ascii(),
	   p->DISPLAY_FRAME_POS, m_pDisplayFramePos->isChecked(),
	   p->AUTOREPEAT, m_pAutorepeat->isChecked(),
	   p->VIDEO_PRESERVE_ASPECT, m_pPreserveAspect->isChecked(),
	   p->VIDEO_QUALITY_AUTO, m_pQualityAuto->isChecked(),
	   p->VIDEO_BUFFERED, m_pVideoBuffered->isChecked(),
	   p->VIDEO_DIRECT, m_pVideoDirect->isChecked(),
	   p->VIDEO_DROPPING, m_pVideoDropping->isChecked(),
	   p->VIDEO_CODECS, vcodecs.c_str(),
           p->AUDIO_CODECS, acodecs.c_str(),
           0);

    m->setDisplayFramePos(m_pDisplayFramePos->isChecked());
    m->setAutorepeat(m_pAutorepeat->isChecked());
}

void MyConfigDialog_impl::onOk()
{
    onApply();
    accept();
}

void MyConfigDialog_impl::onCancel()
{
    m_pAsyncSlider->setValue(int(m_fAsync*100.));
    onAsyncValChanged(0);
    reject();
}

void MyConfigDialog_impl::onAsyncValChanged(int)
{
    float value=(float)m_pAsyncSlider->value();
    value/=100.;
    char text[50];
    sprintf(text, "%2.2f s", value);
//    printf("%s\n", text);
    m_pAsync->setText(text);

    if (m->GetPlayer())
	m->GetPlayer()->SetAsync(rint(value * 10.0)/10.0);
}

void MyConfigDialog_impl::onFont()
{
    bool isOk;
    QFont font = QFontDialog::getFont(&isOk, m_defFont, this, "Select font");
    if (isOk)
    {
        m_defFont=font;
	m_pPreview->setFont(font);

        char str[250];
	string fname;
	if (!m_defFont.family().isNull())
	    fname = m_defFont.family().ascii();

	sprintf(str, "%s, %d pt%s%s",
		fname.size()?fname.c_str():"default",
		//m_defFont.family().ascii(),
		m_defFont.pointSize(),
		m_defFont.bold()?", bold":"",
		m_defFont.italic()?", italic":"");
	m_pFontType->setText(str);

        fontchange = true;
        update();
    }
}

#include "MyConfig.moc"
#include "MyConfigImpl.moc"
