
// IndexedStrokedPath.hpp - interface for an indexed stroked path for polar stroking

#ifndef __IndexedStrokedPath_hpp__
#define __IndexedStrokedPath_hpp__

#include <GL/glew.h>
#include <vector>

#include <Cg/double.hpp>
#include <Cg/vector/xyzw.hpp>
#include <Cg/vector.hpp>

using namespace Cg;

#include "countof.h"

using std::vector;

// A stroke link is a path segment, join, or cap.
// Each link is rendered as a patch with 6 input vertices.
// A stroke link is represented by an array of 6 vertex array indexes.
struct StrokeLink {
    GLuint ndx[6];

    inline void swapIndices(int i, int j) {
        GLuint tmp = ndx[i];
        ndx[i] = ndx[j];
        ndx[j] = tmp;
    }
};

// A stroked path is "baked" into an array of stroke links and their
// corresponding path coordinates for efficient GPU tessellator rendering.
class IndexedStrokedPath {
#ifdef __GNUC__  // Workaround for gcc 4.8.4 complaining in STL headers about Cg::__CGvector<float,2> not being a type
    float2 bogus;
#endif

protected:
    vector<StrokeLink> link;
    vector<float> coord;

public:
    // Methods for accessing resulting link & cp arrays.
    inline size_t numCoords() const { return coord.size(); }
    inline size_t numLinks() const { return link.size(); }
    inline const float& Coord(size_t i) { return coord[i]; }
    inline const StrokeLink& Link(size_t i) const { return link[i]; }
    inline size_t indicesPerLink() { return countof(link[0].ndx); }

    const StrokeLink& ClampedLink(int i) const;
    float2 cp_back();
    void cp_push_back(const float2& cp);
    float2 cp(size_t i);

    void swap(IndexedStrokedPath& other);
};

#endif // __IndexedStrokedPath_hpp__
