/** @file
 * libLASi provides a C++ output stream interface for writing multi-language Postscript documents.
 * Copyright (C) 2003  Larry Siden.
 * See README file in project root directory for copyright and contact info.
 * See COPYING file in project root for terms of re-distribution.
 */

#include "util.h"
#include <sstream>
#include <iostream>

#include <ft2build.h>
#include FT_FREETYPE_H

using namespace std;


static const std::string glyph_format_to_string(const FT_Glyph_Format format) {
  if (0 == format)
    return "none";

  string s;
  s.append(1, (char)((format & 0xff000000) >> 24));
  s.append(1, (char)((format & 0x00ff0000) >> 16));
  s.append(1, (char)((format & 0x0000ff00) >> 8));
  s.append(1, (char)((format & 0x000000ff)));
  return s;
}

static const std::string tag_to_string(const int tag) {
  switch (tag & 0x03) {
    case FT_Curve_Tag_On:
      return "on";

    case FT_Curve_Tag_Conic:
      return "conic";

    case FT_Curve_Tag_Cubic:
      return "cubic";

    default:
      ostringstream ostr;
      ostr << "0x" << hex << (int) tag << dec;
      return ostr.str();
  }
}

ostream& operator<<(ostream& os, const FT_Library ft_library) {
  os << "ft_library=" << hex << (unsigned char&)ft_library << dec << endl;
  FT_Int amajor, aminor, apatch;
  FT_Library_Version(ft_library, &amajor, &aminor, &apatch);
  os << "FreeType lib version " << amajor << "." << aminor << "-" << apatch << endl;
  return os;
}

ostream& operator<<(ostream& os, const FT_Face ft_face) {
  os << "ft_face=" << hex << (unsigned char&)ft_face << dec << endl;
  os << "family name: " << ft_face->family_name << endl;
  os << "style name: " << ft_face->family_name << endl;
  return os;
}

ostream& operator<<(ostream& os, const FT_Glyph ft_glyph) {
  os << "ft_glyph=" << hex << (unsigned char&)ft_glyph << dec << endl;
  os << "glyph format is " << glyph_format_to_string(ft_glyph->format) << endl;
  return os;
}

ostream& operator<<(ostream& os, const FT_Outline outline) {
  os << "n_contours=" << outline.n_contours << ", n_points=" << outline.n_points << endl;
  //const FT_Vector* pEndVector = &outline.points[outline.n_points];
  int ipt = 0; // i-th point in outline.points[]
  
  for (int iContour=0 ; iContour < outline.n_contours ; ++iContour) {
    os << "countour[" << iContour << "]=" << outline.contours[iContour] << endl;
    
    for (; ipt <= outline.contours[iContour] ; ++ipt) {
      const FT_Vector ftvec = outline.points[ipt];
      const char tag = outline.tags[ipt];
      
      os << ftvec.x / 64.0 << " " << ftvec.y / 64.0 << "  " << tag_to_string(tag) << endl;
    }
  }
  return os;
}
