/***************************************************************************
 *   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 "drawsoundwidgetabstract.h"

DrawSoundWidgetAbstract::DrawSoundWidgetAbstract(QWidget *parent, const char *name, SoundManager* sm)
    : QCanvasView(parent,name,Qt::WNoAutoErase)
{
    soundManager=sm;
    canvas=new WaveCanvas(this->viewport());
    canvas->setDoubleBuffering(TRUE);
    enableClipper(TRUE);
    setCanvas(canvas);
    canvas->setSoundManager(sm);
    zoomRatio=1;
    //setResizePolicy(QScrollView::AutoOneFit);
    updateCanvas=true;
    setVScrollBarMode(AlwaysOff);
    setHScrollBarMode(AlwaysOn);
    oldVisibleSize=0;
    canvas->setVisibleWidth(width());
}


DrawSoundWidgetAbstract::~DrawSoundWidgetAbstract()
{
}

/*!
    \fn DrawSoundWidget::canvas()
 */
WaveCanvas* DrawSoundWidgetAbstract::getCanvas()
{
    return canvas;
}





/*!
    \fn DrawSoundWidgetAbstract::getZoomRatio()
 */
long DrawSoundWidgetAbstract::getZoomRatio()
{
    return zoomRatio;
}



/*!
    \fn DrawSoundWidgetAbstract::zoomToSamplePos(long,long)
 */
long DrawSoundWidgetAbstract::zoomToSamplePos(long start,long end)
{
    cout<<"in "<<name()<<" zoomToSamplePos("<<start<<","<<end<<")\n";
    long diff=end-start;
    long mid=start+diff/2;
    //long temp_zoomRatio=long(float(diff)/float(((QCanvasView*)parent())->visibleWidth()));
    long temp_zoomRatio=long(float(diff)/float(width()));
std::cout<<"["<<name()<<"]: temp_zoom: "<<temp_zoomRatio<<" visibleWidth: "<<visibleWidth()<<" s-e:"<<start<<"-"<<end<<"\n";
    if(temp_zoomRatio<1) temp_zoomRatio=1;

    
        zoomRatio=temp_zoomRatio;
        canvas->setZoomRatio(zoomRatio);
        int c_height=
                canvas->height()==0?sizeHint().height():canvas->height();
        canvas->resize(soundManager->getFrames()/zoomRatio,c_height);
        canvas->setPixmapXOrigin(0);
        zapWaveCanvasBuffers(FALSE);
        oldVisibleSize=getLastVisibleSample()-getFirstVisibleSample();
        
        emit(zoomChangedS(zoomRatio));  //forces the effectFrame canvas resize
        center(mid/zoomRatio,canvas->height()/2);
        zoomChanged();
        
        
        return zoomRatio;
}


/*!
    \fn DrawSoundWidgetAbstract::getFirstVisibleSample()
 */
long DrawSoundWidgetAbstract::getFirstVisibleSample()
{
     long sample_pos=contentsX()*getZoomRatio();
     return sample_pos<0?0:sample_pos;
}


/*!
    \fn DrawSoundWidgetAbstract::getLastVisibleSample()
 */
long DrawSoundWidgetAbstract::getLastVisibleSample()
{
    long v_Width=((QWidget*)parentWidget())->width();
    long end_sample=(contentsX()+v_Width)*getZoomRatio();
    return end_sample>soundManager->getFrames()?soundManager->getFrames():end_sample;
}

void DrawSoundWidgetAbstract::resizeEvent(QResizeEvent* ev){
    //long oldZoomRatio=zoomRatio;
    if(ev->oldSize()!=ev->size()){
        if(soundManager->hasSound() && ev->size().width()>20){
            if(oldVisibleSize>0){
                zoomRatio=long(round(oldVisibleSize/ev->size().width()));
                canvas->setZoomRatio(zoomRatio);
                cout<<"in "<<name()<<" resizeEvent()"<<" zoomRatio: "<<zoomRatio<<"\n";
                int scrollbarheight=horizontalScrollBar()->isHidden()?0:
                        horizontalScrollBar()->height();
                int c_height= height()-scrollbarheight;
                canvas->resize(soundManager->getFrames()/zoomRatio,c_height);
                canvas->setVisibleWidth(width());
                canvas->setPixmapXOrigin(contentsX());
                zapWaveCanvasBuffers();
                emit(zoomChangedS(zoomRatio));  //forces the effectFrame canvas resize
                zoomChanged();
                resized();
            }
            oldVisibleSize=getLastVisibleSample()-getFirstVisibleSample();
        }
    }
}


void DrawSoundWidgetAbstract::forceRepaint(){
    //called when applying LADSPA on whole wavefile
    //called after crop
    //called when resizing window
    if(soundManager->hasSound()){
        //cout<<"in "<<name()<<" forceRepaint()\n";
        canvas->setVisibleWidth(width());
        canvas->forceRepaint();//0,soundManager->getFrames());
    }
}

void DrawSoundWidgetAbstract::forceRepaint(long start_sample,long end_sample){
    if(soundManager->hasSound()){
        assert(start_sample>=0 &&
                end_sample<=soundManager->getFrames() && end_sample>start_sample);
        //cout<<"in "<<name()<<" forceRepaint("<<start_sample<<","<<end_sample<<")\n";
        canvas->forceRepaint(start_sample,end_sample);
    }
}


/*!
    \fn DrawSoundWidgetAbstract::checkStartSample(long)
 */
long DrawSoundWidgetAbstract::checkSamplePosition(long sample_pos)
{
    if (sample_pos<0) return 0;
    else if(sample_pos>soundManager->getFrames()) return soundManager->getFrames();
    else return sample_pos;
}
/**
    setZoomRatio(long):
         1) Changes zoom ratio
         2) Resizes the canvas,
*/
void DrawSoundWidgetAbstract::setZoomRatio(long _zr,bool repaint){
    if(zoomRatio!=_zr){
        cout<<"in "<<name()<<" setZoomRatio()\n";
        zoomRatio=_zr!=0?_zr:1;
        canvas->setZoomRatio(zoomRatio);
        //on init
        //cout<<"canvas->height(): "<<canvas->height()<<endl;
        int c_height=
                canvas->height()==0?sizeHint().height():canvas->height();
        //end on init
        canvas->resize(soundManager->getFrames()/zoomRatio,c_height);
        canvas->setPixmapXOrigin(0);
        if (repaint){
            zapWaveCanvasBuffers(repaint);
            zoomChanged();
        }
        //resized();
        oldVisibleSize=getLastVisibleSample()-getFirstVisibleSample();
    }
}


/*!
    \fn DrawSoundWidgetAbstract::zapWaveCanvasBuffers()
 */
void DrawSoundWidgetAbstract::zapWaveCanvasBuffers(bool repaint)
{
    cout<<"in "<<name()<<" zapWaveCanvasBuffers()\n";
    canvas->zapBuffers();
    if (repaint) forceRepaint();
}


/*!
    \fn DrawSoundWidgetAbstract::zapWaveCanvasBuffers(long start, long end)
 */
void DrawSoundWidgetAbstract::zapWaveCanvasBuffers(long start, long end)
{
    cout<<"in "<<name()<<" zapWaveCanvasBuffers("<<start<<","<<end<<")\n";
    canvas->zapBuffers(start,end);
    forceRepaint(start,end);
}


/*!
    \fn DrawSoundWidgetAbstract::getCenterViewSample()
 */
long DrawSoundWidgetAbstract::getCenterViewSample()
{
    return getFirstVisibleSample()+(getLastVisibleSample()-getFirstVisibleSample())/2;
}


/*!
    \fn DrawSoundWidgetAbstract::getFirstVisibleSampleAfterZoom(long zoomRatio)
 */
long DrawSoundWidgetAbstract::getFirstVisibleSampleAfterZoom(long _zoomRatio)
{
    long center=getCenterViewSample();
    long nb_samples_after_zoom=visibleWidth()*_zoomRatio;
    return center-nb_samples_after_zoom/2;
}


/*!
    \fn DrawSoundWidgetAbstract::getLastVisibleSampleAfterZoom(long zoomRatio)
 */
long DrawSoundWidgetAbstract::getLastVisibleSampleAfterZoom(long _zoomRatio)
{
    long center=getCenterViewSample();
    long nb_samples_after_zoom=visibleWidth()*_zoomRatio;
    return center+nb_samples_after_zoom/2;
}


/*!
    \fn DrawSoundWidgetAbstract::putZoomRatio(long zr)
 */
void DrawSoundWidgetAbstract::putZoomRatio(long _zr)
{
    zoomRatio=_zr!=0?_zr:1;
    canvas->setZoomRatio(zoomRatio);
    zapWaveCanvasBuffers();
}
