
/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrTraceMarker.h"
#include "GrTracing.h"
#include "SkString.h"
#include "SkTSort.h"

////////////////////////////////////////////////////////////////////////////////

class GrTraceMarkerSet::Iter {
public:
    Iter() {};
    Iter& operator=(const Iter& i) {
        fCurrentIndex = i.fCurrentIndex;
        fMarkers = i.fMarkers;
        return *this;
    }
    bool operator==(const Iter& i) const {
        return fCurrentIndex == i.fCurrentIndex && fMarkers == i.fMarkers;
    }
    bool operator!=(const Iter& i) const { return !(*this == i); }
    const GrGpuTraceMarker& operator*() const { return fMarkers->fMarkerArray[fCurrentIndex]; }
    Iter& operator++() {
        SkASSERT(*this != fMarkers->end());
        ++fCurrentIndex;
        return *this;
    }

private:
    friend class GrTraceMarkerSet;
    Iter(const GrTraceMarkerSet* markers, int index)
            : fMarkers(markers), fCurrentIndex(index) {
        SkASSERT(markers);
    }

    const GrTraceMarkerSet* fMarkers;
    int fCurrentIndex;
};

////////////////////////////////////////////////////////////////////////////////

GrTraceMarkerSet::GrTraceMarkerSet(const GrTraceMarkerSet& other) {
   this->addSet(other);
}

void GrTraceMarkerSet::add(const GrGpuTraceMarker& marker) {
    this->fMarkerArray.push(marker);
}

void GrTraceMarkerSet::addSet(const GrTraceMarkerSet& markerSet) {
    for (Iter iter = markerSet.begin(); iter != markerSet.end(); ++iter) {
        this->add(*iter);
    }
}

void GrTraceMarkerSet::remove(const GrGpuTraceMarker& marker) {
    SkASSERT(-1 != fMarkerArray.find(marker));
    int index = this->fMarkerArray.find(marker);
    this->fMarkerArray.remove(index);
}

int GrTraceMarkerSet::count() const {
    return this->fMarkerArray.count();
}

SkString GrTraceMarkerSet::toString() const {
    SkTQSort<GrGpuTraceMarker>(this->fMarkerArray.begin(), this->fMarkerArray.end() - 1);
    SkString marker_string;
    const char* prevMarkerName = "";
    int prevMarkerID = -1;
    int counter = 0;
    const int numMarkers = this->fMarkerArray.count();

    // check used for GrGpuGL device after we've already collapsed all markers
    if (1 == numMarkers && -1 == this->fMarkerArray[0].fID) {
        marker_string.append(this->fMarkerArray[0].fMarker);
        return marker_string;
    }

    for (int i = 0; i < numMarkers; ++i ) {
        GrGpuTraceMarker& currMarker = this->fMarkerArray[i];
        const char* currCmd = currMarker.fMarker;
        if (currCmd != prevMarkerName) {
            if (counter != 0) {
                marker_string.append(") ");
            }
            marker_string.append(currCmd);
            marker_string.append("(");
            marker_string.appendS32(currMarker.fID);
            prevMarkerName = currCmd;
        } else if (currMarker.fID != prevMarkerID) {
            marker_string.append(", ");
            marker_string.appendS32(currMarker.fID);
        }
        prevMarkerID = currMarker.fID;
        ++counter;
    }
    if (counter > 0) {
        marker_string.append(")");
    }
    return marker_string;
}

GrTraceMarkerSet::Iter GrTraceMarkerSet::begin() const {
    return Iter(this, 0);
}

GrTraceMarkerSet::Iter GrTraceMarkerSet::end() const {
    return Iter(this, this->fMarkerArray.count());
}
