// dialogs.C
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegård, 1997-1999

#include "qps.h"
#include "dialogs.h"
#include <sched.h>

extern Qps 	*qps;

// center window a with respect to main application window
static void center_window(QWidget *a)
{
	QWidget *b=QApplication::activeWindow ();
    //QWidget *b = qApp->mainWidget();
    a->move(b->x() + (b->width() - a->width()) / 2,
	    b->y() + (b->height() - a->height()) / 2);
}

static void move_mouse_window(QWidget *a)
{
    //QWidget *b = qApp->mainWidget();
	QWidget *b=QApplication::activeWindow ();
    a->move(b->x() + (b->width() - a->width()) / 2,
	    b->y() + (b->height() - a->height()) / 2);
}

static void fix_size(QWidget *w)
{
    w->setFixedSize(w->sizeHint());
}

//Modal dialog
IntervalDialog::IntervalDialog(const char *ed_txt, bool enabled) : QDialog()
{
    setWindowTitle("Change Update Period");
    QVBoxLayout *tl = new QVBoxLayout;
    QHBoxLayout *h1 = new QHBoxLayout;
    setLayout(tl);
    tl->addLayout(h1);

    QLabel *label1 = new QLabel("New Update Period", this);
    h1->addWidget(label1);
    h1->addStretch(1);

	lined = new QLineEdit(this);
	QFont f = font();
	lined->setMaxLength(7);
	lined->setText(ed_txt);
	if(enabled) {
		lined->selectAll();
		lined->setFocus();
	}
	//lined->setEnabled(enabled);
	lined->setEnabled(true);
	fix_size(lined);
	lined->setFixedWidth(64);
	h1->addWidget(lined);

    label = new QLabel( this );
    label->setFrameStyle(QFrame::Panel);
    label->setFrameShadow(QFrame::Sunken);
	label->setText("");
    label->setAlignment(Qt::AlignRight );
    tl->addWidget(label);

	/*
    toggle = new CrossBox("Dynamic Update (under devel)", this);
    fix_size(toggle);
    toggle->setChecked(enabled);
    //toggle->setChecked(false);
    toggle->setChecked(true);
    toggle->setEnabled(false);
    tl->addWidget(toggle);
	*/
    QHBoxLayout *h2 = new QHBoxLayout;
    	//h2->addStretch(1);
    	cancel = new QPushButton("Cancel", this);
    	h2->addWidget(cancel);
    	ok = new QPushButton("OK", this);
		//ok->setFocus();
    	h2->addWidget(ok);
    tl->addLayout(h2);


    connect(ok, SIGNAL(clicked()), SLOT(done_dialog()));
    connect(cancel, SIGNAL(clicked()), SLOT(reject()));
    connect(lined, SIGNAL(returnPressed()), SLOT(done_dialog()));
    connect(lined, SIGNAL( textChanged ( const QString & )), SLOT(event_label_changed()));
//    connect(toggle, SIGNAL(toggled(bool)), lined, SLOT(setEnabled(bool)));

    ok->setDefault(TRUE);

 	///   Q3Accel *acc = new Q3Accel(this);
 	/// acc->connectItem(acc->insertItem(Qt::Key_Escape), this, SLOT(reject()));
 	//  tl->setSizeConstraint(QLayout::SetFixedSize);
	//    center_window(this);
}

void IntervalDialog::event_label_changed()
{
	QString txt;
	int i = 0;
	ed_result = lined->text();
	ed_result = ed_result.simplified();
	
	//if(toggle->isChecked()) 

	QString s = ed_result;
	if (s.length()==0) 
	{
		label->setText("No UPDATE");
		return;
	}

	while(s[i] >= '0' && s[i] <= '9' || s[i] == '.') i++;

	float period = (i > 0) ? s.left(i).toFloat() : -1;
	
	s = s.mid(i, 3).simplified();
	if(s.length() == 0 || s == "s")
		period *= 1000;
	else if(s == "min")
		period *= 60000;
	else if(s != "ms")
		period = -1;
	if(period <= 0) {
		label->setText( "Invalid value");
		return;
		
	}

	txt.sprintf("%d ms",(int)period);
	label->setText(txt);
}

void IntervalDialog::done_dialog()
{
	int i = 0;

	ed_result = lined->text();
	ed_result = ed_result.simplified();
	
	//if(toggle->isChecked()) 
	QString s = ed_result;
	while(s[i] >= '0' && s[i] <= '9' || s[i] == '.') i++;

	float period = (i > 0) ? s.left(i).toFloat() : -1;
	
	s = s.mid(i, 3).simplified();
	if(s.length() == 0 || s == "s")
		period *= 1000;
	else if(s == "min")
		period *= 60000;
	else if(s != "ms")
		period = -1;
	if(period < 0) 
		return;
	
	qps->set_update_period((int)period);
	qps->update_timer();
	
	accept();
}

SliderDialog::SliderDialog(int defaultval, int minval, int maxval)
            : QDialog()
{
    setWindowTitle("Renice Process");
    QVBoxLayout *tl = new QVBoxLayout;
    QHBoxLayout *h1 = new QHBoxLayout;
	setLayout(tl);
    tl->addLayout(h1);

    label = new QLabel("New nice value:", this);
    h1->addWidget(label);

    h1->addStretch(1);

    lined = new QLineEdit(this);
    lined->setMaxLength(3);
    lined->setText(QString::number(defaultval));
    lined->setFocus();
    lined->setFixedWidth(64);
    h1->addWidget(lined);

    slider = new QSlider(Qt::Horizontal, this);
    slider->setMaximum(maxval);
    slider->setMinimum(minval);
	slider->setTickInterval(10);
    slider->setTickPosition(QSlider::TicksBelow);
    slider->setValue(defaultval);
    tl->addWidget(slider);

    QHBoxLayout *h2 = new QHBoxLayout;
    tl->addLayout(h2);

    // decorate slider
    QLabel *left = new QLabel(this);
    QLabel *mid = new QLabel(this);
    QLabel *right = new QLabel(this);
    left->setNum(minval);
    mid->setNum((minval + maxval) / 2);
    right->setNum(maxval);
    h2->addWidget(left);
    h2->addStretch(1);
    h2->addWidget(mid);
    h2->addStretch(1);
    h2->addWidget(right);

    QHBoxLayout *h3 = new QHBoxLayout;
    tl->addLayout(h3);

    h3->addStretch(1);
    cancel = new QPushButton("Cancel", this);
   // fix_size(cancel);
    h3->addWidget(cancel);

    ok = new QPushButton("OK", this);
    ok->setFixedSize(cancel->sizeHint());
    h3->addWidget(ok);

    connect(ok, SIGNAL(clicked()), SLOT(done_dialog()));
    ok->setDefault(TRUE);
    connect(cancel, SIGNAL(clicked()), SLOT(reject()));
    connect(lined, SIGNAL(returnPressed()), SLOT(done_dialog()));
    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slider_change(int)));
   // Q3Accel *acc = new Q3Accel(this);
   // acc->connectItem(acc->insertItem(Qt::Key_Escape), this, SLOT(reject()));
   // tl->freeze();

    center_window(this);
}

void SliderDialog::done_dialog()
{
    ed_result = lined->text();
    ed_result = ed_result.simplified();
    accept();
}

void SliderDialog::slider_change(int val)
{
    QString s;
    s.setNum(val);
    lined->setText(s);
    lined->selectAll();
}

// DRAFT CODE, 
PermissionDialog::PermissionDialog(QString msg,QString passwd): QDialog()
{
	setWindowTitle("Permission");
    QVBoxLayout *vbox = new QVBoxLayout;
	label=new QLabel(msg,this);
	vbox->addWidget(label);
	
	setLayout(vbox);

	QHBoxLayout *hbox = new QHBoxLayout;
    vbox->addLayout(hbox);
	label=new QLabel("root password",this);
	hbox->addWidget(label);
	lined=new QLineEdit(this);
	hbox->addWidget(lined);

	hbox = new QHBoxLayout;
    vbox->addLayout(hbox);
    QPushButton	*cancel = new QPushButton("Cancel", this);
	hbox->addWidget(cancel);

    QPushButton* ok = new QPushButton("OK", this);
	hbox->addWidget(ok);
	
	connect(ok, SIGNAL(clicked()), SLOT(accept()) );
    connect(cancel, SIGNAL(clicked()), SLOT(reject()));
}


SchedDialog::SchedDialog(int policy, int prio) : QDialog()
{
    setWindowTitle("Change scheduling");
    QVBoxLayout *vl = new QVBoxLayout;
	setLayout(vl);
   
    bgrp = new QGroupBox("Scheduling Policy", this);
	vl->addWidget(bgrp);	//bgrp->setCheckable(1); 
	rb_other = new QRadioButton("SCHED_OTHER (time-sharing)",bgrp);
    rb_fifo = new QRadioButton("SCHED_FIFO (real-time)", bgrp);
    rb_rr = new QRadioButton("SCHED_RR (real-time)", bgrp);
    
    QVBoxLayout *vbox = new QVBoxLayout;
	vbox->addWidget(rb_other);
    vbox->addWidget(rb_fifo);
    vbox->addWidget(rb_rr);
	bgrp->setLayout(vbox);

	connect(rb_other, SIGNAL(clicked(bool)), SLOT(button_clicked(bool)));
	connect(rb_fifo, SIGNAL(clicked(bool)), SLOT(button_clicked(bool)));
	connect(rb_rr, SIGNAL(clicked(bool)), SLOT(button_clicked(bool)));
 
    QHBoxLayout *hbox1 = new QHBoxLayout;
	QPushButton *ok, *cancel;
    ok = new QPushButton("OK", this);
    ok->setDefault(TRUE);
    cancel = new QPushButton("Cancel", this);
   	hbox1->addWidget(ok); 
   	hbox1->addWidget(cancel);
   	vl->addLayout(hbox1);

	connect(ok, SIGNAL(clicked()), SLOT(done_dialog()));
	connect(cancel, SIGNAL(clicked()), SLOT(reject()));

    int active = 0;
    QRadioButton *rb;
	switch(policy) {
    	case SCHED_OTHER:
			active = 0;	rb=rb_other; 
			break;
    	case SCHED_FIFO:
			active = 1;	rb=rb_fifo;
			break;
    	case SCHED_RR:
			active = 2;	rb=rb_rr;
			break;
    }
    rb->setChecked(TRUE);
    out_policy = policy;
    out_prio = prio;

    QHBoxLayout *hbox = new QHBoxLayout;
    lbl = new QLabel("Priority (1-99):", this);
    lined = new QLineEdit(this);
	hbox->addWidget(lbl);
	hbox->addWidget(lined);
	vbox->addLayout(hbox);	
    QFont f = font();
    f.setBold(FALSE);
    lined->setFont(f);
    lined->resize(60, lined->sizeHint().height());
    lined->setMaxLength(4);
    QString s;
    s.setNum(prio);
    lined->setText(s);
    button_clicked(active);

    // make sure return and escape work as accelerators
    connect(lined, SIGNAL(returnPressed()), SLOT(done_dialog()));

}

void SchedDialog::done_dialog()
{
    if(rb_rr->isChecked())
		out_policy = SCHED_RR;
    else if(rb_fifo->isChecked())
		out_policy = SCHED_FIFO;
    else
		out_policy = SCHED_OTHER;
    QString s(lined->text());
    bool ok;
    out_prio = s.toInt(&ok);
    if(out_policy != SCHED_OTHER && (!ok || out_prio < 1 || out_prio > 99)) {
		QMessageBox::warning(this, "Invalid Input", "The priority must be in the range 1..99");
    } else
	accept();
}

void SchedDialog::button_clicked(bool val)
{
//	printf("SchedDialog::checked()\n");
    if(rb_other->isChecked()) {
		lbl->setEnabled(FALSE);
		lined->setEnabled(FALSE);
    } 
	else {
		QString s(lined->text());
		bool ok;
		int n = s.toInt(&ok);
		if(ok && n == 0)
	    	lined->setText("1");
		lbl->setEnabled(TRUE);
		lined->setEnabled(TRUE);
		lined->setFocus();
		lined->selectAll();
    }
}

