/*
 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Path.h"

#include "FloatRect.h"
#include <QPainterPath>
#include <QMatrix>

#include <math.h>

namespace WebCore {

Path::Path()
    : m_path(new QPainterPath())
{
}

Path::~Path()
{
    delete m_path;
    m_path = 0;
}

Path::Path(const Path& other)
    : m_path(new QPainterPath(*other.platformPath()))
{
}

Path& Path::operator=(const Path& other)
{
    if (&other != this) {
        delete m_path;
        m_path = new QPainterPath(*other.platformPath());
    }

    return *this;
}

bool Path::contains(const FloatPoint& point) const
{
    return m_path->contains(point);
}

void Path::translate(const FloatSize& size)
{
    QMatrix matrix;
    matrix.translate(size.width(), size.height());
    *m_path = (*m_path) * matrix;
}

FloatRect Path::boundingRect() const
{
    return m_path->boundingRect();
}

void Path::moveTo(const FloatPoint& point)
{
    m_path->moveTo(point);
}

void Path::addLineTo(const FloatPoint& p)
{
    m_path->lineTo(p);
}

void Path::addQuadCurveTo(const FloatPoint& cp, const FloatPoint& p)
{
    m_path->quadTo(cp, p);
}

void Path::addBezierCurveTo(const FloatPoint& cp1, const FloatPoint& cp2, const FloatPoint& p)
{
    m_path->cubicTo(cp1, cp2, p);
}

void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius)
{
    //FIXME: busted
    qWarning("arcTo is busted");
    m_path->arcTo(p1.x(), p1.y(), p2.x(), p2.y(), radius, 90);
}

void Path::closeSubpath()
{
    m_path->closeSubpath();
}

#define DEGREES(t) ((t) * 180.0 / M_PI)
void Path::addArc(const FloatPoint& p, float r, float sar, float ear, bool anticlockwise)
{
    qreal xc = p.x();
    qreal yc = p.y();
    qreal radius = r;


    //### HACK
    // In Qt we don't switch the coordinate system for degrees
    // and still use the 0,0 as bottom left for degrees so we need
    // to switch
    sar = -sar;
    ear = -ear;
    anticlockwise = !anticlockwise;
    //end hack

    float sa = DEGREES(sar);
    float ea = DEGREES(ear);

    double span = 0;

    double xs = xc - radius;
    double ys = yc - radius;
    double width  = radius*2;
    double height = radius*2;

    if (!anticlockwise && (ea < sa))
        span += 360;
    else if (anticlockwise && (sa < ea))
        span -= 360;

    // this is also due to switched coordinate system
    // we would end up with a 0 span instead of 360
    if (!(qFuzzyCompare(span + (ea - sa), 0.0) &&
          qFuzzyCompare(abs(span), 360.0))) {
        span += ea - sa;
    }

    m_path->moveTo(QPointF(xc + radius  * cos(sar),
                          yc - radius  * sin(sar)));

    m_path->arcTo(xs, ys, width, height, sa, span);
}

void Path::addRect(const FloatRect& r)
{
    m_path->addRect(r.x(), r.y(), r.width(), r.height());
}

void Path::addEllipse(const FloatRect& r)
{
    m_path->addEllipse(r.x(), r.y(), r.width(), r.height());
}

void Path::clear()
{
    *m_path = QPainterPath();
}

}

// vim: ts=4 sw=4 et
