//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.1
// Copyright (C) 2002-2004 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_FONT_WIN32_TT_INCLUDED
#define AGG_FONT_WIN32_TT_INCLUDED

#include <windows.h>
#include "agg_scanline_storage_aa.h"
#include "agg_scanline_storage_bin.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_path_storage_integer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_font_cache_manager.h"

namespace agg
{

    //------------------------------------------------------------------------
    class font_engine_win32_tt
    {
       enum { buf_size = 32768-32 };

    public:
        //--------------------------------------------------------------------
        typedef path_storage_integer<int16, 6>            path_type;
        typedef serialized_integer_path_adaptor<int16, 6> path_adaptor_type;
        typedef serialized_scanlines_adaptor_aa<int8u>    gray8_adaptor_type;
        typedef serialized_scanlines_adaptor_bin          mono_adaptor_type;
        typedef scanline_storage_aa8                      scanlines_aa_type;
        typedef scanline_storage_bin                      scanlines_bin_type;

        //--------------------------------------------------------------------
        ~font_engine_win32_tt();
        font_engine_win32_tt(HDC dc, unsigned max_fonts = 32);

        // Set font parameters
        //--------------------------------------------------------------------
        void resolution(unsigned dpi) { m_resolution = unsigned(dpi); }
        void height(double h)         { m_height = unsigned(h);  }
        void width(double w)          { m_width = unsigned(w);   }
        void weight(int w)            { m_weight = w;            }
        void italic(bool it)          { m_italic = it;           }
        void underline(bool u)        { m_underline = u;         }
        void strikeout(bool s)        { m_strikeout = s;         }
        void char_set(DWORD c)        { m_char_set = c;          }
        void pitch_and_family(DWORD p){ m_pitch_and_family = p; }
        void flip_y(bool flip)        { m_flip_y = flip;         }
        void hinting(bool h)          { m_hinting = h;           }
        bool create_font(const char* typeface_, glyph_rendering ren_type);

        bool create_font(const char* typeface_, 
                         glyph_rendering ren_type,
                         double height_,
                         double width_=0.0,
                         int weight_=FW_REGULAR,
                         bool underline_=false,
                         bool strikeout_=false,
                         DWORD char_set_=ANSI_CHARSET,
                         DWORD pitch_and_family_=FF_DONTCARE);

        // Set Gamma
        //--------------------------------------------------------------------
        template<class GammaF> void gamma(const GammaF& f)
        {
            m_rasterizer.gamma(f);
        }

        // Accessors
        //--------------------------------------------------------------------
        unsigned    resolution()   const { return m_resolution; }
        const char* typeface()     const { return m_typeface;   }
        double      height()       const { return m_height;     }
        double      width()        const { return m_width;      }
        int         weight()       const { return m_weight;     }
        bool        italic()       const { return m_italic;     }
        bool        underline()    const { return m_underline;  }
        bool        strikeout()    const { return m_strikeout;  }
        DWORD       char_set()     const { return m_char_set;   }
        DWORD       pitch_and_family() const { return m_pitch_and_family; }
        bool        hinting()      const { return m_hinting;    }
        bool        flip_y()       const { return m_flip_y;     }


        // Interface mandatory to implement for font_cache_manager
        //--------------------------------------------------------------------
        const char*     font_signature() const { return m_signature;    }
        int             change_stamp()   const { return m_change_stamp; }

        bool            prepare_glyph(unsigned glyph_code);
        unsigned        glyph_index() const { return m_glyph_index; }
        unsigned        data_size()   const { return m_data_size;   }
        glyph_data_type data_type()   const { return m_data_type;   }
        const rect&     bounds()      const { return m_bounds;      }
        double          advance_x()   const { return m_advance_x;   }
        double          advance_y()   const { return m_advance_y;   }
        void            write_glyph_to(int8u* data) const;
        bool            add_kerning(unsigned first, unsigned second,
                                    double* x, double* y);

    private:
        void update_signature();
        static bool pair_less(const KERNINGPAIR v1, const KERNINGPAIR v2);
        void load_kerning_pairs();
        void sort_kerning_pairs();
        int  find_font(const char* name) const;

        HDC             m_dc;
        HFONT           m_old_font;
        HFONT*          m_fonts;
        unsigned        m_num_fonts;
        unsigned        m_max_fonts;
        char**          m_font_names;
        HFONT           m_cur_font;

        int             m_change_stamp;
        char*           m_typeface;
        unsigned        m_typeface_len;
        char*           m_signature;
        unsigned        m_height;
        unsigned        m_width;
        int             m_weight;
        bool            m_italic;
        bool            m_underline;
        bool            m_strikeout;
        DWORD           m_char_set;
        DWORD           m_pitch_and_family;
        bool            m_hinting;
        bool            m_flip_y;

        bool            m_font_created;
        unsigned        m_resolution;
        glyph_rendering m_glyph_rendering;
        unsigned        m_glyph_index;
        unsigned        m_data_size;
        glyph_data_type m_data_type;
        rect            m_bounds;
        double          m_advance_x;
        double          m_advance_y;
        MAT2            m_mat2;
        char*           m_gbuf;
        KERNINGPAIR*    m_kerning_pairs;
        unsigned        m_num_kerning_pairs;
        unsigned        m_max_kerning_pairs;


        path_type                m_path;
        conv_curve<path_type>    m_curves;
        scanline_u8              m_scanline_aa;
        scanline_bin             m_scanline_bin;
        scanlines_aa_type        m_scanlines_aa;
        scanlines_bin_type       m_scanlines_bin;
        rasterizer_scanline_aa<> m_rasterizer;
    };

}

#endif
