#include <QtGui>

#include "MainWindow.h"

#include <limits.h>
#include <time.h>

#include <QList.h>
#include <QPushButton.h>
#include <QTextEdit.h>
#include <QSettings.h>
#include <QSet.h>
#include <QElapsedTimer.h>
#include <QSplitter.h>

#include "CollectorDiagramWidget.h"
#include "CollectorStatisticWidget.h"
#include "KeypadWidget.h"
#include "SerialPort.h"
#include "SerialEnumerator.h"
#include "SoundPlayer.h"
#include "LargeDialog.h"

const unsigned char COMMAND_SELECT = 0xFF;
const unsigned char COMMAND_RESET = 0xFE;
const unsigned char COMMAND_STATUS = 0xFD;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
	, mRowCount(0)
	, mCollectorCount(0)
{
	QTabWidget *optionsTabWidget = new QTabWidget();
    createDiagramTab(optionsTabWidget);
	createStatisticsTab(optionsTabWidget);
	createConfigurationTab(optionsTabWidget);
	createLogTab(optionsTabWidget);
    optionsTabWidget->setContentsMargins(0,0,0,0);
	setCentralWidget(optionsTabWidget);
	setWindowTitle(tr("Egg Alert and Real-time Logistics"));
	loadSettings();
}

MainWindow::~MainWindow()
{
	delete mKeypadWidget;
	delete mDiagramList;
	delete mStatisticList;
	delete mStatisticBoxLayout;
	delete mDiagramBoxLayout;
	delete mSnoozeButton;
	delete mLogTextArea;
	delete mSerialPort;
	delete mSettings;
	delete mProcessTimer;
	delete mEggCountLabel;
	delete mSoundPlayer;
	delete mSnoozeTimer;
}

QString MainWindow::readSerial()
{
    int numBytes = mSerialPort->bytesAvailable();
    if (numBytes)
    {
        if(numBytes > 1024)
            numBytes = 1024;
        char buffer[1024];
        int i = mSerialPort->read(buffer, numBytes);
        if (i != -1)
            buffer[i] = '\0';
        else
            buffer[0] = '\0';
        return QString(buffer);
    }
    return QString::null;
}

void MainWindow::tick()
{
	if (!mSerialPort->isOpen())
	{
		static clock_t reconnectTimer = 0;
		double elapsed_secs = double(clock() - reconnectTimer) / CLOCKS_PER_SEC;
		if (elapsed_secs > mTimeout)
		{
			static bool portWarning = true;
			elapsed_secs = clock();
			qDebug() << "Trying to open " + mSerialPort->portName();
            if (mSerialPort->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
			{
				log(tr("Opened %0.").arg(mSerialPort->portName()));
				portWarning = true;
			}
			else if (portWarning)
			{
				log(tr("Could not open %0.").arg(mSerialPort->portName()));
				portWarning = false;
			}
		}
	}
	else
    {
        static int collectorIndex = 0, laneIndex = 0;
        static bool transmitQuery = true;
        if (collectorIndex >= mCollectorCount)
        {
            collectorIndex = 0;
            laneIndex = 0;
            transmitQuery = true;
        }
        else if (laneIndex >= mRowCount * 2)
        {
            collectorIndex++;
            laneIndex = 0;
            transmitQuery = true;
        }
        else
        {
            CollectorStatisticWidget *stat = mStatisticList->at(collectorIndex);
            CollectorDiagramWidget *diagram = mDiagramList->at(collectorIndex);
            static bool forceReset = true;
			static QElapsedTimer portTimer;
            if (forceReset)
            {
                forceReset = false;
                const char reset[] = { COMMAND_SELECT, COMMAND_RESET };
                mSerialPort->write(reset, 2);
                log("Resetting all module counts");
            }
            else if (transmitQuery)
            {
				const char query[] = {COMMAND_SELECT, COMMAND_STATUS, stat->address()};
                mSerialPort->write(query, 3);
				portTimer.restart();
                transmitQuery = false;
                log(tr("Querying module %0").arg(stat->address()));
            }
            else if (mSerialPort->bytesAvailable() > 0)
            {
                static bool hasBuffer = false;
                static char buffer;
                char data;
                mSerialPort->read(&data, 1);
                if (!hasBuffer)
                {
                    buffer = data;
                    hasBuffer = true;
                }
                else
                {
                    hasBuffer = false;
                    int laneValue = (data << 8) + buffer;
                    log(QString::number(laneValue));
                    stat->setLaneValue(laneIndex, laneValue);
					if (diagram->laneState(laneIndex) == CollectorDiagramWidget::Unknown)
						diagram->setLaneState(laneIndex, CollectorDiagramWidget::Good);
                    portTimer.restart();
                    laneIndex++;
                    if (laneIndex == mRowCount * 2)
                        diagram->setState(CollectorDiagramWidget::Good);
                }
            }
            else if (portTimer.hasExpired(1000 * mTimeout))
            {
                if (diagram->state() != CollectorDiagramWidget::Ignored)
                {
					playAlarm();
					diagram->setState(CollectorDiagramWidget::Bad);
					log(tr("Module %0 timed out.").arg(stat->address()));
                }
                collectorIndex++;
                laneIndex = 0;
                transmitQuery = true;
            }

            // TODO: Report jams if beyond thresholds.
        }
    }
}

void MainWindow::createDiagramTab(QTabWidget *optionsTabWidget)
{
	QWidget *diagramTab = new QWidget();
	QVBoxLayout *layout = new QVBoxLayout();

	mDiagramBoxLayout = new QHBoxLayout();
	mDiagramList = new QList<CollectorDiagramWidget*>();
	mSnoozeButton = new QPushButton("Snooze");
	mSnoozeButton->hide();
	connect(mSnoozeButton, SIGNAL(clicked()), this, SLOT(snooze()));

	mDiagramBoxLayout->setMargin(0);
	mDiagramBoxLayout->setSpacing(0);
	mDiagramBoxLayout->setContentsMargins(0,0,0,0);
	mDiagramBoxLayout->addWidget(new QLabel("N"));

	QWidget *diagramContainerWidget = new QWidget();
	diagramContainerWidget->setLayout(mDiagramBoxLayout);

	layout->setSpacing(0);
	layout->setMargin(0);
	layout->setContentsMargins(0,0,0,0);
	layout->addWidget(diagramContainerWidget);
	layout->addWidget(mSnoozeButton);
    layout->setStretchFactor(diagramContainerWidget,5);
	layout->setStretchFactor(mSnoozeButton,1);


	diagramTab->setLayout(layout);
	optionsTabWidget->addTab(diagramTab, "Diagram");
}

void MainWindow::createStatisticsTab(QTabWidget *optionsTabWidget)
{
	QWidget *optionsTab = new QWidget();
	QVBoxLayout *layout = new QVBoxLayout();
	
	mStatisticBoxLayout = new QHBoxLayout();
	mStatisticList = new QList<CollectorStatisticWidget*>();
	mEggCountLabel = new QLabel("0");

    mEggCountLabel->setAlignment(Qt::AlignCenter);
	mEggCountLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
	mEggCountLabel->setStyleSheet("border: 2px solid black;	border-radius: 8px;");

	mStatisticBoxLayout->addWidget(new QLabel("N"));
	mStatisticBoxLayout->setMargin(0);

	mDiagramBoxLayout->setContentsMargins(0,0,0,0);

	QWidget *statisticsContainerWidget = new QWidget();
	statisticsContainerWidget->setLayout(mStatisticBoxLayout);

	layout->setSpacing(0);
	layout->setMargin(0);
	layout->setContentsMargins(0,0,0,0);
	layout->addWidget(statisticsContainerWidget);
	layout->addWidget(mEggCountLabel);
	layout->setStretchFactor(statisticsContainerWidget,1);
	
	optionsTab->setLayout(layout);

	optionsTabWidget->addTab(optionsTab, "Statistics");
}

void MainWindow::createConfigurationTab(QTabWidget *optionsTabWidget)
{
#define PROPERTY(name, layout, slot) {\
    QRadioButton *propButton = new QRadioButton(name);\
	layout->addWidget(propButton);\
    connect(propButton, SIGNAL(clicked()), this, SLOT(slot()));}

	QWidget *configurationTab = new QWidget();

	mKeypadWidget = new KeypadWidget();

	QHBoxLayout *mainLayout = new QHBoxLayout();
	QTabWidget *configurationTabWidget = new QTabWidget();
	configurationTabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	connect(configurationTabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
	QWidget *alarmTab = new QWidget();
	QVBoxLayout *alarmLayout = new QVBoxLayout();
	alarmLayout->setSpacing(0);
	PROPERTY("Alarm Delay", alarmLayout, delayRadioButton_Click);
	PROPERTY("Alarm Snooze", alarmLayout, snoozeRadioButton_Click);
	PROPERTY("Alarm File", alarmLayout, alarmRadioButton_Click);
	QWidget *volumePanel = new QWidget();
	volumePanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	mSoundPlayer = new SoundPlayer(volumePanel);
	connect(mSoundPlayer, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
	alarmLayout->addWidget(volumePanel);
	alarmTab->setLayout(alarmLayout);
	configurationTabWidget->addTab(alarmTab, "Alarm");
    
	QWidget *collectorTab = new QWidget();
	QVBoxLayout *collectorLayout = new QVBoxLayout();
	collectorLayout->setSpacing(0);
	PROPERTY("Collector Count", collectorLayout, collectorCountRadioButton_Click);
	PROPERTY("Row Count", collectorLayout, rowCountRadioButton_Click);
	collectorTab->setLayout(collectorLayout);
	configurationTabWidget->addTab(collectorTab, "Collector");

	QWidget *portTab = new QWidget();
	QVBoxLayout *portLayout = new QVBoxLayout();
	portLayout->setSpacing(0);
	PROPERTY("Port Number", portLayout, portNameRadioButton_Click);
	PROPERTY("Port Timeout", portLayout, portTimeoutRadioButton_Click);
	portTab->setLayout(portLayout);
	configurationTabWidget->addTab(portTab, "Port");

	mainLayout->addWidget(configurationTabWidget);
	mainLayout->addWidget(mKeypadWidget);
	mainLayout->setStretch(0, 1);
	mainLayout->setStretchFactor(mKeypadWidget, 1);
	mainLayout->setContentsMargins(0,0,0,0);
    
	configurationTab->setContentsMargins(0,0,0,0);
	configurationTab->setLayout(mainLayout);
	optionsTabWidget->addTab(configurationTab, "Configuration");
}

void MainWindow::createLogTab(QTabWidget *optionsTabWidget)
{
	mLogTextArea = new QTextEdit();
	mLogTextArea->setReadOnly(true);
	optionsTabWidget->addTab(mLogTextArea, tr("Log"));
}

void MainWindow::log(QString message)
{
	QFile logFile("Log.txt");
	if (logFile.open(QIODevice::Append | QIODevice::Text))
		QTextStream(&logFile) << QDateTime::currentDateTime().toString("dd/MM/yy HH:mm:ss") << " " << message << "\n";
	mLogTextArea->append(QDateTime::currentDateTime().toString("HH:mm:ss") + " " + message);
	qDebug() << message;
	QScrollBar *bar = mLogTextArea->verticalScrollBar();
	if (!bar->isSliderDown())
		bar->setValue(bar->maximum());
}

void MainWindow::portNameRadioButton_Click()
{
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setTimeoutDelay(int)));
	mKeypadWidget->setMode(KeypadWidget::Selection);
	QString portName = 0;
	QSet<int> selections;
	QListIterator<PortInfo> itr(SerialEnumerator::getPorts());
	while(itr.hasNext())
	{
		portName = itr.next().portName;
		if (portName.startsWith("COM") && portName.length() > 3)
		{
			int id = portName.mid(3).toInt();
			selections.insert(id);
		}
	}
	mKeypadWidget->setSelections(selections);
	mKeypadWidget->setMode(KeypadWidget::Selection);
    connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setPortName(int)), Qt::UniqueConnection);
	portName = mSerialPort->portName();
	if (portName.startsWith("COM") && portName.length() > 3)
	{
		mKeypadWidget->setValue(portName.mid(3).toInt());
		mKeypadWidget->setDefaultValue(mKeypadWidget->value());
	}
	else
	{
		qDebug() << "No default port name";
		mKeypadWidget->setValue(0);
		mKeypadWidget->setDefaultValue(mKeypadWidget->value());
	}
	mKeypadWidget->show();
}

void MainWindow::portTimeoutRadioButton_Click()
{
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setPortName(int)));
	mKeypadWidget->setMode(KeypadWidget::Range);
	mKeypadWidget->setMinimum(0);
	mKeypadWidget->setMaximum(INT_MAX);
    connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setTimeoutDelay(int)), Qt::UniqueConnection);
	mKeypadWidget->setValue(mTimeout);
	mKeypadWidget->setDefaultValue(mTimeout);
	mKeypadWidget->show();
}

void MainWindow::delayRadioButton_Click()
{
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setSnoozeDuration(int)));
	mKeypadWidget->setMode(KeypadWidget::Range);
	mKeypadWidget->setMinimum(0);
	mKeypadWidget->setMaximum(INT_MAX);
    connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setAlarmDelay(int)), Qt::UniqueConnection);
	mKeypadWidget->setValue(mAlarmDelay);
	mKeypadWidget->setDefaultValue(mAlarmDelay);
	mKeypadWidget->show();
}
void MainWindow::snoozeRadioButton_Click()
{
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setAlarmDelay(int)));
	mKeypadWidget->setMode(KeypadWidget::Range);
	mKeypadWidget->setMinimum(0);
	mKeypadWidget->setMaximum(INT_MAX);
    connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setSnoozeDuration(int)), Qt::UniqueConnection);
	mKeypadWidget->setValue(mSnoozeDuration);
	mKeypadWidget->setDefaultValue(mSnoozeDuration);
	mKeypadWidget->show();
}

void MainWindow::alarmRadioButton_Click()
{
	QRadioButton *button = qobject_cast<QRadioButton*>(sender());
	Q_ASSERT(button);
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setSnoozeDuration(int)));
	disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setAlarmDelay(int)));
	mKeypadWidget->hide();
	button->setChecked(false);

	QStringList files = QFileDialog::getOpenFileNames(this, tr("Select Music File"),
		QApplication::applicationDirPath(), "Sound Files (*.WAV)");

	if (files.isEmpty())
		return;

	QString fileName = files.first();

	mSoundPlayer->setSource(fileName);
	mSoundPlayer->play();
	mSettings->setValue("Alarm/File", fileName);
}

void MainWindow::collectorCountRadioButton_Click()
{
	disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setRowCount(int)));
	mKeypadWidget->setMode(KeypadWidget::Range);
	mKeypadWidget->setMinimum(0);
	mKeypadWidget->setMaximum(20);
	connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setCollectorCount(int)), Qt::UniqueConnection);
	mKeypadWidget->setValue(mCollectorCount);
	mKeypadWidget->setDefaultValue(mCollectorCount);
	mKeypadWidget->show();
}
void MainWindow::rowCountRadioButton_Click()
{
	disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setCollectorCount(int)));
	mKeypadWidget->setMode(KeypadWidget::Range);
	mKeypadWidget->setMinimum(0);
	mKeypadWidget->setMaximum(20);
	connect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setRowCount(int)), Qt::UniqueConnection);
	mKeypadWidget->setValue(mRowCount);
	mKeypadWidget->setDefaultValue(mRowCount);
	mKeypadWidget->show();
}

void MainWindow::setAlarmDelay(int value)
{
	mSettings->setValue("Alarm/Delay", value);
	mAlarmDelay = value;
}

void MainWindow::setSnoozeDuration(int value)
{
	mSettings->setValue("Alarm/Snooze", value);
	mSnoozeDuration = value;
}

void MainWindow::setCollectorCount(int value)
{
	while(value > mCollectorCount)
	{
		int address = mSettings->value(tr("Collectors/%0").arg(mCollectorCount), mCollectorCount + 1).toInt();
        CollectorDiagramWidget *diagramWidget = new CollectorDiagramWidget(mRowCount);
		CollectorStatisticWidget *statisticWidget = new CollectorStatisticWidget(address, mRowCount);

		connect(diagramWidget, SIGNAL(laneClicked(int)), this, SLOT(laneClicked(int)));
        connect(diagramWidget, SIGNAL(collectorClicked()), this, SLOT(diagramClicked()));
        connect(statisticWidget, SIGNAL(addressClicked()), this, SLOT(addressClicked()));
		connect(statisticWidget, SIGNAL(addressChanged()), this, SLOT(addressChanged()));

        statisticWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
		mDiagramBoxLayout->addWidget(diagramWidget);
		mStatisticBoxLayout->addWidget(statisticWidget);
		mStatisticBoxLayout->setStretchFactor(statisticWidget, 1);
		mDiagramList->append(diagramWidget);
		mStatisticList->append(statisticWidget);
		mCollectorCount++;
	}
	while(value < mCollectorCount)
	{
		CollectorDiagramWidget *diagramWidget = mDiagramList->takeLast();
		CollectorStatisticWidget *statisticWidget = mStatisticList->takeLast();

		mStatisticBoxLayout->removeWidget(statisticWidget);
		mDiagramBoxLayout->removeWidget(diagramWidget);
		delete diagramWidget;
		delete statisticWidget;
		mCollectorCount--;
	}
	mSettings->setValue("Collectors/CollectorCount", value);
	mCollectorCount = value;
}

void MainWindow::setRowCount(int rowCount)
{
	for(int i = 0; i < mCollectorCount; i++)
	{
		mDiagramList->at(i)->setRowCount(rowCount);
		mStatisticList->at(i)->setRowCount(rowCount);
	}
	mSettings->setValue("Collectors/RowCount", rowCount);
	mRowCount = rowCount;
}

void MainWindow::setPortName(int value)
{
	if (mSerialPort->portName().mid(3).toInt() == value)
		return;
	mSettings->setValue("Port/Name", value);
    mSerialPort->close();
    mSerialPort->setPortName(tr("COM%0").arg(value));
}

void MainWindow::setTimeoutDelay(int value)
{
	mSettings->setValue("Port/Timeout", value);
	mTimeout = value;
}

void MainWindow::loadStyleSheet(const QString &styleSheetFileName /*= ":/style/style.qss"*/)
{
    QFile file(styleSheetFileName);
	if (file.open(QIODevice::ReadOnly | QIODevice::Text))
		qApp->setStyleSheet(file.readAll());
	else
		log("Could not open style sheet: " + styleSheetFileName);
}

void MainWindow::loadSettings()
{
	mSettings = new QSettings("Settings.ini", QSettings::IniFormat);

    qApp->setStyle( mSettings->value("Window/Style", "CleanLooks").toString() );
    loadStyleSheet( mSettings->value("Window/StyleSheet", ":/style/style.qss").toString() );
    setGeometry( mSettings->value("Window/Position", QRect(0,330,795,240)).toRect() );

    setSnoozeDuration( mSettings->value("Alarm/Snooze", 300).toInt() );
	setAlarmDelay( mSettings->value("Alarm/Delay", 60).toInt() );
	mSoundPlayer->setVolume( mSettings->value("Alarm/Volume", 100).toReal() );

    setRowCount(mSettings->value("Collectors/RowCount", 0).toInt() );
    setCollectorCount(mSettings->value("Collectors/CollectorCount", 0).toInt() );

    mTimeout = mSettings->value("Port/Timeout", 5).toInt();
    mSerialPort = new SerialPort(SerialPort::Polling);
	mSerialPort->setBaudRate(BAUD9600);
    mSerialPort->setFlowControl(FLOW_OFF);
	mSerialPort->setParity(PAR_NONE);
	mSerialPort->setDataBits(DATA_8);
	mSerialPort->setStopBits(STOP_2);
	mSerialPort->setTimeout(mTimeout);
    setPortName( mSettings->value("Port/Name", 1).toInt() );

	mSoundPlayer->setSource(mSettings->value("Alarm/File", "Fightsong.WAV").toString());
	mProcessTimer = new QTimer(this);
	mProcessTimer->setInterval(25);
	connect(mProcessTimer, SIGNAL(timeout()), this, SLOT(tick()));
	mProcessTimer->start();

	mSnoozeTimer = new QElapsedTimer();
	mSnoozeTimer->invalidate();
}

void MainWindow::tabChanged( int )
{
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setAlarmDelay(int)));
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setSnoozeDuration(int)));
	disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setCollectorCount(int)));
	disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setRowCount(int)));
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setPortName(int)));
    disconnect(mKeypadWidget, SIGNAL(valueChanged(int)), this, SLOT(setTimeoutDelay(int)));
	mKeypadWidget->hide();
}

void MainWindow::laneClicked( int index )
{
	CollectorDiagramWidget *diagram = qobject_cast<CollectorDiagramWidget*>(sender());
	Q_ASSERT(diagram);
	LargeDialog dialog("test","test");
	dialog.exec();
	return;
	if (diagram->laneState(index) == CollectorDiagramWidget::Ignored)
	{
		dialog.setText("This lane is disabled.");
		dialog.setWindowTitle("Would you like to enable it?");
		if (QMessageBox::Yes == dialog.exec())
			diagram->setLaneState(index, CollectorDiagramWidget::Unknown);
	}
	else
	{
		dialog.setText("This lane is enabled.");
		dialog.setWindowTitle("Would you like to disable it?");
		if (QMessageBox::Yes == dialog.exec())
			diagram->setLaneState(index, CollectorDiagramWidget::Ignored);
	}
}

void MainWindow::diagramClicked()
{
	CollectorDiagramWidget *diagram = qobject_cast<CollectorDiagramWidget*>(sender());
    Q_ASSERT(diagram);
    return;
    LargeDialog dialog(geometry());
	return;
	if (diagram->state() == CollectorDiagramWidget::Ignored)
	{
		dialog.setText("This collector is disabled.");
		dialog.setWindowTitle("Would you like to enable it?");
		if (QMessageBox::Yes == dialog.exec())
			diagram->setState(CollectorDiagramWidget::Unknown);
	}
	else
	{
		dialog.setText("This collector is enabled.");
		dialog.setWindowTitle("Would you like to disable it?");
		if (QMessageBox::Yes == dialog.exec())
			diagram->setState(CollectorDiagramWidget::Ignored);
	}

}

void MainWindow::addressClicked()
{
    CollectorStatisticWidget *statistic = qobject_cast<CollectorStatisticWidget*>(sender());
    Q_ASSERT(statistic);
	QDialog dialog(this);
	QVBoxLayout dialogLayout;
	KeypadWidget keypad;
	QPushButton closeButton("Close");
	

	keypad.setMode(KeypadWidget::Range);
	keypad.setMinimum(0);
	keypad.setMaximum(255);
	keypad.setValue(statistic->address());
	keypad.setDefaultValue(statistic->address());
	
	connect(&keypad, SIGNAL(valueChanged(int)), statistic, SLOT(setAddress(int)));
	connect(&closeButton, SIGNAL(clicked()), &dialog, SLOT(accept()));
	
	dialogLayout.addWidget(&keypad);
	dialogLayout.addWidget(&closeButton);
	dialog.setLayout(&dialogLayout);
	dialog.setGeometry(geometry());
	dialog.exec();
}

void MainWindow::saveSettings()
{
	QListIterator<QString> itr(mSettings->allKeys());
	while (itr.hasNext())
	{
		QString current = itr.next();
		// HACK: Force all keys to serialize.
		mSettings->setValue(current, mSettings->value(current));
	}
}

void MainWindow::closeEvent(QCloseEvent *)
{
    mSettings->setValue("Window/Position", geometry());
	QFile countFile(mSettings->value("Output/File", "Count.txt").toString());
}

bool MainWindow::playAlarm()
{
	if ((mSnoozeTimer->isValid() && !mSnoozeTimer->hasExpired(1000 * mSnoozeDuration)) || mSoundPlayer->isPlaying())
		return false;
	mSoundPlayer->playLooping();
	mSnoozeButton->show();
	mSnoozeTimer->invalidate();
	return true;
}

void MainWindow::snooze()
{
	mSnoozeTimer->restart();
	mSnoozeButton->hide();
	mSoundPlayer->stop();
}

void MainWindow::volumeChanged(qreal newVolume)
{
	mSettings->setValue("Alarm/Volume", newVolume);
}

void MainWindow::addressChanged()
{
	CollectorStatisticWidget *statistic = qobject_cast<CollectorStatisticWidget*>(sender());
	Q_ASSERT(statistic);
	int index = mStatisticList->indexOf(statistic);
	Q_ASSERT(index >= 0);
	mSettings->setValue(tr("Collectors/%0").arg(index), statistic->address());
}
