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

EffectPortFrame::EffectPortFrame(QString _name,LADSPAPort* _port,QWidget *parent, const char *name)
    : QCanvasView(parent, name,Qt::WNoAutoErase)
{
    enableClipper(TRUE);
    zoomRatio=1;
    name=_name;
    port=_port;
    //c_height=100;
    linesCreated=FALSE;
    //setGeometry(((QVBox*)parent)->contentsRect());
    canvas=new ControllerCanvas(viewport());
    canvas->setBackgroundColor(QColor(230,230,230));
    canvas->setMaxValue(port->getUpperBound());
    canvas->setMinValue(port->getLowerBound());
    canvas->setStartX(contentsX());
    canvas->setVisibleWidth(visibleWidth());
    setResizePolicy(QScrollView::AutoOneFit);
    setCanvas(canvas);
    drawValueLines();
    drawBeatlines();
    setVScrollBarMode(AlwaysOff);
    setHScrollBarMode(AlwaysOff);
    drawing=FALSE;
    update_interval.reset();
    applyPolicy=NO_AUTO_APPLY;
    drawMode=DRAW_MODE_POINTS;
    drawingLine=new DrawingLine(canvas);
    polyLine=new PolyLine(canvas);
    polyLine->setMaxValue(port->getUpperBound());
    polyLine->setMinValue(port->getLowerBound());
    polyLine->updateSize(canvas->size());
    spline=new SplineLine(canvas);
    spline->setMaxValue(port->getUpperBound());
    spline->setMinValue(port->getLowerBound());
    spline->updateSize(canvas->size());
    ladspaValueView=new LADSPAValueView(canvas);
    ladspaValueView->hide();

    connect(this,SIGNAL(contentsMoving(int,int)), this,SLOT(contentsMoved(int,int)));
}


EffectPortFrame::~EffectPortFrame()
{
    delete ladspaValueView;    
    delete drawingLine;
    delete polyLine;
    delete spline;
    delete canvas;
}

void EffectPortFrame::raiseMe(){
    ((QWidgetStack*)parent())->raiseWidget(this);
    canvas->resize((int)((double)port->getNbFrames()/(double)zoomRatio),visibleHeight());
    drawValueLines();
    drawBeatlines();
    polyLine->updateSize(canvas->size());
    spline->updateSize(canvas->size());
    update();
    emit(drawModeChanged(drawMode));
    //std::cout<<"i'm raised!: "<<port->getPortName()<<"\n";
}


/*!
    \fn EffectPortFrame::resizeEvent(QResizeEvent*)
 */
void EffectPortFrame::resizeEvent(QResizeEvent* ev)
{
    QCanvasView::resizeEvent(ev);
    canvas->resize((int)((double)port->getNbFrames()/(double)zoomRatio),
                    visibleHeight());
    canvas->setStartX(contentsX());
    canvas->setVisibleWidth(visibleWidth());
    drawValueLines();
    drawBeatlines();
    polyLine->updateSize(canvas->size());
    spline->updateSize(canvas->size());

    canvas->update();
    //updateGeometry();
}

void EffectPortFrame::drawValueLines(bool updateCanvas){
    float max=port->getUpperBound();
    float min=port->getLowerBound();
    float diff=max-min;
    int count=0;
    if(!linesCreated){
        int reminder=port->getNbFrames() % 1024;
        for (double i=0;i<port->getNbFrames()-reminder;i+=1024){
                ValueLine* line=new ValueLine(canvas,(long)i,(float*)port->getVOTPointer((int)i/1024));
                int drawValue=(int)(visibleHeight()-((line->getValue()-min)*visibleHeight())/diff);
                line->setPen(darkGray);
                line->setPoints((int)(i/zoomRatio),drawValue,(int)(i/zoomRatio),visibleHeight());
                line->setWidth(int(ceil(1024/zoomRatio)));
                line->show();
        }
        linesCreated=TRUE;
    }else{
        QCanvasItemList l=canvas->allItems();
        for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
            if((*it)->rtti()==RTTI_VALUELINE){
                count++;
                ValueLine* templine=(ValueLine*)(*it);
                if (templine->isVisible()){
                    int drawValue=
                            (int)(visibleHeight()-((templine->getValue()-min)*visibleHeight())/diff);
                    templine->setPoints(templine->getSamplePos()/zoomRatio,
                                                        drawValue,
                                                    templine->getSamplePos()/zoomRatio,
                                                    visibleHeight());
                    templine->setWidth(int(ceil(1024/zoomRatio)));
                }
            }
        }
    }
    if(updateCanvas) canvas->update();
    //cout<<"VALUELINES_NB= "<<count<<endl;
}


void EffectPortFrame::closeEvent( QCloseEvent* ce ){

    //delete canvas;
    ce->accept();
}



/*!
    \fn EffectPortFrame::setZoomRatio(long)
 */
void EffectPortFrame::setZoomRatio(long _zr)
{
        zoomRatio=_zr;
        canvas->resize((int)((double)port->getNbFrames()/(double)zoomRatio),visibleHeight());
        //cout<<"Effect frame canvas resized\n";
        drawValueLines(false);
        drawBeatlines(false);
        polyLine->setZoomRatio(zoomRatio);
        polyLine->updateSize(canvas->size());
        spline->setZoomRatio(zoomRatio);
        spline->updateSize(canvas->size());
        //canvas->update();
}


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


/*!
    \fn EffectPortFrame::getCanvas()
 */
ControllerCanvas* EffectPortFrame::getCanvas()
{
    return canvas;
}

void EffectPortFrame::contentsMousePressEvent( QMouseEvent * mouseEvent){
    QPoint pos=mouseEvent->pos();
    ladspaValueView->setX(pos.x()+10);
    ladspaValueView->setY(pos.y());
    ladspaValueView->setValue(yPosToVal(pos.y()));
    ladspaValueView->show();
    pos.setX(pos.x()<contentsX()?
            contentsX():pos.x()>contentsX()+width()?contentsX()+width():pos.x());
    //magnet selection
    long sample_pos=pos.x()*zoomRatio,temp_sample_pos=0;
    int temp_pos_x=0;
    this->getNearestLinePos(pos,temp_sample_pos,temp_pos_x);
    if(pos.x()!=temp_pos_x && fabs(pos.x()-temp_pos_x)<3){
        sample_pos=temp_sample_pos;
        pos.setX(temp_pos_x);
    }
    //end magnet selection
    if(drawMode==DRAW_MODE_LINES){
        if (mouseEvent->button()==LeftButton){
            drawingLine->setStartPoint(pos.x(),pos.y());
            drawingLine->setEndPoint(pos.x(),pos.y());
            drawingLine->setStartSample(sample_pos);
            drawingLine->setEndSample(sample_pos);
            drawingLine->setStartValue(yPosToVal(pos.y()));
            drawingLine->show();
            canvas->update();
            drawing=TRUE;
        }
    }else if(drawMode==DRAW_MODE_POLYLINES){
        if (mouseEvent->button()==LeftButton){
            polyLine->addPoint(pos,sample_pos,yPosToVal(pos.y()));
            polyLine->show();
            canvas->update();
            drawing=TRUE;

        }
        if (mouseEvent->button()==RightButton){
            polyLine->removePoint(pos);
            canvas->update();
            drawing=TRUE;
        }
    }else if(drawMode==DRAW_MODE_SPLINES){
        if (mouseEvent->button()==LeftButton){
            spline->addPoint(pos,sample_pos,yPosToVal(pos.y()));
            spline->show();
            canvas->update();
            drawing=TRUE;

        }
        if (mouseEvent->button()==RightButton){
            spline->removePoint(pos);
            canvas->update();
            drawing=TRUE;
        }
    }else if(drawMode==DRAW_MODE_POINTS){
        if (mouseEvent->button()==LeftButton||mouseEvent->button()==RightButton){
            update_interval.add(
                        updateValueAtPos(pos,
                                         mouseEvent->button()==LeftButton,
                                         mouseEvent->button()==RightButton));
            drawing=TRUE;
            if(applyPolicy==APPLY_ON_CHANGE){
                    emit(valueChanged(update_interval.start_sample,
                                                        update_interval.end_sample));
                update_interval.reset();
            }
        }
    }
}

void EffectPortFrame::contentsMouseMoveEvent( QMouseEvent * mouseEvent){
    QPoint pos=mouseEvent->pos();
    ladspaValueView->setX(pos.x()+10);
    ladspaValueView->setY(pos.y());
    ladspaValueView->setValue(yPosToVal(pos.y()));
    pos.setX(pos.x()<contentsX()?
            contentsX():pos.x()>contentsX()+width()?contentsX()+width():pos.x());
    pos.setY(pos.y()<0?
            0:pos.y()>contentsHeight()?contentsHeight():pos.y());

    //magnet selection
    long sample_pos=pos.x()*zoomRatio,temp_sample_pos=0;
    int temp_pos_x=0;
    this->getNearestLinePos(pos,temp_sample_pos,temp_pos_x);
    if(pos.x()!=temp_pos_x && fabs(pos.x()-temp_pos_x)<3){
        sample_pos=temp_sample_pos;
        pos.setX(temp_pos_x);
    }
    //end magnet selection

    if(drawMode==DRAW_MODE_LINES){
        if(drawing){
            drawingLine->setEndPoint(pos.x(),pos.y());
            drawingLine->setEndSample(sample_pos);
            drawingLine->setEndValue(yPosToVal(pos.y()));
            canvas->update();
        }
    }else if(drawMode==DRAW_MODE_POLYLINES){
        polyLine->moveSelectedPoint(pos,sample_pos,yPosToVal(pos.y()));
        canvas->update();
    }else if(drawMode==DRAW_MODE_SPLINES){
        spline->moveSelectedPoint(pos,sample_pos,yPosToVal(pos.y()));
        canvas->update();
    }else if(drawMode==DRAW_MODE_POINTS){
        if(mouseEvent->state()==LeftButton ||mouseEvent->state()==RightButton){
            if(drawing){
                update_interval.add(
                        updateValueAtPos(pos,
                                         mouseEvent->state()==LeftButton,
                                         mouseEvent->state()==RightButton));
                if(applyPolicy==APPLY_ON_CHANGE){
                        emit(valueChanged(update_interval.start_sample,
                             update_interval.end_sample));
                        update_interval.reset();
                }
            }
        }
    }
}

void EffectPortFrame::contentsMouseReleaseEvent( QMouseEvent * mouseEvent){
    ladspaValueView->hide();
    canvas->update();
    QPoint pos=mouseEvent->pos();
    pos.setX(pos.x()<contentsX()?
            contentsX():pos.x()>contentsX()+width()?contentsX()+width():pos.x());
    if(drawMode==DRAW_MODE_LINES){
        if(drawing){
            QCanvasItemList collisions=canvas->collisions(drawingLine->boundingRect());
            if(!collisions.isEmpty()){
                    QCanvasItemList::iterator it;
                    for ( it = collisions.begin(); it != collisions.end(); ++it ){
                            if((*it)->rtti()==RTTI_VALUELINE){
                                ValueLine* temp=(ValueLine*)(*it);
                                float controlerValue=drawingLine->getValueAtSample(temp->getSamplePos());
                                *(temp->getValuePointer())=controlerValue;
                                int y=drawingLine->getYAtX(temp->startPoint().x());
                                temp->setPoints(temp->startPoint().x(),y,
                                                                temp->endPoint().x(),visibleHeight());
                                temp->setWidth(int(ceil(1024/zoomRatio)));
                                if (temp->getSamplePos()<update_interval.start_sample) {
                                    update_interval.start_sample=temp->getSamplePos();
                                }
                                if (temp->getSamplePos()>update_interval.end_sample) {
                                        update_interval.end_sample=temp->getSamplePos();
                                }
                            }
                    }
            }
            drawingLine->hide();
            canvas->update();
            if(applyPolicy==APPLY_ON_RELEASE){
                if(update_interval.isValid()){
                    emit(valueChanged(update_interval.start_sample,
                                                            update_interval.end_sample));
                }
            }
            drawing=FALSE;
        }
    }else if(drawMode==DRAW_MODE_POLYLINES ||
             drawMode==DRAW_MODE_SPLINES){
        polyLine->deselectAll();
        spline->deselectAll();
        if(drawing && ((drawMode==DRAW_MODE_POLYLINES
           && polyLine->count()>0) ||
           (drawMode==DRAW_MODE_SPLINES
           && spline->count()>0))){

            QCanvasItemList collisions=drawMode==DRAW_MODE_POLYLINES?
                    canvas->collisions(polyLine->boundingRect()):
                    canvas->collisions(spline->boundingRect());
            if(!collisions.isEmpty()){
                QCanvasItemList::iterator it;
                for ( it = collisions.begin(); it != collisions.end(); ++it ){
                    if((*it)->rtti()==RTTI_VALUELINE){
                        ValueLine* temp=(ValueLine*)(*it);
                        int y=
                                drawMode==DRAW_MODE_POLYLINES?
                                    polyLine->getYAtX(temp->startPoint().x()):
                                    spline->getYAtX(temp->startPoint().x());
                        if(y>-1){
                            float controlerValue=
                                drawMode==DRAW_MODE_POLYLINES?
                                    polyLine->getValueAtSample(temp->getSamplePos()):
                                    spline->getValueAtSample(temp->getSamplePos());

                            *(temp->getValuePointer())=controlerValue;
                            temp->setPoints(temp->startPoint().x(),y,temp->endPoint().x(),visibleHeight());
                            temp->setWidth(int(ceil(1024/zoomRatio)));
                            if (temp->getSamplePos()<update_interval.start_sample) {
                                update_interval.start_sample=temp->getSamplePos();
                            }
                            if (temp->getSamplePos()>update_interval.end_sample) {
                                update_interval.end_sample=temp->getSamplePos();
                            }
                        }
                    }
                }
            }
            canvas->update();
            if(applyPolicy==APPLY_ON_RELEASE){
                if(update_interval.isValid()){
                    emit(valueChanged(update_interval.start_sample,
                         update_interval.end_sample));
                }
            }
        }
        drawing=FALSE;
        canvas->update();
    }else if(drawMode==DRAW_MODE_POINTS){
        if(drawing){
            drawing=FALSE;
            if(applyPolicy==APPLY_ON_RELEASE){
                if(update_interval.isValid()){
                    emit(valueChanged(update_interval.start_sample,
                                                           update_interval.end_sample));
                }
            }
        }
    }
    update_interval.reset();
}

void EffectPortFrame::contentsWheelEvent( QWheelEvent *){
}

EffectPortFrame::interval EffectPortFrame::updateValueAtPos(QPoint pos,bool leftButton,bool rightButton){
        float max=port->getUpperBound();
        float min=port->getLowerBound();
        float diff=max-min;
        int x=pos.x();
        if(x<0) x=0;
        int y=pos.y();
        if(y>visibleHeight()) y=visibleHeight();
        if(y<0) y=0;
        long intdown=LONG_MAX;
        long intup=LONG_MIN;
        QCanvasItemList colisions;
        interval returninterval;
        returninterval.start_sample=0;
        returninterval.end_sample=0;
        QRect rect(pos.x(),0,1,height());
        if(leftButton){
            colisions=canvas->collisions(rect);
        }else if(rightButton)
            colisions=canvas->allItems();
        if(!colisions.isEmpty()){
            float controlerValue=(((visibleHeight()-y)*diff)/visibleHeight())+min;
                //std::cout<<"cv: "<<controlerValue<<"\n";
                for (QCanvasItemList::Iterator it=colisions.begin(); it!=colisions.end(); ++it) {
                    if((*it)->rtti()==RTTI_VALUELINE){
                        ValueLine* temp=(ValueLine*)(*it);
                        *(temp->getValuePointer())=controlerValue;
                        temp->setPoints(temp->startPoint().x(),y,temp->endPoint().x(),visibleHeight());
                        temp->setWidth(int(ceil(1024/zoomRatio)));
                        if (temp->getSamplePos()<intdown) {intdown=temp->getSamplePos();}
                        if (temp->getSamplePos()>intup) {intup=temp->getSamplePos();}
                    }
                }
                canvas->update();
                returninterval.start_sample=intdown;
                returninterval.end_sample=intup;
        }
        return returninterval;
}


/*!
    \fn EffectPortFrame::setApplyPolicy()
 */
void EffectPortFrame::setApplyPolicy(int pol)
{
    applyPolicy=pol;
}

void EffectPortFrame::pointsToggled()
{
    if(isVisible()){
        drawMode=DRAW_MODE_POINTS;
        polyLine->clear();
        polyLine->hide();
        spline->clear();
        spline->hide();
        canvas->update();
    }
}

void EffectPortFrame::linesToggled()
{
    if(isVisible()){
        drawMode=DRAW_MODE_LINES;
        polyLine->clear();
        polyLine->hide();
        spline->clear();
        spline->hide();
        canvas->update();
    }
}

void EffectPortFrame::polylinesToggled()
{
    if(isVisible()){
        drawMode=DRAW_MODE_POLYLINES;
        spline->clear();
        spline->hide();
        if(polyLine->count()>0) polyLine->show();
        canvas->update();
    }
}

void EffectPortFrame::splinesToggled()
{
    if(isVisible()){
        drawMode=DRAW_MODE_SPLINES;
        polyLine->clear();
        polyLine->hide();
        if(spline->count()>0) spline->show();
        canvas->update();
    }
}

QSize EffectPortFrame::minimumSizeHint () const {
    return QSize(parentWidget()->width(),60);
}



/*!
    \fn EffectPortFrame::yPosToVal(int y)
 */
float EffectPortFrame::yPosToVal(int y)
{
        float max=port->getUpperBound();
        float min=port->getLowerBound();
        float diff=max-min;
        if(y>visibleHeight()) y=visibleHeight();
        if(y<0) y=0;
        return (((visibleHeight()-y)*diff)/visibleHeight())+min;
}


/*!
    \fn EffectPortFrame::getDrawMode()
 */
EffectPortFrame::DrawMode EffectPortFrame::getDrawMode()
{
    return drawMode;
}


/*!
    \fn EffectPortFrame::beatLinesChanged(QValueList <beatline_data> beatlines)
 */
void EffectPortFrame::beatLinesChanged(QValueList <beatline_data> _beatlines)
{
    beatlines=_beatlines;
    drawBeatlines();
    canvas->update();
}


/*!
    \fn EffectPortFrame::lockedBeatLinesChanged(QValueList <beatline_data> beatlines)
 */
void EffectPortFrame::lockedBeatLinesChanged(QValueList <beatline_data> _beatlines)
{
    lockedBeatlines=_beatlines;
    drawBeatlines();
    canvas->update();
}


/*!
    \fn EffectPortFrame::drawBeatlines()
 */
void EffectPortFrame::drawBeatlines(bool /*updateCanvas*/)
{
    removeBeatlines();
    /*
    if(beatlines.count()!=0){
        for (int i=0;i<beatlines.count();i++){
            BeatLine* line=new BeatLine(canvas,beatlines[i]);
            line->setPen(green);
            int x=beatlines[i]/zoomRatio;
            line->setPoints(x,0,x,visibleHeight());
            line->show();
        }
    }
    */
    //cout<<"Drawing "<<lockedBeatlines.count()<<" locked beatlines\n";
    if(lockedBeatlines.count()!=0){
        for (uint i=0;i<lockedBeatlines.count();i++){
            BeatLine* line=new BeatLine(canvas,lockedBeatlines[i].position);
            line->lock();
            line->setZ(10);
            line->setDrawHandles(0);
            line->setX(line->getBeatPos() / zoomRatio);
            line->setPen(green);
            int x=lockedBeatlines[i].position/zoomRatio;
            line->setPoints(x,0,x,visibleHeight());
            line->show();
        }
    }
}


/*!
    \fn EffectPortFrame::removeBeatlines()
 */
void EffectPortFrame::removeBeatlines()
{
    QCanvasItemList items=canvas->allItems();
    if(!items.isEmpty()){
        QCanvasItemList::iterator it;
        for ( it = items.begin(); it != items.end(); ++it ){
            if((*it)->rtti()==RTTI_BEATLINE){
                (*it)->hide();
                delete (*it);
            }
        }
    }
}

/*!
    \fn EffectPortFrame::getNearestLinePos(QPoint)
 */
void EffectPortFrame::getNearestLinePos(QPoint pos,long& sample_pos,int& x)
{
    QCanvasItemList colisions=canvas->collisions(pos);
    if(!colisions.isEmpty()){
        QCanvasItemList::iterator it;
        for ( it = colisions.begin(); it != colisions.end(); ++it ){
            if((*it)->rtti()==RTTI_BEATLINE){
                BeatLine* temp=(BeatLine*)(*it);
                x=int(temp->x());
                sample_pos=temp->getBeatPos();
                    //cout<<"x: "<<x<<" sample_pos: "<<sample_pos<<endl;
            }
        }
    }
}





/*!
    \fn EffectPortFrame::getPortNumber()
 */
int EffectPortFrame::getPortNumber()
{
    return port->getPortNumber();
}


/*!
    \fn EffectPortFrame::hasPolyline()
 */
bool EffectPortFrame::hasPolyline()
{
    return (polyLine && polyLine->isVisible() && polyLine->count()>0);
}


/*!
    \fn EffectPortFrame::hasSpline()
 */
bool EffectPortFrame::hasSpline()
{
    return (spline && spline->isVisible() && spline->count()>0);
}


/*!
    \fn EffectPortFrame::getPolyline()
 */
PolyLine* EffectPortFrame::getPolyline()
{
    return polyLine;
}


/*!
    \fn EffectPortFrame::getSpline()
 */
SplineLine* EffectPortFrame::getSpline()
{
    return spline;
}


/*!
    \fn EffectPortFrame::setPolylineData(QValueList<SortablePoint>)
 */
void EffectPortFrame::setPolylineData(QValueList<SortablePoint> points)
{
    drawMode=DRAW_MODE_POLYLINES;
    for (uint i=0;i<points.count();i++){
        points[i].setX(points[i].getSamplePos()/zoomRatio);
        points[i].setY(valToYPos(points[i].getValue()));
    }
    polyLine->setSortablePoints(points);
    polyLine->show();
}


/*!
    \fn EffectPortFrame::setSplineData(QValueList<SplinePoint>)
 */
void EffectPortFrame::setSplineData(QValueList<SplinePoint> points)
{
    drawMode=DRAW_MODE_SPLINES;
    for (uint i=0;i<points.count();i++){
        points[i].setX(points[i].getSamplePos()/zoomRatio);
        points[i].setY(valToYPos(points[i].getValue()));
        points[i].cp1.setX(points[i].cp1.getSamplePos()/zoomRatio);
        points[i].cp1.setY(valToYPos(points[i].cp1.getValue()));
        points[i].cp2.setX(points[i].cp2.getSamplePos()/zoomRatio);
        points[i].cp2.setY(valToYPos(points[i].cp2.getValue()));
    }
    spline->setSplinePoints(points);
    spline->show();
}


/*!
    \fn EffectPortFrame::valToYPos(float val)
 */
int EffectPortFrame::valToYPos(float val)
{
    float max=port->getUpperBound();
    float min=port->getLowerBound();
    return int(MyMath::linear_regression(min,max,visibleHeight(),0,val));
}


/*!
    \fn EffectPortFrame::reinitLADSPAValues()
 */
void EffectPortFrame::reinitLADSPAValues()
{
    cout<<"reiniting ladspa control values\n";
    port->initControlValues();
    QCanvasItemList l=canvas->allItems();
    for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
        if((*it)->rtti()==RTTI_VALUELINE){
            (*it)->hide();
            delete (*it);
        }
    }
    linesCreated=FALSE;
    drawValueLines();
    drawBeatlines();
    spline->clear();
    polyLine->clear();
    canvas->setAllChanged();
    canvas->update();
}




/*!
    \fn EffectPortFrame::contentsMoved(int x, int y)
 */
void EffectPortFrame::contentsMoved(int x, int /*y*/)
{
    canvas->setStartX(x);
    canvas->setVisibleWidth(visibleWidth());
    canvas->setAllChanged();
    canvas->update();
}


/*!
    \fn EffectPortFrame::crop(long start, long end)
 */
void EffectPortFrame::crop(long start, long end)
{
    cout<<"cropping port frame\n";
    if (hasPolyline()) polyLine->crop(start,end);
    if (hasSpline()) spline->crop(start,end);
    long rest=1024-(start%1024);
    port->crop(start,end);
    QCanvasItemList l=canvas->allItems();
    for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
            if((*it)->rtti()==RTTI_VALUELINE){
                ValueLine* templine=(ValueLine*)(*it);
                if(templine->getSamplePos()<start || templine->getSamplePos()>=end){
                    templine->hide();
                    delete templine;
                }else{
                    templine->setSamplePos(templine->getSamplePos()-start-rest);
                    templine->setValuePointer(port->getVOTPointer((int)(templine->getSamplePos()/1024)));
                }
            }
    }
    drawValueLines();
}
