#include <boost/gil/typedefs.hpp>
#include <boost/gil/extension/io/png_dynamic_io.hpp>
#include <freegil.hpp>

using namespace boost::gil;

//GCC Build String
//g++ sample2.cpp -lpng -lz -I . -I ~/lib/freetype2/include -I ~/lib/boost -I ~/lib -L ~/lib/freetype2 -lfreetype

//REMEMBER TO SEND IN THE FULL PATH TO THE FONT

struct glyph
{
        char ch;
        FT_Face face;
        boost::gil::rgb8_pixel_t color;
};

struct make_glyph
{
        FT_Face face;   
        make_glyph(FT_Face face) : face(face) {}               
        boost::shared_ptr<glyph> operator()(char ch)
        {
                using namespace boost::gil;
                glyph* u = new glyph();
                u->ch = ch;
                u->color = rgb8_pixel_t(0,0,0);
                u->face = face;
                return boost::shared_ptr<glyph>(u);
        }
};

int main(int args, char** argv)
{
        assert(args == 2);
        char* font_path = argv[1];

        //Step 1. Create boost::gil image
        //Step 2. Initialize freetype
        //Step 3. Make Glyphs Array
        //Step 4. Make Metrics Array
        //Step 5. Make Kerning Array
        //Step 6. Get Coordinates (x,y)
        //Step 7. Render Glyphs on GIL View
        //Step 8. Save GIL Image
       
        //Step 1. Create boost::gil image -----------
       
        rgb8_image_t img(200,200);
        boost::gil::fill_pixels(boost::gil::view(img),
                boost::gil::rgb8_pixel_t(170,170,170));

        //Step 2. Initialize freetype ---------------
       
        FT_Library library;
        FT_Init_FreeType(&library);
       
        FT_Face face;
        FT_New_Face(library,argv[1],0,&face);
        FT_Set_Pixel_Sizes(face,0,12);

        //Step 3. Make Glyphs Array ------------------
       
        std::string str = "World";
        std::vector<boost::shared_ptr<glyph> > glyphs;
        std::transform(str.begin(),str.end(),
                std::back_inserter(glyphs), make_glyph(face));

        //Step 4. Make Metrics Array --------------------
       
        std::vector<FT_Glyph_Metrics> metrics;                 
        std::transform(glyphs.begin(),glyphs.end(),
                std::back_inserter(metrics), make_metric());

        //Step 5. Make Kerning Array ----------------
       
        std::vector<int> kerning;                      
        std::transform(glyphs.begin(),glyphs.end(),
                std::back_inserter(kerning), make_kerning());

        //Step 6. Get Coordinates (x,y) ----------------

        int width = std::for_each(metrics.begin(), metrics.end(),
                kerning.begin(), make_width());
        int height = std::for_each(metrics.begin(), metrics.end(),
                kerning.begin(), make_width());
        int x = (boost::gil::view(img).width()-width)/2;
        int y = (boost::gil::view(img).height()-height)/2;

        //Step 7. Render Glyphs ------------------------
       
        std::for_each(glyphs.begin(), glyphs.end(), kerning.begin(),
                boost::gil::render_gray_glyph<rgb8_view_t>(boost::gil::subimage_view(
                        boost::gil::view(img),x,y,width,height)));

        //Step 8. Save GIL Image ---------------------
       
        png_write_view("sample2.png", boost::gil::view(img));
}