/* libs/graphics/animator/SkSVGPath.cpp
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/

#include <ctype.h>
#include "SkDrawPath.h"
#include "SkParse.h"
#include "SkPoint.h"
#include "SkUtils.h"
#define QUADRATIC_APPROXIMATION 1

#if QUADRATIC_APPROXIMATION
////////////////////////////////////////////////////////////////////////////////////
//functions to approximate a cubic using two quadratics

//      midPt sets the first argument to be the midpoint of the other two
//      it is used by quadApprox
static inline void midPt(SkPoint& dest,const SkPoint& a,const SkPoint& b)
{
    dest.set(SkScalarAve(a.fX, b.fX),SkScalarAve(a.fY, b.fY));
}
//      quadApprox - makes an approximation, which we hope is faster
static void quadApprox(SkPath &fPath, const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)
{
    //divide the cubic up into two cubics, then convert them into quadratics
    //define our points
    SkPoint c,j,k,l,m,n,o,p,q, mid;
    fPath.getLastPt(&c);
    midPt(j, p0, c);
    midPt(k, p0, p1);
    midPt(l, p1, p2);
    midPt(o, j, k);
    midPt(p, k, l);
    midPt(q, o, p);
    //compute the first half
    m.set(SkScalarHalf(3*j.fX - c.fX), SkScalarHalf(3*j.fY - c.fY));
    n.set(SkScalarHalf(3*o.fX -q.fX), SkScalarHalf(3*o.fY - q.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,q);
    c = q;
    //compute the second half
    m.set(SkScalarHalf(3*p.fX - c.fX), SkScalarHalf(3*p.fY - c.fY));
    n.set(SkScalarHalf(3*l.fX -p2.fX),SkScalarHalf(3*l.fY -p2.fY));
    midPt(mid,m,n);
    fPath.quadTo(mid,p2);
}
#endif


static inline bool is_between(int c, int min, int max)
{
    return (unsigned)(c - min) <= (unsigned)(max - min);
}

static inline bool is_ws(int c)
{
    return is_between(c, 1, 32);
}

static inline bool is_digit(int c)
{
    return is_between(c, '0', '9');
}

static inline bool is_sep(int c)
{
    return is_ws(c) || c == ',';
}

static const char* skip_ws(const char str[])
{
    SkASSERT(str);
    while (is_ws(*str))
        str++;
    return str;
}

static const char* skip_sep(const char str[])
{
    SkASSERT(str);
    while (is_sep(*str))
        str++;
    return str;
}

static const char* find_points(const char str[], SkPoint value[], int count,
     bool isRelative, SkPoint* relative)
{
    str = SkParse::FindScalars(str, &value[0].fX, count * 2);
    if (isRelative) {
        for (int index = 0; index < count; index++) {
            value[index].fX += relative->fX;
            value[index].fY += relative->fY;
        }
    }
    return str;
}

static const char* find_scalar(const char str[], SkScalar* value, 
    bool isRelative, SkScalar relative)
{
    str = SkParse::FindScalar(str, value);
    if (isRelative)
        *value += relative;
    return str;
}

void SkDrawPath::parseSVG() {
    fPath.reset();
    const char* data = d.c_str();
    SkPoint f = {0, 0};
    SkPoint c = {0, 0};
    SkPoint lastc = {0, 0};
    SkPoint points[3];
    char op = '\0';
    char previousOp = '\0';
    bool relative = false;
    do {
        data = skip_ws(data);
        if (data[0] == '\0')
            break;
        char ch = data[0];
        if (is_digit(ch) || ch == '-' || ch == '+') {
            if (op == '\0')
                return;
        }
        else {
            op = ch;
            relative = false;
            if (islower(op)) {
                op = (char) toupper(op);
                relative = true;
            }
            data++;
            data = skip_sep(data);
        }
        switch (op) {
            case 'M':
                data = find_points(data, points, 1, relative, &c);
                fPath.moveTo(points[0]);
                op = 'L';
                c = points[0];
                break;
            case 'L': 
                data = find_points(data, points, 1, relative, &c);
                fPath.lineTo(points[0]);
                c = points[0];
                break;
            case 'H': {
                SkScalar x;
                data = find_scalar(data, &x, relative, c.fX);
                fPath.lineTo(x, c.fY);
                c.fX = x;
            }
                break;
            case 'V': {
                SkScalar y;
                data = find_scalar(data, &y, relative, c.fY);
                fPath.lineTo(c.fX, y);
                c.fY = y;
            }
                break;
            case 'C': 
                data = find_points(data, points, 3, relative, &c);
                goto cubicCommon;
            case 'S': 
                data = find_points(data, &points[1], 2, relative, &c);
                points[0] = c;
                if (previousOp == 'C' || previousOp == 'S') {
                    points[0].fX -= lastc.fX - c.fX;
                    points[0].fY -= lastc.fY - c.fY;
                }
            cubicCommon:
    //          if (data[0] == '\0')
    //              return;
#if QUADRATIC_APPROXIMATION
                    quadApprox(fPath, points[0], points[1], points[2]);
#else   //this way just does a boring, slow old cubic
                    fPath.cubicTo(points[0], points[1], points[2]);
#endif
        //if we are using the quadApprox, lastc is what it would have been if we had used
        //cubicTo
                    lastc = points[1];
                    c = points[2];
                break;
            case 'Q':  // Quadratic Bezier Curve
                data = find_points(data, points, 2, relative, &c);
                goto quadraticCommon;
            case 'T':
                data = find_points(data, &points[1], 1, relative, &c);
                points[0] = points[1];
                if (previousOp == 'Q' || previousOp == 'T') {
                    points[0].fX = c.fX * 2 - lastc.fX;
                    points[0].fY = c.fY * 2 - lastc.fY;
                }
            quadraticCommon:
                fPath.quadTo(points[0], points[1]);
                lastc = points[0];
                c = points[1];
                break;
            case 'Z':
                fPath.close();
#if 0   // !!! still a bug?
                if (fPath.isEmpty() && (f.fX != 0 || f.fY != 0)) {
                    c.fX -= SkScalar.Epsilon;   // !!! enough?
                    fPath.moveTo(c);
                    fPath.lineTo(f);
                    fPath.close();
                }
#endif
                c = f;
                op = '\0';
                break;
            case '~': {
                SkPoint args[2];
                data = find_points(data, args, 2, false, NULL);
                fPath.moveTo(args[0].fX, args[0].fY);
                fPath.lineTo(args[1].fX, args[1].fY);
            }
                break;
            default:
                SkASSERT(0);
                return;
        }
        if (previousOp == 0)
            f = c;
        previousOp = op;
    } while (data[0] > 0);
}

