/***************************************************************************
 *   Copyright (C) 2007 by Andreas Krumnow   *
 *   andreas@krumnow.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   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.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "metronom.h"

metronom::metronom()
{
    currentAngleWidth = 60;
    is_running  = false;
    zeiger_on   = false;
    click_on    = false;
    taktZ       = 4;
    taktT       = 4;
    curCount    = taktZ + 1;

    pendel = new ZeigerFeld(this);
    pendel->setObjectName(QString::fromUtf8("pendel"));
    pendel->setMaxWinkel(currentAngleWidth);

    speaker = new audioThread(this);

    quitButton  = new QPushButton(tr("Quit"));
    connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));

    runButton   = new QPushButton(tr("Start"));
    connect(runButton, SIGNAL(clicked()), this, SLOT(on_runButton()));
    sld_sWidth = new QSlider(Qt::Horizontal);
    sld_sWidth->setObjectName(QString::fromUtf8("sld_sWidth"));
    sld_sWidth->setRange(8, 120);
    sld_sWidth->setTickPosition(QSlider::TicksAbove);
    sld_sWidth->setTickInterval(41);
    sld_sWidth->setValue(currentAngleWidth);
    sld_sWidth->setToolTip("Ausschlag des Pendels");
    connect(sld_sWidth, SIGNAL(valueChanged(int)),this, SLOT(on_sld_sWidth(int)));
    lbl_sWidth = new QLabel(QString::number(currentAngleWidth));
    lbl_sWidth->setObjectName(QString::fromUtf8("lbl_sWidth"));
    lbl_sWidth->setToolTip(tr("Ausschlag des Pendels"));

    tempo = 120;
    pendel->setClockTempo(tempo);
    sld_tempo = new QSlider(Qt::Vertical);
    sld_tempo->setObjectName(QString::fromUtf8("sld_tempo"));
    sld_tempo->setRange(20, 280);
    sld_tempo->setTickPosition(QSlider::TicksBothSides);
    sld_tempo->setTickInterval(10);
    sld_tempo->setValue(tempo);
    sld_tempo->setToolTip(tr("Tempo (beats per minute)"));
    connect(sld_tempo, SIGNAL(valueChanged(int)),this, SLOT(on_sld_tempo(int)));
    lbl_tempo = new QLabel(QString::number(tempo));
    lbl_tempo->setObjectName(QString::fromUtf8("lbl_tempo"));
    lbl_tempo->setToolTip(tr("Tempo (beats per minute)"));
    lbl_tempo->setFont(QFont("Helvetica", 18, QFont::Bold));
    lbl_temp1 = new QLabel("/4          bpm: ");
    lbl_temp1->setObjectName(QString::fromUtf8("lbl_temp1"));
    lbl_temp1->setToolTip(tr("Tempo (beats per minute)"));

    cbx_zeiger = new QCheckBox(tr("Pendel"));
    cbx_zeiger->setObjectName(QString::fromUtf8("cbx_zeiger"));
    cbx_zeiger->setCheckState(Qt::Checked);
    on_cbx_zeiger(Qt::Checked);
    connect(cbx_zeiger, SIGNAL(stateChanged(int)),this, SLOT(on_cbx_zeiger(int)));
    cbx_click = new QCheckBox(tr("Click"));
    cbx_click->setObjectName(QString::fromUtf8("cbx_click"));
    cbx_click->setCheckState(Qt::Checked);
    on_cbx_click(Qt::Checked);
    connect(cbx_click, SIGNAL(stateChanged(int)),this, SLOT(on_cbx_click(int)));
    spx_takt = new QSpinBox(this);
    spx_takt->setObjectName(QString::fromUtf8("spx_takt"));
    spx_takt->setRange(2,8);
    spx_takt->setValue(4);
    connect(spx_takt, SIGNAL(valueChanged(int)), this, SLOT(on_spx_takt(int)));

    lbl_dbgln = new QLabel(tr("debug:"));
    lbl_dbgln->setObjectName(QString::fromUtf8("lbl_dbgln"));
    lbl_dbgln->setToolTip(tr(""));

    pulse = new QTimer(this);
    connect(pulse, SIGNAL(timeout()), this, SLOT(playTick()));
    connect(pulse, SIGNAL(timeout()), pendel, SLOT(resetZeiger()));

    gridLayout = new QGridLayout;
    gridLayout->addWidget(lbl_sWidth, 0, 0, 1, 1);
    gridLayout->addWidget(sld_sWidth,0,1,1,2);
    gridLayout->addWidget(spx_takt,0,4,1,1);
    gridLayout->addWidget(lbl_temp1,0,5,1,1);
    gridLayout->addWidget(lbl_tempo,0,6,1,1);
    gridLayout->addWidget(pendel, 1, 0,1,6);
    gridLayout->addWidget(sld_tempo,1,6,1,1);
    gridLayout->addWidget(cbx_zeiger,2,0,1,2);
    gridLayout->addWidget(cbx_click,2,2,1,1);
    gridLayout->addWidget(runButton, 2, 3,1,2);
    gridLayout->addWidget(quitButton, 2, 5,1,2);
    gridLayout->addWidget(lbl_dbgln, 3, 0, 1, 6);
    setLayout(gridLayout);

    resize( 450, 600 );
}

metronom::~metronom()
{
    delete pulse;
    delete pendel;
    delete speaker;
    delete quitButton;
    delete runButton;
    delete sld_sWidth;
    delete sld_tempo;
    delete cbx_zeiger;
    delete cbx_click;
    delete lbl_sWidth;
    delete lbl_tempo;
    delete lbl_temp1;
    delete lbl_dbgln;
    delete gridLayout;
}

void metronom::playTick()
{
    speaker->setVoice(1);
    if( ++curCount > taktZ){
        curCount = 1;
        speaker->setVoice(0);
    }
    if(click_on){
        speaker->start();
   }
}

void metronom::on_sld_sWidth(int i)
{
    pendel->setMaxWinkel(i);
    currentAngleWidth = i;
    pendel->setClockTempo(tempo);
    lbl_sWidth->setText(QString::number(currentAngleWidth));
}

void metronom::on_sld_tempo(int i)
{
    tempo = i;
    pulse->setInterval(60000/tempo);
    pendel->setClockTempo(tempo);
    lbl_tempo->setText(QString::number(tempo));
}

void metronom::on_spx_takt(int i)
{
    taktZ = i;
    if(i<2) taktZ = 2;
    if(i>8) taktZ = 8;
    curCount = taktZ + 1;
    if(is_running){
        on_runButton();
    }
}

void metronom::on_runButton()
{
    if (is_running){
        pulse->stop();
        is_running = false;
        runButton->setText("Start");
    } else {
        if(zeiger_on || click_on){
            is_running = true;
            pulse->start((int)60000/tempo);
            runButton->setText("Stop");
        }
    }
    if(zeiger_on){
        pendel->startStop();
    }
}

void metronom::on_cbx_zeiger(int qtcs)
{
    if (qtcs == Qt::Checked){
        zeiger_on = true;
        if(is_running)pendel->swing(true);
    }else{
        zeiger_on = false;
        pendel->swing(false);
        if(is_running && (!click_on)){
            on_runButton();
        }
    }
}

void metronom::on_cbx_click(int qtcs)
{
    if (qtcs == Qt::Checked){
        click_on = true;
    }else{
        click_on = false;
        if(is_running && (!zeiger_on)){
            on_runButton();
        }
    }
}