void UBGraphicsVideoItemDelegate::buildButtons()
{
    mPlayPauseButton = new DelegateButton(":/images/play.svg", mDelegated, mFrame);

    mStopButton = new DelegateButton(":/images/stop.svg", mDelegated, mFrame);
    mStopButton->hide();

    if (delegated()->isMuted())
        mMuteButton = new DelegateButton(":/images/soundOff.svg", mDelegated, mFrame);
    else
        mMuteButton = new DelegateButton(":/images/soundOn.svg", mDelegated, mFrame);

    mMuteButton->hide();

    mVideoControl = new DelegateVideoControl(delegated(), mFrame);
    mVideoControl->setZValue(UBGraphicsScene::toolLayerStart + 2);
    mVideoControl->setFlag(QGraphicsItem::ItemIsSelectable, true);

    connect(mPlayPauseButton, SIGNAL(clicked(bool)), this, SLOT(togglePlayPause()));
    connect(mStopButton, SIGNAL(clicked(bool)), mMedia, SLOT(stop()));
    connect(mMuteButton, SIGNAL(clicked(bool)), delegated(), SLOT(toggleMute()));
    connect(mMuteButton, SIGNAL(clicked(bool)), this, SLOT(toggleMute()));

    mButtons << mPlayPauseButton << mStopButton << mMuteButton;

    mMedia->setTickInterval(50);

    connect(mMedia, SIGNAL(stateChanged (Phonon::State, Phonon::State)), this, SLOT(mediaStateChanged (Phonon::State, Phonon::State)));
    connect(mMedia, SIGNAL(finished()), this, SLOT(updatePlayPauseState()));
    connect(mMedia, SIGNAL(tick(qint64)), this, SLOT(updateTicker(qint64)));
    connect(mMedia, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));

}
void UBGraphicsMediaItemDelegate::buildButtons()
{
    if(!mPlayPauseButton){
        mPlayPauseButton = new DelegateButton(":/images/play.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
        connect(mPlayPauseButton, SIGNAL(clicked(bool)),
                this, SLOT(togglePlayPause()));

        mStopButton = new DelegateButton(":/images/stop.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
        connect(mStopButton, SIGNAL(clicked(bool)),
                delegated(), SLOT(stop()));

        mMediaControl = new DelegateMediaControl(delegated(), mToolBarItem);
        mMediaControl->setFlag(QGraphicsItem::ItemIsSelectable, true);
        UBGraphicsItem::assignZValue(mMediaControl, delegated()->zValue());

        if (delegated()->isMuted())
            mMuteButton = new DelegateButton(":/images/soundOff.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);
        else
            mMuteButton = new DelegateButton(":/images/soundOn.svg", mDelegated, mToolBarItem, Qt::TitleBarArea);

        connect(mMuteButton, SIGNAL(clicked(bool)),
                delegated(), SLOT(toggleMute()));
        connect(mMuteButton, SIGNAL(clicked(bool)),
                this, SLOT(toggleMute())); // for changing button image

        mToolBarButtons << mPlayPauseButton << mStopButton << mMuteButton;

        mToolBarItem->setItemsOnToolBar(QList<QGraphicsItem*>() << mPlayPauseButton << mStopButton << mMediaControl  << mMuteButton );
        mToolBarItem->setVisibleOnBoard(true);
        mToolBarItem->setShifting(false);

        if (!mToolBarShowTimer) {
            if (delegated()->hasLinkedImage()) {
                mToolBarShowTimer = new QTimer();
                mToolBarShowTimer->setInterval(m_iToolBarShowingInterval);
                connect(mToolBarShowTimer, SIGNAL(timeout()), this, SLOT(hideToolBar()));
            }
        }

        else {
            connect(mPlayPauseButton, SIGNAL(clicked(bool)),
                    mToolBarShowTimer, SLOT(start()));

            connect(mStopButton, SIGNAL(clicked(bool)),
                    mToolBarShowTimer, SLOT(start()));

            connect(mMediaControl, SIGNAL(used()),
                    mToolBarShowTimer, SLOT(start()));

            connect(mMuteButton, SIGNAL(clicked(bool)),
                    mToolBarShowTimer, SLOT(start()));
        }


        positionHandles();
    }
void UBGraphicsVideoItemDelegate::remove(bool canUndo)
{
    if (delegated() && delegated()->mediaObject())
        delegated()->mediaObject()->stop();

    QGraphicsScene* scene = mDelegated->scene();

    scene->removeItem(mVideoControl);

    UBGraphicsItemDelegate::remove(canUndo);
}
void UBGraphicsDelegateFrame::initializeTransform()
{
    QTransform itemTransform = delegated()->sceneTransform();
    QRectF itemRect = delegated()->boundingRect();
    QPointF topLeft = itemTransform.map(itemRect.topLeft());
    QPointF topRight = itemTransform.map(itemRect.topRight());
    QPointF  bottomLeft = itemTransform.map(itemRect.bottomLeft());

    qreal horizontalFlip = (topLeft.x() > topRight.x()) ? -1 : 1;
    mMirrorX = horizontalFlip < 0 ;
    if(horizontalFlip < 0) {
        // why this is because of the way of calculating the translations that checks which side is the most is the
        // nearest instead of checking which one is the left side.
        QPointF tmp = topLeft;
        topLeft = topRight;
        topRight = tmp;

        // because of the calculation of the height is done by lenght and not deltaY
        bottomLeft = itemTransform.map(itemRect.bottomRight());
    }

    qreal verticalFlip = (bottomLeft.y() < topLeft.y()) ? -1 : 1;
    // not sure that is usefull
    mMirrorY = verticalFlip < 0;
    if(verticalFlip < 0 && !mMirrorX) {
        topLeft = itemTransform.map(itemRect.bottomLeft());
        topRight = itemTransform.map(itemRect.bottomRight());
        bottomLeft = itemTransform.map(itemRect.topLeft());
    }

    QLineF topLine(topLeft, topRight);
    QLineF leftLine(topLeft, bottomLeft);
    qreal width = topLine.length();
    qreal height = leftLine.length();

    mAngle = topLine.angle();

    // the fact the the length is used we loose the horizontalFlip information
    // a better way to do this is using DeltaX that preserve the direction information.
    mTotalScaleX = (width / itemRect.width()) * horizontalFlip;
    mTotalScaleY = height / itemRect.height() * verticalFlip;

    QTransform tr;
    QPointF center = delegated()->boundingRect().center();
    tr.translate(center.x() * mTotalScaleX, center.y() * mTotalScaleY);
    tr.rotate(-mAngle);
    tr.translate(-center.x() * mTotalScaleX, -center.y() * mTotalScaleY);
    tr.scale(mTotalScaleX, mTotalScaleY);

    mTotalTranslateX = delegated()->transform().dx() - tr.dx();
    mTotalTranslateY = delegated()->transform().dy() - tr.dy();
}
UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, QObject * parent)
    : UBGraphicsItemDelegate(pDelegated, parent, GF_COMMON
                             | GF_RESPECT_RATIO
                             | GF_TOOLBAR_USED)
    , mPlayPauseButton(NULL)
    , mToolBarShowTimer(NULL)
    , m_iToolBarShowingInterval(5000)
{
    QPalette palette;
    palette.setBrush ( QPalette::Light, Qt::darkGray );

    if (delegated()->isMuted())
        delegated()->setMute(true);

}
void UBGraphicsDelegateFrame::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    mDelegate->startUndoStep();

    mStartingPoint = event->scenePos();

    initializeTransform();

    mScaleX = 1;
    mScaleY = 1;
    mTranslateX = 0;
    mTranslateY = 0;
    mAngleOffset = 0;

    mInitialTransform = buildTransform();
    mOriginalSize = delegated()->boundingRect().size();

    mCurrentTool = toolFromPos(event->pos());
    setCursorFromAngle(QString::number((int)mAngle % 360));
    event->accept();

    if (moving())
        prepareFramesToMove(getLinkedFrames());

}
void UBGraphicsVideoItemDelegate::updateTicker(qint64 time)
{
    Phonon::MediaObject* media = delegated()->mediaObject();
    mVideoControl->totalTimeChanged(media->totalTime());

    mVideoControl->updateTicker(time);
}
void UBGraphicsVideoItemDelegate::toggleMute()
{
    if (delegated()->isMuted())
        mMuteButton->setFileName(":/images/soundOff.svg");
    else
        mMuteButton->setFileName(":/images/soundOn.svg");

}
void UBGraphicsVideoItemDelegate::updatePlayPauseState()
{
    Phonon::MediaObject* media = delegated()->mediaObject();

    if (media->state() == Phonon::PlayingState)
        mPlayPauseButton->setFileName(":/images/pause.svg");
    else
        mPlayPauseButton->setFileName(":/images/play.svg");
}
/**
 * @brief Show the toolbar (play/pause, seek, mute).
 *
 * The toolbar then auto-hides after a set amount of time, if the video is currently
 * playing or is paused.
 */
void UBGraphicsMediaItemDelegate::showToolBar(bool autohide)
{
    mToolBarItem->show();
    if (mToolBarShowTimer) {

        if (delegated()->isPlaying() || delegated()->isPaused())
            mToolBarShowTimer->start();
        else
            mToolBarShowTimer->stop();

        // Don't hide the toolbar if we're at the beginning of the video
        if (delegated()->mediaPosition() == delegated()->initialPos())
            mToolBarShowTimer->stop();

        // Don't hide the toolbar if it was explicitly requested
        if (!autohide)
            mToolBarShowTimer->stop();
    }
}
QSizeF UBGraphicsDelegateFrame::resizeDelegate(qreal moveX, qreal moveY)
{
    QSizeF incVector;
    mFixedPoint = getFixedPointFromPos();

    UBResizableGraphicsItem* resizableItem = dynamic_cast<UBResizableGraphicsItem*>(delegated());
    if (resizableItem)
    {
        incVector = getResizeVector(moveX, moveY);
        resizableItem->resize(mOriginalSize + incVector);

        if (resizingTop() || resizingLeft() || ((mMirrorX || mMirrorY) && resizingBottomRight()))
        {
            QPointF pos1 = getFixedPointFromPos();
            delegated()->setPos(delegated()->pos()-pos1+mFixedPoint);
        }
    }

    return incVector;
}
QList<UBGraphicsDelegateFrame *> UBGraphicsDelegateFrame::getLinkedFrames()
{
    QList<UBGraphicsDelegateFrame*> linkedFrames;
    QList<QGraphicsItem*> sItems = mDelegate->delegated()->scene()->selectedItems();
    if (sItems.count())
    {
        sItems.removeAll(delegated());

        foreach(QGraphicsItem *item, sItems)
        {
            UBGraphicsItem *gitem = dynamic_cast<UBGraphicsItem*>(item);
            if (gitem)
                linkedFrames << gitem->Delegate()->frame();
        }
QPointF UBGraphicsDelegateFrame::getFixedPointFromPos()
{
    QPointF fixedPoint;
    if (!moving() && !rotating())
    {
        if (resizingTop())
        {
            if (mMirrorX && mMirrorY)
            {
                if ((0 < mAngle) && (mAngle < 90))
                    fixedPoint = delegated()->sceneBoundingRect().topLeft();
                else
                    fixedPoint = delegated()->sceneBoundingRect().topRight();
            }
            else
            {
                if ((0 < mAngle) && (mAngle <= 90))
                    fixedPoint = delegated()->sceneBoundingRect().bottomRight();
                else
                    fixedPoint = delegated()->sceneBoundingRect().bottomLeft();
            }
        }
        else if (resizingLeft())
        {
            if (mMirrorX && mMirrorY)
            {
                if ((0 < mAngle) && (mAngle < 90))
                    fixedPoint = delegated()->sceneBoundingRect().bottomLeft();
                else
                    fixedPoint = delegated()->sceneBoundingRect().topLeft();
            }
            else
            {
                if ((0 < mAngle) && (mAngle <= 90))
                    fixedPoint = delegated()->sceneBoundingRect().topRight();
                else
                    fixedPoint = delegated()->sceneBoundingRect().bottomRight();
            }
        }
    }
    return fixedPoint;
}
void UBGraphicsVideoItemDelegate::togglePlayPause()
{
    if (delegated() && delegated()->mediaObject())
    {
        Phonon::MediaObject* media = delegated()->mediaObject();

        if (media->state() == Phonon::StoppedState)
        {
            media->play();
        }
        else if (media->state() == Phonon::PlayingState)
        {
            if (media->remainingTime() <= 0)
            {
                media->stop();
                media->play();
            }
            else
            {
                media->pause();
                if(delegated()->scene())
                        delegated()->scene()->setModified(true);
            }
        }
        else if (media->state() == Phonon::PausedState)
        {
            if (media->remainingTime() <= 0)
            {
                media->stop();
            }

            media->play();
        }
		else  if ( media->state() == Phonon::LoadingState ){
            delegated()->mediaObject()->setCurrentSource(delegated()->mediaFileUrl());
            media->play();
        }
        else{
          qDebug() << "Media state "<< media->state() << " not supported";
        }
    }
}
UBGraphicsTextItemDelegate::UBGraphicsTextItemDelegate(UBGraphicsTextItem* pDelegated, QObject * parent)
    : UBGraphicsItemDelegate(pDelegated,0, parent, true)
    , mLastFontPixelSize(-1)
    , delta(5)
{
    delegated()->setData(UBGraphicsItemData::ItemEditable, QVariant(true));
    delegated()->setPlainText("");

    QTextCursor curCursor = delegated()->textCursor();
    QTextCharFormat format;
    QFont font(createDefaultFont());
    font.setPointSize(UBSettings::settings()->fontPointSize());

    format.setFont(font);
    curCursor.mergeCharFormat(format);
    delegated()->setTextCursor(curCursor);
    delegated()->setFont(font);

    delegated()->adjustSize();
    delegated()->contentsChanged();

    // NOOP
}
void UBGraphicsDelegateFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if (None == mCurrentTool)
        return;

    QLineF move = QLineF(mStartingPoint, event->scenePos());
    qreal moveX = move.length() * cos((move.angle() - mAngle) * PI / 180);
    qreal moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180);
    qreal width = delegated()->boundingRect().width() * mTotalScaleX;
    qreal height = delegated()->boundingRect().height() * mTotalScaleY;

    if (mOperationMode == Scaling)
    {
        if(!rotating())
        {
            mTranslateX = moveX;
            // Perform the resize
            if (resizingBottomRight())
            {
                // -----------------------------------------------------
                // ! We want to keep the aspect ratio with this resize !
                // -----------------------------------------------------
                qreal scaleX;
                qreal scaleY;

                if(!mMirrorX) {
                    scaleX = (width + moveX) / width;
                } else {
                    scaleX = (width - moveX) / width;
                }

                if(!mMirrorY) {
                    scaleY = (height + moveY) / height;
                } else {
                    scaleY = (height - moveY) / height;
                }

                qreal scaleFactor = (scaleX + scaleY) / 2;

                // Do not allow resizing of image size under frame size
                if (canResizeBottomRight(width, height, scaleFactor))
                {
                    if (mRespectRatio)
                    {
                        mScaleX = scaleFactor;
                        mScaleY = scaleFactor;
                    }
                    else
                    {
                        mScaleX = scaleX;
                        mScaleY = scaleY;
                    }
                }
            } else if (resizingLeft() || resizingRight())
            {
                if(width != 0) {
                    qreal scaleX = 0.0;
                    if(resizingLeft()) {
                        scaleX = (width - moveX) / width;
                    } else if(resizingRight()) {
                        scaleX = (width + moveX) / width;
                    }
                    if(mDelegate->isFlippable() && qAbs(scaleX) != 0) {
                        if((qAbs(width * scaleX)) < 2*mFrameWidth) {
                            bool negative = (scaleX < 0)?true:false;
                            if(negative) {
                                if(mMirrorX)
                                    scaleX = 2*mFrameWidth/width;
                                else
                                    scaleX = -2*mFrameWidth/width;
                            } else {
                                scaleX = -1;
                                mFlippedX = !mFlippedX;
                            }
                        }
                        mScaleX = scaleX;
                    } else if (scaleX > 1 || (width * scaleX) > 2 * mFrameWidth) {
                        mScaleX = scaleX;
                        if(resizingLeft()) {
                            mTranslateX = moveX;
                        }
                    }
                }
            } else if(resizingTop() || resizingBottom()) {
                if(height != 0) {
                    qreal scaleY = 0.0;
                    if(resizingTop()) {
                        scaleY = (height - moveY) / height;
                    } else if(resizingBottom()) {
                        scaleY = (height + moveY) / height;
                    }

                    if(mDelegate->isFlippable() && qAbs(scaleY) != 0) {
                        if((qAbs(height * scaleY)) < 2*mFrameWidth) {
                            bool negative = (scaleY < 0)?true:false;
                            if(negative) {
                                if(mMirrorY)
                                    scaleY = 2*mFrameWidth/width;
                                else
                                    scaleY = -2*mFrameWidth/width;
                            } else {
                                scaleY = -1;
                                mFlippedY = !mFlippedY;
                            }
                        }
                        mScaleY = scaleY;
                    } else if (scaleY > 1 || (height * scaleY) > 2 * mFrameWidth)
                    {
                        mScaleY = scaleY;
                        if(resizingTop()) {
                            mTranslateY = moveY;
                        }
                    }
                }
            }
        }
    }

    if (rotating())
    {
        mTranslateX = 0;
        mTranslateY = 0;

        QLineF startLine(sceneBoundingRect().center(), event->lastScenePos());
        QLineF currentLine(sceneBoundingRect().center(), event->scenePos());
        mAngle += startLine.angleTo(currentLine);

        if ((int)mAngle % 45 >= 45 - mAngleTolerance || (int)mAngle % 45 <= mAngleTolerance)
        {
            mAngle = qRound(mAngle / 45) * 45;
            mAngleOffset += startLine.angleTo(currentLine);
            if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance)
            {
                mAngle += mAngleOffset;
                mAngleOffset = 0;
            }
        }
        else if ((int)mAngle % 30 >= 30 - mAngleTolerance || (int)mAngle % 30 <= mAngleTolerance)
        {
            mAngle = qRound(mAngle / 30) * 30;
            mAngleOffset += startLine.angleTo(currentLine);
            if ((int)mAngleOffset % 360 > mAngleTolerance && (int)mAngleOffset % 360 < 360 - mAngleTolerance)
            {
                mAngle += mAngleOffset;
                mAngleOffset = 0;
            }
        }

        setCursorFromAngle(QString::number((int)mAngle % 360));
    }
    else if (moving())
    {
        mTranslateX = move.dx();
        mTranslateY = move.dy();
        moveLinkedItems(move);
    }

    if (mOperationMode == Scaling || moving() || rotating())
    {
        QTransform tr = buildTransform();

        if (resizingRight() || resizingBottom() || resizingBottomRight())
        {
            QPointF ref;

            // we just detects coordinates of corner before and after scaling and then moves object at diff between them.
            if (resizingBottomRight() && (mMirrorX || mMirrorY))
            {
                if (mFlippedX && !mMirrorX && mFlippedY)// && !mMirrorY)
                {
                    mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x();
                    mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y();
                }
                else if ((mFlippedX || mMirrorX) && (mFlippedY || mMirrorY))
                {
                    mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x();
                    mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y();
                }
                else if (mFlippedX || mMirrorX)
                {
                    mTranslateX += mInitialTransform.map(delegated()->boundingRect().topRight()).x() - tr.map(delegated()->boundingRect().topRight()).x();
                    mTranslateY += mInitialTransform.map(delegated()->boundingRect().topRight()).y() - tr.map(delegated()->boundingRect().topRight()).y();
                }
                else if (mFlippedY || mMirrorY)
                {
                    mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).x() - tr.map(delegated()->boundingRect().bottomLeft()).x();
                    mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomLeft()).y() - tr.map(delegated()->boundingRect().bottomLeft()).y();
                }
                else
                {
                    mTranslateX += mInitialTransform.map(delegated()->boundingRect().bottomRight()).x() - tr.map(delegated()->boundingRect().bottomRight()).x();
                    mTranslateY += mInitialTransform.map(delegated()->boundingRect().bottomRight()).y() - tr.map(delegated()->boundingRect().bottomRight()).y();
                }
            }
            else
            {
                mTranslateX += mInitialTransform.map(delegated()->boundingRect().topLeft()).x() - tr.map(delegated()->boundingRect().topLeft()).x();
                mTranslateY += mInitialTransform.map(delegated()->boundingRect().topLeft()).y() - tr.map(delegated()->boundingRect().topLeft()).y();
            }
        }
        else if (resizingTop() || resizingLeft())
        {
            QPointF bottomRight = tr.map(delegated()->boundingRect().bottomRight());
            QPointF fixedPoint = mInitialTransform.map(delegated()->boundingRect().bottomRight());
            mTranslateX += fixedPoint.x() - bottomRight.x();
            mTranslateY += fixedPoint.y() - bottomRight.y();
        }
        delegated()->setTransform(buildTransform());
    }
    else // resizing/resizing horizontally
    {

        if (resizingBottomRight())
        {
            static QSizeF incV = QSizeF();
            static QSizeF incH = QSizeF();

            if (mMirrorX && mMirrorY)
                mCurrentTool = ResizeTop;
            else
                mCurrentTool = ResizeBottom;

            incV = resizeDelegate(moveX, moveY);
            mOriginalSize += incV;

            if (mMirrorX && mMirrorY)
                mCurrentTool = ResizeLeft;
            else
                mCurrentTool = ResizeRight;

            move = QLineF(event->lastScenePos(), event->scenePos());
            moveX = move.length() * cos((move.angle() - mAngle) * PI / 180);
            moveY = -move.length() * sin((move.angle() - mAngle) * PI / 180);

            mFixedPoint = getFixedPointFromPos();

            incH = resizeDelegate(moveX, moveY);

            mOriginalSize -= incV;
            mOriginalSize += incH;

            mCurrentTool = ResizeBottomRight;
        }
        else
            resizeDelegate(moveX, moveY);
    }
    event->accept();
}
void UBGraphicsTextItemDelegate::contentsChanged()
{
    positionHandles();
    delegated()->contentsChanged();
}