
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "SkSVGGradient.h"
#include "SkSVGParser.h"
#include "SkSVGStop.h"

SkSVGGradient::SkSVGGradient() {
}

SkSVGElement* SkSVGGradient::getGradient() {
    return this;
}

bool SkSVGGradient::isDef() {
    return true;
}

bool SkSVGGradient::isNotDef() {
    return false;
}

void SkSVGGradient::translate(SkSVGParser& parser, bool defState) {
    INHERITED::translate(parser, defState);
    // !!! no support for 'objectBoundingBox' yet
    bool first = true;
    bool addedFirst = false;
    bool addedLast = false;
    SkString offsets("[");
    SkString* lastOffset = NULL;
    for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkASSERT((*ptr)->getType() == SkSVGType_Stop);
        SkSVGStop* stop = (SkSVGStop*) *ptr;
        if (first && stop->f_offset.equals("0") == false) {
            addedFirst = true;
            offsets.append("0,");
        }
        SkString* thisOffset = &stop->f_offset;
        if (lastOffset && thisOffset->equals(*lastOffset)) {
            if (thisOffset->equals("1")) {
                offsets.remove(offsets.size() - 2, 2);
                offsets.append(".999,");
            } else {
                SkASSERT(0); // !!! need to write this case
            }
        }
        offsets.append(*thisOffset);
        if (ptr == fChildren.end() - 1) { // last
            if (stop->f_offset.equals("1") == false) {
                offsets.append(",1");
                addedLast = true;
            }
        } else
            offsets.appendUnichar(',');
        first = false;
        lastOffset = thisOffset;
    }
    offsets.appendUnichar(']');
    parser._addAttribute("offsets", offsets);
    if (addedFirst)
        parser.translate(*fChildren.begin(), defState);
    for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++)
        parser.translate(*ptr, defState);
    if (addedLast)
        parser.translate(*(fChildren.end() - 1), defState);
}

void SkSVGGradient::translateGradientUnits(SkString& units) {
    // !!! no support for 'objectBoundingBox' yet
    SkASSERT(strcmp(units.c_str(), "userSpaceOnUse") == 0);
}

void SkSVGGradient::write(SkSVGParser& parser, SkString& baseColor) {
    if (baseColor.c_str()[0] != '#')
        return;
    SkSVGPaint* saveHead = parser.fHead;
    parser.fHead = &fPaintState;
    parser.fSuppressPaint = true;
    SkString originalID(f_id);
    f_id.set("mask"); // write out gradient named given name + color (less initial #)
    f_id.append(baseColor.c_str() + 1);
    SkString originalColors;
    for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkSVGStop* colorElement = (SkSVGStop*) *ptr;
        SkString& color = colorElement->fPaintState.f_stopColor;
        originalColors.append(color);
        originalColors.appendUnichar(',');
        SkASSERT(color.c_str()[0] == '#');
        SkString replacement;
        replacement.set("0x");
        replacement.append(color.c_str() + 1, 2); // add stop colors using given color, turning existing stop color into alpha
        SkASSERT(baseColor.c_str()[0] == '#');
        SkASSERT(baseColor.size() == 7);
        replacement.append(baseColor.c_str() + 1);
        color.set(replacement);
    }
    translate(parser, true);
    const char* originalPtr = originalColors.c_str(); // restore original gradient values
    for (SkSVGElement** ptr = fChildren.begin(); ptr < fChildren.end(); ptr++) {
        SkSVGStop* color = (SkSVGStop*) *ptr;
        const char* originalEnd = strchr(originalPtr, ',');
        color->fPaintState.f_stopColor.set(originalPtr, originalEnd - originalPtr);
        originalPtr = originalEnd + 1;
    }
    f_id.set(originalID);
    parser.fSuppressPaint = false;
    parser.fHead = saveHead;
}
