
// CommonStrokeTessellatorPrivate.hpp - internal common declarations to evaluate polar stroking geometry on CPU

#ifndef __CommonStrokeTessellatorPrivate_hpp__
#define __CommonStrokeTessellatorPrivate_hpp__

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

using namespace Cg;

#define ARC_LENGTH_TEXGEN 1

# define StrokeTessellatorMETHOD CPUStrokeTessellator::
// Use GlobalNamespace or StdNamespace to avoid ambiguous overloads in C++
# define GlobalNamespace ::
# define StdNamespace std::
# define CgNamespace Cg::
# define CONST const
# ifdef __GNUC__
#  define STATIC static __attribute__ ((unused)) // Unfortunately GLSL lacks static (also allow unused)
# else
#  define STATIC static
# endif
# define OUTPARAM(type) type&
# define INOUTPARAM(type) type&
# ifdef __GNUC__
#  define UNUSED __attribute__ ((unused))  // Avoid warnings about unused variables or functions
# else
#  define UNUSED
# endif

//// Link type enumeration
#define LT_CUBIC_SEGMENT       (-3)
#define LT_QUADRATIC_SEGMENT   (-2)
#define LT_JOIN                (-1) // This value and all larger values are caps or joins (see isJoinOrCap)
#define LT_NO_CAP              (0)  // This value and all larger values are caps (see isCap)
#define LT_ROUND_CAP_PRE_REMAP (1)  // This later gets remapped to LT_HEMICIRCLE_CAP
#define LT_TRIANGULAR_CAP      (2)
#define LT_SQUARE_CAP          (3)
#define LT_HEMICIRCLE_CAP      (max_steps)

// Return max(a,b) except if one is NaN, always return the other.
template <typename REAL>
inline REAL safe_max(REAL a, REAL b)
{
    if (a > b) {
        return a;
    } else {
        if (Cg::isnan(b)) {
            return a;
        } else {
            return b;
        }
    }
}

// Return min(a,b) except if one is NaN, always return the other.
template <typename REAL>
inline REAL safe_min(REAL a, REAL b)
{
    if (a < b) {
        return a;
    } else {
        if (Cg::isnan(b)) {
            return a;
        } else {
            return b;
        }
    }
}

// Emulate GLSL vector types.
// XXX should we be using FakeGLSLTypes?
typedef Cg::float2 vec2;
typedef Cg::float3 vec3;
typedef Cg::int2 ivec2;

//#include "polar/tangent_change_map.hpp"

#endif // __CommonStrokeTessellatorPrivate_hpp__
