/***************************************************************************
 *   Copyright (C) 2004 by Predrag Viceic                                  *
 *   viceic@net2000.ch                                             *
 *                                                                         *
 *   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 "scopeview.h"

ScopeView::ScopeView(QWidget *parent, const char *name)
 : QFrame(parent, name,WNoAutoErase)
{
    setFrameStyle(LineEditPanel | Sunken);
    frames=1024;
    position=0;
    lastRenderedPosition=0;
    horiz_steps=64;
    vert_steps=32;
    setPaletteBackgroundColor(QColor(0,0,0));
    playing=FALSE;
    max_energies=0;
}


ScopeView::~ScopeView()
{
    zaparr(max_energies);
}

void ScopeView::showEvent(QShowEvent* /*ev*/){

}

void ScopeView::paintEvent(QPaintEvent* ){
    static QPixmap pixmap;
    bool resized=false;  //force repaint on resize even if between frames.
    if(contentsRect().size().isValid() && pixmap.size()!=contentsRect().size()){
        pixmap.resize(contentsRect().size());
        resized=true;
    }
    if((!playing || ((position>=lastRenderedPosition+frames)&&
        position+frames<soundManager->getFrames()) || resized) &&
         horiz_steps>0 && vert_steps>0 &&contentsRect().size().isValid() &&
         pixmap.size().isValid()){
        if(playing){
            float* lchannel=&soundManager->getLeftChannel()[position];
            //float* rchannel=&soundManager->getRightChannel()[position];

            for (int i=0;i<horiz_steps;i++){
                max_energies[i]=lchannel[i];
            }

        }else{
            for (int i=0;i<horiz_steps;i++){
                max_energies[i]=0;
            }
        }
        lastRenderedPosition=position;

        int x=contentsRect().x();
        int y=contentsRect().y();
        QPainter p(&pixmap);
        p.fillRect(0,0,contentsRect().width(),contentsRect().height(),QBrush::black);
        float total_horiz_step_width=float(contentsRect().width())/float(horiz_steps);
        int rectWidth=int(round(round(total_horiz_step_width)*0.5f));
        int spaceH=int(round(round(total_horiz_step_width)*0.5f));
        float total_vert_step_width=float(contentsRect().height())/float(vert_steps);
        int rectHeight=int(round(round(total_vert_step_width)*0.5f));
        int spaceV=int(round(round(total_vert_step_width)*0.5f));

        QColor color(0,255,0);
        QColor fadedColor(0,255,0);
        QBrush brush(color);
        QBrush fadedBrush(fadedColor);
        for (int i=0;i<horiz_steps;i++){
            color.setRgb(0,255,0);
            for(int j=0;j<vert_steps;j++){
                int r=color.red();
                int g=color.green();
                int b=color.blue();
                if(r<255){
                    r=(int)(255*(double(j)/double(vert_steps)))*2;
                    r=r>255?255:r;
                }
                else if(g>0){
                    g=(int)(255*(double(vert_steps-j)/double(vert_steps)))*2;
                    g=g>255?255:g;
                }
                color.setRgb(r,g,b);
                fadedColor.setRgb(int(float(r)*0.5),int(float(g)*0.5),int(float(b)*0.5));
                brush.setColor(color);
                fadedBrush.setColor(fadedColor);
                if(max_energies[i]>=0 && j>=vert_steps/2){
                    if(max_energies[i]>=double(j-(vert_steps/2))/double(vert_steps/2)){

                        p.fillRect(x+i*(rectWidth+spaceH),
                                         y+(contentsRect().height()/2)-((j-vert_steps/2)*(rectHeight+spaceV)),
                                        rectWidth,-rectHeight,brush);

                    }else{
                        /*
                        p.fillRect(x+i*(rectWidth+spaceH),
                                         y+(contentsRect().height()/2)-((j-vert_steps/2)*(rectHeight+spaceV)),
                                        rectWidth,-rectHeight,fadedBrush);
                        */

                    }
                }else if(max_energies[i]<0 && j<vert_steps/2){

                    if(fabs(max_energies[i])>=double(j)/double(vert_steps/2)){
                        p.fillRect(x+i*(rectWidth+spaceH),
                                   y+(contentsRect().height()/2)+((j)*(rectHeight+spaceV)),
                                        rectWidth,rectHeight,brush);
                    }else{
                        /*
                        p.fillRect(x+i*(rectWidth+spaceH),
                                   y+(contentsRect().height()/2)+((j)*(rectHeight+spaceV)),
                                   rectWidth,rectHeight,fadedBrush);
                        */

                    }

                }
            }
        }
        p.end();
    }
    if (position<lastRenderedPosition) lastRenderedPosition=0;
    if(pixmap.size().isValid() && contentsRect().size().isValid())
        bitBlt(this,contentsRect().x(),contentsRect().y(),&pixmap);
    //QFrame::paintEvent(ev);
}

void ScopeView::customEvent(QCustomEvent* ev)
{
    if(ev->type() == PLAY_POSITION_CHANGED_EVENT){
        position=(((PlayPositionChanged*)ev)->getPosition());
        playing=(((PlayPositionChanged*)ev)->getPlaying());
        update();
    }
}


/*!
    \fn ScopeView::setSoundManager(SoundManager*)
 */
void ScopeView::setSoundManager(SoundManager* sm)
{
    soundManager=sm;
}


/*!
    \fn ScopeView::resizeEvent(QResizeEvent* ev)
 */
void ScopeView::resizeEvent(QResizeEvent* ev)
{
    if(ev->size().isValid()){
        horiz_steps=int(round(ev->size().width()/3));
        vert_steps=int(round(ev->size().height()/3));
        if(horiz_steps>0){
            if(max_energies) zaparr(max_energies);
            max_energies=new float[horiz_steps];
        }
    }
}

QSize ScopeView::sizeHint () const{
    return QSize(100,height());
}
