
/*
 * 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"
#include <QtGui>

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()));
    connect(&fGLWidget, SIGNAL(drawComplete()), this->parentWidget(), SLOT(drawComplete()));
}

SkCanvasWidget::~SkCanvasWidget() {}

void SkCanvasWidget::drawTo(int index) {
    fDebugger->setIndex(index);
    fRasterWidget.updateImage();
#if SK_SUPPORT_GPU
    fGLWidget.updateImage();
#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());
}
