
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
//          mcseemagg@yahoo.com
//          http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PATH_STORAGE_INCLUDED
#define AGG_PATH_STORAGE_INCLUDED
#include "agg_basics.h"
namespace agg
{
class path_storage 
{
    enum block_scale_e {
        block_shift = 8,
        block_size  = 1 << block_shift,
        block_mask  = block_size - 1,
        block_pool  = 256
    };
public:
    class vertex_source 
    {
    public:
        vertex_source() {}
        vertex_source(const path_storage& p) : m_path(&p), m_vertex_idx(0) {}
        void rewind(unsigned path_id)
        {
            m_vertex_idx = path_id;
        }
        unsigned vertex(FX_FLOAT* x, FX_FLOAT* y)
        {
            return (m_vertex_idx < m_path->total_vertices()) ?
                   m_path->vertex(m_vertex_idx++, x, y) :
                   path_cmd_stop;
        }
    private:
        const path_storage* m_path;
        unsigned            m_vertex_idx;
    };
    ~path_storage();
    path_storage();
    unsigned last_vertex(FX_FLOAT* x, FX_FLOAT* y) const;
    unsigned prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const;
    void move_to(FX_FLOAT x, FX_FLOAT y);
    void line_to(FX_FLOAT x, FX_FLOAT y);
    void curve4(FX_FLOAT x_ctrl1, FX_FLOAT y_ctrl1,
                FX_FLOAT x_ctrl2, FX_FLOAT y_ctrl2,
                FX_FLOAT x_to,    FX_FLOAT y_to);
    template<class VertexSource>
    void add_path(VertexSource& vs,
                  unsigned path_id = 0,
                  bool solid_path = true)
    {
        FX_FLOAT x, y;
        unsigned cmd;
        vs.rewind(path_id);
        while(!is_stop(cmd = vs.vertex(&x, &y))) {
            if(is_move_to(cmd) && solid_path && m_total_vertices) {
                cmd = path_cmd_line_to;
            }
            add_vertex(x, y, cmd);
        }
    }
    template<class VertexSource>
    void add_path_curve(VertexSource& vs,
                        unsigned path_id = 0,
                        bool solid_path = true)
    {
        FX_FLOAT x, y;
        unsigned cmd;
        int flag;
        vs.rewind(path_id);
        while(!is_stop(cmd = vs.vertex_curve_flag(&x, &y, flag))) {
            if(is_move_to(cmd) && solid_path && m_total_vertices) {
                cmd = path_cmd_line_to | flag;
            }
            add_vertex(x, y, cmd | flag);
        }
    }
    unsigned total_vertices() const
    {
        return m_total_vertices;
    }
    unsigned vertex(unsigned idx, FX_FLOAT* x, FX_FLOAT* y) const
    {
        unsigned nb = idx >> block_shift;
        const FX_FLOAT* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
        *x = *pv++;
        *y = *pv;
        return m_cmd_blocks[nb][idx & block_mask];
    }
    unsigned command(unsigned idx) const
    {
        return m_cmd_blocks[idx >> block_shift][idx & block_mask];
    }
    unsigned getflag(unsigned idx) const
    {
        return m_cmd_blocks[idx >> block_shift][idx & block_mask] & path_flags_jr;
    }
    void     rewind(unsigned path_id);
    unsigned vertex(FX_FLOAT* x, FX_FLOAT* y);
    void add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd);
    void end_poly();
private:
    void allocate_block(unsigned nb);
    unsigned char* storage_ptrs(FX_FLOAT** xy_ptr);
private:
    unsigned        m_total_vertices;
    unsigned        m_total_blocks;
    unsigned        m_max_blocks;
    FX_FLOAT**   m_coord_blocks;
    unsigned char** m_cmd_blocks;
    unsigned        m_iterator;
};
inline unsigned path_storage::vertex(FX_FLOAT* x, FX_FLOAT* y)
{
    if(m_iterator >= m_total_vertices) {
        return path_cmd_stop;
    }
    return vertex(m_iterator++, x, y);
}
inline unsigned path_storage::prev_vertex(FX_FLOAT* x, FX_FLOAT* y) const
{
    if(m_total_vertices > 1) {
        return vertex(m_total_vertices - 2, x, y);
    }
    return path_cmd_stop;
}
inline unsigned path_storage::last_vertex(FX_FLOAT* x, FX_FLOAT* y) const
{
    if(m_total_vertices) {
        return vertex(m_total_vertices - 1, x, y);
    }
    return path_cmd_stop;
}
inline unsigned char* path_storage::storage_ptrs(FX_FLOAT** xy_ptr)
{
    unsigned nb = m_total_vertices >> block_shift;
    if(nb >= m_total_blocks) {
        allocate_block(nb);
    }
    *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
    return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
}
inline void path_storage::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd)
{
    FX_FLOAT* coord_ptr = 0;
    unsigned char* cmd_ptr = storage_ptrs(&coord_ptr);
    *cmd_ptr = (unsigned char)cmd;
    *coord_ptr++ = x;
    *coord_ptr   = y;
    m_total_vertices++;
}
inline void path_storage::move_to(FX_FLOAT x, FX_FLOAT y)
{
    add_vertex(x, y, path_cmd_move_to);
}
inline void path_storage::line_to(FX_FLOAT x, FX_FLOAT y)
{
    add_vertex(x, y, path_cmd_line_to);
}
}
#endif
