
//----------------------------------------------------------------------------
// 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 : public CFX_Object
{
    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 CFX_Object
    {
    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
