/*
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "core/platform/graphics/PathTraversalState.h"

#include "core/svg/SVGPathTraversalStateBuilder.h"

namespace WebCore {

SVGPathTraversalStateBuilder::SVGPathTraversalStateBuilder()
    : m_traversalState(0)
{
}

void SVGPathTraversalStateBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode)
{
    ASSERT(m_traversalState);
    m_traversalState->m_totalLength += m_traversalState->moveTo(targetPoint);
}

void SVGPathTraversalStateBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode)
{
    ASSERT(m_traversalState);
    m_traversalState->m_totalLength += m_traversalState->lineTo(targetPoint);
}

void SVGPathTraversalStateBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode)
{
    ASSERT(m_traversalState);
    m_traversalState->m_totalLength += m_traversalState->cubicBezierTo(point1, point2, targetPoint);
}

void SVGPathTraversalStateBuilder::closePath()
{
    ASSERT(m_traversalState);
    m_traversalState->m_totalLength += m_traversalState->closeSubpath();
}

void SVGPathTraversalStateBuilder::setDesiredLength(float desiredLength)
{
    ASSERT(m_traversalState);
    m_traversalState->m_desiredLength = desiredLength;
}

bool SVGPathTraversalStateBuilder::continueConsuming()
{
    ASSERT(m_traversalState);    
    m_traversalState->processSegment();
    return !m_traversalState->m_success;
}

void SVGPathTraversalStateBuilder::incrementPathSegmentCount()
{
    ASSERT(m_traversalState);
    ++m_traversalState->m_segmentIndex;
}

unsigned SVGPathTraversalStateBuilder::pathSegmentIndex()
{
    ASSERT(m_traversalState);
    return m_traversalState->m_segmentIndex;
}

float SVGPathTraversalStateBuilder::totalLength()
{
    ASSERT(m_traversalState);
    return m_traversalState->m_totalLength;
}

SVGPoint SVGPathTraversalStateBuilder::currentPoint()
{
    ASSERT(m_traversalState);
    return m_traversalState->m_current;
}

}
