/**************************************************************************

    channel.cpp  - The KMidChannel widget (with pure virtual members)
    Copyright (C) 1998  Antonio Larrosa Jimenez

    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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

    Send comments and bug fixes to larrosa@kde.org
    or to Antonio Larrosa, Rio Arnoya, 10 5B, 29006 Malaga, Spain

***************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <tqpainter.h>
#include <tqcombobox.h>

#include <tdeglobal.h>
#include <tdeinstance.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include "tdemidbutton.h"

#include "channel.h"
#include "instrname.h"
#include <kiconloader.h>

KMidChannel::KMidChannel(int chn,TQWidget *parent) : TQWidget (parent)
{
    channel=chn;
    replay=true;
    int i;
    for (i=0;i<128;i++) pressed[i]=0;
    keyboard = TQPixmap(locate("appdata","icons/keyboard.xpm"));
    penB = new TQPen (black);
    penW = new TQPen (white);
    penT = new TQPen (colorGroup().background());

    TDEConfig *kcfg=TDEGlobal::instance()->config();
    kcfg->setGroup("KMid");
    TQFont *qtextfontdefault=new TQFont("lucida",18,TQFont::Bold,true);
    qcvfont=new TQFont(kcfg->readFontEntry("ChannelViewFont",qtextfontdefault));
    delete qtextfontdefault;

    instrumentCombo = new TQComboBox(false,this,"instr");
    instrumentCombo->setGeometry(160,2,200,20);

    for (i=0;i<128;i++)
        instrumentCombo->insertItem(i18n(instrumentName[i]),i);

    connect(instrumentCombo,TQ_SIGNAL(activated(int)),this,TQ_SLOT(pgmChanged(int)));

    forcepgm=new KMidButton(this,"forcepgm");
    forcepgm->setGeometry(135,4,16,16);
    forcepgm->setToggleButton(true);
    button1 = TQPixmap(locate("appdata","icons/button1.xpm"));
    button2 = TQPixmap(locate("appdata","icons/button2.xpm"));
    forcepgm->setPixmaps(button1,button2);
    forcepgm->show();
    connect(forcepgm,TQ_SIGNAL(toggled(bool)),this,TQ_SLOT(changeForcedState(bool)));

}

KMidChannel::~KMidChannel()
{
    delete penB;
    delete penW;
    delete penT;
}

void KMidChannel::paintEvent( TQPaintEvent * )
{

    TQPainter *qpaint=new TQPainter(this);

    TQString tmp = i18n("Channel %1").arg(channel);
    qpaint->setFont(*qcvfont);
    qpaint->setPen(*penB);
    qpaint->drawText(2,20,tmp);
    qpaint->setPen(*penW);
    qpaint->drawText(0,18,tmp);

    drawKeyboard(qpaint);
    drawPressedKeys(qpaint);

    delete qpaint;
}

void KMidChannel::drawKeyboard(TQPainter *qpaint)
{
    int x=1;
    for (int i=0;(i<12) && (x<width());i++,x+=63)
    {
        qpaint->drawPixmap(x,KEYBOARDY,keyboard);
    };
    qpaint->setPen(*penB);
    qpaint->drawLine(0,KEYBOARDY,0,KEYBOARDY+44);

    qpaint->setPen(*penT);
    qpaint->drawLine(0,KEYBOARDY+45,x+63,KEYBOARDY+45);


}

void KMidChannel::drawPressedKeys(TQPainter *qpaint)
{
    for (int i=0;i<128;i++)
        if (pressed[i]) drawKey(qpaint,i);
}

void KMidChannel::drawKey(TQPainter *qpaint,int key)
{
    int octave=key/12;
    int note=key%12;
    int x=octave*63+1;

    switch (note)
    {
    case (0) :  drawDo   (qpaint,x,pressed[key]);break;
    case (1) :  drawDo__ (qpaint,x,pressed[key]);break;
    case (2) :  drawRe   (qpaint,x,pressed[key]);break;
    case (3) :  drawRe__ (qpaint,x,pressed[key]);break;
    case (4) :  drawMi   (qpaint,x,pressed[key]);break;
    case (5) :  drawFa   (qpaint,x,pressed[key]);break;
    case (6) :  drawFa__ (qpaint,x,pressed[key]);break;
    case (7) :  drawSol  (qpaint,x,pressed[key]);break;
    case (8) :  drawSol__(qpaint,x,pressed[key]);break;
    case (9) :  drawLa   (qpaint,x,pressed[key]);break;
    case (10) : drawLa__ (qpaint,x,pressed[key]);break;
    case (11) : drawSi   (qpaint,x,pressed[key]);break;
    };
//    qpaint->flush();
}

void KMidChannel::noteOn(int key)
{
    pressed[key]=1;
    TQPainter *qpaint=new TQPainter(this);
    drawKey(qpaint,key);
    delete qpaint;
}

void KMidChannel::noteOff(int key)
{
    pressed[key]=0;
    TQPainter *qpaint=new TQPainter(this);
    drawKey(qpaint,key);
    delete qpaint;
}

void KMidChannel::changeInstrument(int pgm)
{
    instrumentCombo->setCurrentItem(pgm);
}

void KMidChannel::changeForceState(bool i)
{
        replay=false;
        forcepgm->setOn(i);
        replay=true;
}

void KMidChannel::reset(int level)
{
    for (int i=0;i<128;i++) pressed[i]=0;
    if (level>=1)
    {
        instrumentCombo->setCurrentItem(0);
        replay=false;
        forcepgm->setOn(false);
        replay=true;
    };

    repaint(false);
}

void KMidChannel::saveState(bool *p,int *pgm)
{
    for (int i=0;i<128;i++) p[i]=pressed[i];
    *pgm=instrumentCombo->currentItem();
}

void KMidChannel::loadState(bool *p,int *pgm)
{
    for (int i=0;i<128;i++) pressed[i]=p[i];
    instrumentCombo->setCurrentItem(*pgm);
    repaint(false);
}

void KMidChannel::pgmChanged(int i)
{
    int data[4];
    data[0]=CHN_CHANGE_PGM;
    data[1]=channel;
    data[2]=i;
    data[3]=0;

    replay=false;
    forcepgm->setOn(true);
    replay=true;

    emit signalToKMidClient(data);


}


void KMidChannel::changeForcedState(bool i)
{
    int data[4];
    data[0]=CHN_CHANGE_FORCED_STATE;
    data[1]=channel;
    data[2]=i;
    data[3]=(replay)? 1 : 0;

    emit signalToKMidClient(data);

}
#include "channel.moc"
