/*
 * Copyright (C) 2003, 2006, 2009 Apple Inc. All rights reserved.
 *               2006 Rob Buis <buis@kde.org>
 * Copyright (C) 2007-2008 Torch Mobile, Inc.
 * Copyright (C) 2013 Google Inc. 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.
 */

#ifndef Path_h
#define Path_h

#include "core/platform/graphics/RoundedRect.h"
#include "core/platform/graphics/WindRule.h"
#include "third_party/skia/include/core/SkPath.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Forward.h"

class SkPath;

namespace WebCore {

class AffineTransform;
class FloatPoint;
class FloatRect;
class FloatSize;
class GraphicsContext;
class StrokeData;

enum PathElementType {
    PathElementMoveToPoint, // The points member will contain 1 value.
    PathElementAddLineToPoint, // The points member will contain 1 value.
    PathElementAddQuadCurveToPoint, // The points member will contain 2 values.
    PathElementAddCurveToPoint, // The points member will contain 3 values.
    PathElementCloseSubpath // The points member will contain no values.
};

// The points in the sturcture are the same as those that would be used with the
// add... method. For example, a line returns the endpoint, while a cubic returns
// two tangent points and the endpoint.
struct PathElement {
    PathElementType type;
    FloatPoint* points;
};

typedef void (*PathApplierFunction)(void* info, const PathElement*);

class Path {
    WTF_MAKE_FAST_ALLOCATED;
public:
    Path();
    ~Path();

    Path(const Path&);
    Path& operator=(const Path&);
    bool operator==(const Path&) const;

    bool contains(const FloatPoint&, WindRule = RULE_NONZERO) const;
    bool strokeContains(const FloatPoint&, const StrokeData&) const;
    FloatRect boundingRect() const;
    FloatRect strokeBoundingRect(const StrokeData&) const;

    float length() const;
    FloatPoint pointAtLength(float length, bool& ok) const;
    float normalAngleAtLength(float length, bool& ok) const;
    bool pointAndNormalAtLength(float length, FloatPoint&, float&) const;

    void clear();
    bool isEmpty() const;
    // Gets the current point of the current path, which is conceptually the final point reached by the path so far.
    // Note the Path can be empty (isEmpty() == true) and still have a current point.
    bool hasCurrentPoint() const;
    FloatPoint currentPoint() const;

    WindRule windRule() const;
    void setWindRule(const WindRule);

    void moveTo(const FloatPoint&);
    void addLineTo(const FloatPoint&);
    void addQuadCurveTo(const FloatPoint& controlPoint, const FloatPoint& endPoint);
    void addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& controlPoint2, const FloatPoint& endPoint);
    void addArcTo(const FloatPoint&, const FloatPoint&, float radius);
    void closeSubpath();

    void addArc(const FloatPoint&, float radius, float startAngle, float endAngle, bool anticlockwise);
    void addRect(const FloatRect&);
    void addEllipse(const FloatRect&);

    void addRoundedRect(const FloatRect&, const FloatSize& roundingRadii);
    void addRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
    void addRoundedRect(const RoundedRect&);

    void translate(const FloatSize&);

    const SkPath& skPath() const { return m_path; }

    void apply(void* info, PathApplierFunction) const;
    void transform(const AffineTransform&);

    void addPathForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);
    void addBeziersForRoundedRect(const FloatRect&, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius);

    // Updates the path to the union (inclusive-or) of itself with the given argument.
    bool unionPath(const Path& other);

private:
    SkPath m_path;
};

}

#endif
