
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkCanvasWidget.h"

SkCanvasWidget::SkCanvasWidget(QWidget* parent,
        SkDebugger* debugger) : QWidget(parent)
    , fHorizontalLayout(this)
    , fRasterWidget(debugger)
#if SK_SUPPORT_GPU
    , fGLWidget(debugger)
#endif
{

    fDebugger = debugger;

    fHorizontalLayout.setSpacing(6);
    fHorizontalLayout.setContentsMargins(0,0,0,0);
    fRasterWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);
#if SK_SUPPORT_GPU
    fGLWidget.setSizePolicy(QSizePolicy::Expanding,
            QSizePolicy::Expanding);
#endif

    fHorizontalLayout.addWidget(&fRasterWidget);
#if SK_SUPPORT_GPU
    fHorizontalLayout.addWidget(&fGLWidget);
#endif

    fPreviousPoint.set(0,0);
    fUserMatrix.reset();

#if SK_SUPPORT_GPU
    setWidgetVisibility(kGPU_WidgetType, true);
#endif
    connect(&fRasterWidget, SIGNAL(drawComplete()),
            this->parentWidget(), SLOT(drawComplete()));
}

SkCanvasWidget::~SkCanvasWidget() {}

void SkCanvasWidget::drawTo(int index) {
    fDebugger->setIndex(index);
    fRasterWidget.draw();
#if SK_SUPPORT_GPU
    fGLWidget.draw();
#endif
    emit commandChanged(fDebugger->index());
}

void SkCanvasWidget::mouseMoveEvent(QMouseEvent* event) {
    SkIPoint eventPoint = SkIPoint::Make(event->globalX(), event->globalY());
    SkIPoint eventOffset = eventPoint - fPreviousPoint;
    fPreviousPoint = eventPoint;
    fUserMatrix.postTranslate(eventOffset.fX, eventOffset.fY);
    fDebugger->setUserMatrix(fUserMatrix);
    drawTo(fDebugger->index());
}

void SkCanvasWidget::mousePressEvent(QMouseEvent* event) {
    fPreviousPoint.set(event->globalX(), event->globalY());
    emit hitChanged(fDebugger->getCommandAtPoint(event->x(), event->y(),
            fDebugger->index()));
}

void SkCanvasWidget::mouseDoubleClickEvent(QMouseEvent* event) {
    Qt::KeyboardModifiers modifiers = event->modifiers();
    if (modifiers.testFlag(Qt::ControlModifier)) {
        snapWidgetTransform();
    } else {
        resetWidgetTransform();
    }
}

#define ZOOM_FACTOR (1.25f)

void SkCanvasWidget::wheelEvent(QWheelEvent* event) {
    Qt::KeyboardModifiers modifiers = event->modifiers();
    if (modifiers.testFlag(Qt::ControlModifier)) {
        zoom(event->delta() > 0 ? ZOOM_FACTOR : (1.0f / ZOOM_FACTOR), event->x(), event->y());
    } else {
        if (Qt::Horizontal == event->orientation()) {
            fUserMatrix.postTranslate(event->delta(), 0.0f);
        } else {
            fUserMatrix.postTranslate(0.0f, event->delta());
        }
        fDebugger->setUserMatrix(fUserMatrix);
        drawTo(fDebugger->index());
    }
}

void SkCanvasWidget::zoom(int zoomCommand) {
    zoom(kIn_ZoomCommand == zoomCommand ? ZOOM_FACTOR : (1.0f / ZOOM_FACTOR),
         this->size().width() / 2, this->size().height() / 2);
}

void SkCanvasWidget::snapWidgetTransform() {
    double x, y;
    modf(fUserMatrix.getTranslateX(), &x);
    modf(fUserMatrix.getTranslateY(), &y);
    fUserMatrix[SkMatrix::kMTransX] = x;
    fUserMatrix[SkMatrix::kMTransY] = y;
    fDebugger->setUserMatrix(fUserMatrix);
    drawTo(fDebugger->index());
}

void SkCanvasWidget::resetWidgetTransform() {
    fUserMatrix.reset();
    fDebugger->setUserMatrix(fUserMatrix);
    emit scaleFactorChanged(fUserMatrix.getScaleX());
    drawTo(fDebugger->index());
}

void SkCanvasWidget::setWidgetVisibility(WidgetType type, bool isHidden) {
    if (type == kRaster_8888_WidgetType) {
        fRasterWidget.setHidden(isHidden);
    }
#if SK_SUPPORT_GPU
    else if (type == kGPU_WidgetType) {
        fGLWidget.setHidden(isHidden);
    }
#endif
}

#if SK_SUPPORT_GPU
void SkCanvasWidget::setGLSampleCount(int sampleCount)
{
    fGLWidget.setSampleCount(sampleCount);
}
#endif

void SkCanvasWidget::zoom(float scale, int px, int py) {
    fUserMatrix.postScale(scale, scale, px, py);
    emit scaleFactorChanged(fUserMatrix.getScaleX());
    fDebugger->setUserMatrix(fUserMatrix);
    drawTo(fDebugger->index());
}
