//**************************************************************************
//*                     This file is part of the                           *
//*                MMC - Mpxplay Multimedia Commander                      *
//*                   The source code of MMC is                            *
//*        (C) copyright 1998-2014 by PDSoft (Attila Padar)                *
//*                http://mpxplay.sourceforge.net                          *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  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.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function: Seekbar and time-pos in mainwindow

//#define MPXPLAY_USE_DEBUGF 1
#define DISPQT_DEBUG_OUTPUT stdout

#include <QtGui>
#include <QtWidgets>
#include "disp_qt.h"
#include "moc_seekbar.h"
#include "moc_mainwindow.h"
#include "display/display.h"

#define DISPQT_SEEKBAR_RESOLUTION  1000
#define DISPQT_SEEKBAR_SLIDER_BUTTON_SIZE_X  6
#define DISPQT_SEEKBAR_SLIDER_TOOLTIP_SHOWTIME  10000

extern "C" {
 extern struct mainvars mvps;
 extern unsigned int refdisp, timemode;
 extern keyconfig kb[];
}

DispQtMainwinSeekbar::DispQtMainwinSeekbar(MainWindow *main_window, QWidget *parent) : QWidget(parent)
{
	this->main_window = main_window;
	this->time_len_ms = 0;
	this->time_display_mode = timemode;
	this->setFocusPolicy(Qt::NoFocus);

	layout_seekbar = new QHBoxLayout;
	layout_seekbar->setSpacing(2);

	mainwinseekbar_config_style_apply(main_window->mainwin_is_translucent_enabled());

	this->label_songnums = new QLabel;
	//this->label_songnums->setFlat(true);
	layout_seekbar->addWidget(this->label_songnums, 0);
	this->seek_slider = new DispQtMainwinSeekslider(main_window, this);
	layout_seekbar->addWidget(this->seek_slider, 1);
	this->label_times = new QLabel;
	//this->label_times->setFlat(true);
	layout_seekbar->addWidget(this->label_times, 0);

	this->mainwinseekbar_set_timepos(0);

	this->setLayout(layout_seekbar);

	connect(this, SIGNAL(signal_mainwinseekbar_set_timepos(int)), this, SLOT(mainwinseekbar_set_timepos(int)));
	connect(this, SIGNAL(signal_mainwinseekbar_option_timemode_change(unsigned int)), this, SLOT(mainwinseekbar_option_timemode_change(unsigned int)));
	//connect(this->label_songnums, SIGNAL(pressed()), this, SLOT(mainwinseekbar_timelabel_change_timemode()));
	//connect(this->label_times, SIGNAL(pressed()), this, SLOT(mainwinseekbar_timelabel_change_timemode()));

	refdisp |= RDT_HEADER;
}

void DispQtMainwinSeekbar::mainwinseekbar_config_style_apply(bool lucent_enable)
{
	this->mutex_seekbar.tryLock(DISPQT_MUTEX_TIMEOUT);
	if(lucent_enable){
		layout_seekbar->setMargin(0);
		setStyleSheet("QWidget { background: transparent; color: white}");
	} else {
		layout_seekbar->setContentsMargins(2,0,2,0);
		setStyleSheet(QString());
	}
	this->mutex_seekbar.unlock();
}

void DispQtMainwinSeekbar::mainwinseekbar_set_currfileinfos(struct dispqt_currfileinfo_s *cur)
{
	char sout[128];
	this->mutex_seekbar.tryLock(DISPQT_MUTEX_TIMEOUT);
	this->time_len_ms = cur->currtimelen;
	if(this->time_len_ms < 0)
		this->time_len_ms = 0;
	this->time_len_ms += 500;
	this->seek_slider->mainwin_seekslider_set_timelen(this->time_len_ms);
	snprintf(sout, sizeof(sout), "%2d / %d", cur->currsongnum, cur->allsongnum);
	this->label_songnums->setText(QString::fromLatin1(sout));
	this->mutex_seekbar.unlock();
}

void DispQtMainwinSeekbar::mainwinseekbar_set_timepos(int new_timepos_ms)
{
	char sout[128];
	this->mutex_seekbar.tryLock(DISPQT_MUTEX_TIMEOUT);
	this->seek_slider->mainwin_seekslider_set_timepos(new_timepos_ms);
	if(this->time_display_mode & 1)
		new_timepos_ms = this->time_len_ms - new_timepos_ms;
	else
		new_timepos_ms += 500;
	if(new_timepos_ms < 0)
		new_timepos_ms = 0;
	if(this->time_len_ms < 3600000)
		snprintf(sout, sizeof(sout), "%d:%2.2d / %d:%2.2d", (new_timepos_ms / 60000), ((new_timepos_ms % 60000) / 1000), (this->time_len_ms / 60000), ((this->time_len_ms % 60000) / 1000));
	else
		snprintf(sout, sizeof(sout), "%d:%2.2d:%2.2d / %d:%2.2d:%2.2d", (new_timepos_ms / 3600000), (new_timepos_ms / 60000) % 60, ((new_timepos_ms % 60000) / 1000),
									(this->time_len_ms / 3600000), (this->time_len_ms / 60000) % 60, ((this->time_len_ms % 60000) / 1000));
	this->label_times->setText(QString::fromUtf8(sout));
	this->mutex_seekbar.unlock();
}

void DispQtMainwinSeekbar::mainwinseekbar_option_timemode_change(unsigned int new_timemode)
{
	this->mutex_seekbar.tryLock(DISPQT_MUTEX_TIMEOUT);
	this->time_display_mode = timemode;
	this->mutex_seekbar.unlock();
}

void DispQtMainwinSeekbar::mainwinseekbar_timelabel_change_timemode(void)
{
	this->mutex_seekbar.tryLock(DISPQT_MUTEX_TIMEOUT);
	timemode = (timemode + 1) & 3;
	this->mutex_seekbar.unlock();
	emit this->signal_mainwinseekbar_option_timemode_change(timemode);
}

//---------------------------------------------------

DispQtMainwinSeekslider::DispQtMainwinSeekslider(MainWindow *main_window, QWidget *parent) : QSlider(Qt::Horizontal, parent)
{
	this->main_window = main_window;
	this->mouse_is_pressed = mouse_is_moved_while_pressed = false;
	this->time_len_ms = 0;
	this->setFocusPolicy(Qt::NoFocus);
	this->setTickPosition(QSlider::NoTicks);
	this->setRange(0, DISPQT_SEEKBAR_RESOLUTION);
	this->setSliderPosition(0);
	this->setMouseTracking(true);
}

void DispQtMainwinSeekslider::mainwin_seekslider_config_style_apply(bool lucent_enable)
{
}

void DispQtMainwinSeekslider::mainwin_seekslider_set_timelen(int new_timelen_ms)
{
	this->time_len_ms = new_timelen_ms;
}

void DispQtMainwinSeekslider::mainwin_seekslider_set_timepos(int new_timepos_ms)
{
	int newpos;
	if(this->mouse_is_pressed)
		return;
	if(this->time_len_ms){
		newpos = (int)((float)DISPQT_SEEKBAR_RESOLUTION * (float) new_timepos_ms / (float) this->time_len_ms);
		if(newpos > DISPQT_SEEKBAR_RESOLUTION)
			newpos = DISPQT_SEEKBAR_RESOLUTION;
		else if(newpos < 0)
			newpos = 0;
	} else {
		newpos = 0;
	}
	this->setSliderPosition(newpos);
}

void DispQtMainwinSeekslider::wheelEvent(QWheelEvent *event)
{
    this->main_window->mainwin_handle_keypresscode(kb[(event->delta() < 0)? 0 : 2].c);  // seek rewind / forward with wheel
	event->accept();
}

void DispQtMainwinSeekslider::mousePressEvent(QMouseEvent *event)
{
	this->mouse_is_moved_while_pressed = false;
    if(event->button() & Qt::LeftButton){
        this->mouse_is_pressed = true;
        QSlider::mousePressEvent(event);
    } else {
        this->main_window->mainwin_handle_mousepress_skip_or_seek_event(event);
    }
}

static void DispQtMainwinSeekslider_file_seek(int x, int w)
{
    if(x <= DISPQT_SEEKBAR_SLIDER_BUTTON_SIZE_X)
        mvps.seek_absolute = 1;
    else
        mvps.seek_absolute = (long) ((float)mvps.fr_primary->index_len * (float)x / (float)w) + mvps.fr_primary->index_start;
}

void DispQtMainwinSeekslider::mouseReleaseEvent(QMouseEvent *event)
{
    if(this->mouse_is_pressed) {
        this->mouse_is_pressed = false;
        int x = event->x(), w = this->width() - DISPQT_SEEKBAR_SLIDER_BUTTON_SIZE_X;
        if(!this->mouse_is_moved_while_pressed) // to avoid duplicated seek
        	DispQtMainwinSeekslider_file_seek(x, w);
        QSlider::mouseReleaseEvent(event);
        this->main_window->mainwindow_set_focus(); // FIXME: bullshit
    }else{
    	this->main_window->mainwin_handle_mousepress_skip_or_seek_event(event);
    }
}

void DispQtMainwinSeekslider::mouseMoveEvent(QMouseEvent *event)
{
	int x = event->x(), w = this->width();
	int time_pos = (int)((float) x * (float)this->time_len_ms / (float)w);
	char sout[32];
	if(this->time_len_ms < 3600000)
		snprintf(sout, sizeof(sout), "%d:%2.2d", (time_pos / 60000), ((time_pos % 60000) / 1000));
	else
		snprintf(sout, sizeof(sout), "%d:%2.2d:%2.2d", (time_pos / 3600000), (time_pos / 60000) % 60, ((time_pos % 60000) / 1000));
	QToolTip::showText(QPoint(event->globalPos().x() - 18, event->globalPos().y() - 42), QString::fromLatin1(sout), this, rect(), DISPQT_SEEKBAR_SLIDER_TOOLTIP_SHOWTIME);
	if(this->mouse_is_pressed) {
		int slider_pos = (int)((float) x * (float)DISPQT_SEEKBAR_RESOLUTION / (float)w);
		this->setSliderPosition(slider_pos);
		DispQtMainwinSeekslider_file_seek(x, w);
		this->mouse_is_moved_while_pressed = true;
	}
}

bool DispQtMainwinSeekslider::event(QEvent *event)
{
	switch(event->type()){
		case QEvent::Leave: QToolTip::hideText(); break;
	}
	return QSlider::event(event);
}

void DispQtMainwinSeekslider::keyPressEvent(QKeyEvent *event)
{
    this->main_window->handle_keypressevent(event);
}

