#import <UIKit/UIKit.h>

#include "SkStream_NSData.h"
#include "SkTypeface.h"
#include "SkFontHost.h"
#include "SkThread.h"
#include "SkTemplates.h"

enum FontDesign {
    kUnknown_Design,
    kSans_FontDesign,
    kSerif_FontDesign,

    kIllegal_FontDesign,    // never use with a real font
};

// returns kIllegal_FontDesign if not found
static FontDesign find_design_from_name(const char name[]) {
    static const struct {
        const char* fName;
        FontDesign  fDesign;
    } gRec[] = {
        { "sans-serif", kSans_FontDesign },
        { "serif",      kSerif_FontDesign },
    };

    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
        if (!strcasecmp(name, gRec[i].fName)) {
            return gRec[i].fDesign;
        }
    }
    return kIllegal_FontDesign;
}

struct FontRes {
    const char*         fName;
    SkTypeface::Style   fStyle;
    FontDesign          fDesign;
};

static const FontRes gFontRes[] = {
    { "DroidSans",          SkTypeface::kNormal,    kSans_FontDesign    },
    { "DroidSans",          SkTypeface::kBold,      kSans_FontDesign    },
    { "DroidSerif-Regular", SkTypeface::kNormal,    kSerif_FontDesign    },
    { "DroidSerif-Bold",    SkTypeface::kBold,      kSerif_FontDesign    },
//    { "PescaderoPro",       SkTypeface::kNormal,    kSerif_FontDesign   },
//    { "PescaderoPro-Bold",  SkTypeface::kBold,      kSerif_FontDesign   },
};
#define FONTRES_COUNT SK_ARRAY_COUNT(gFontRes)

#define DEFAULT_INDEX_REGULAR   1
#define DEFAULT_INDEX_BOLD      2

///////////////////////////////////////////////////////////////////////////////

class SkTypeface_Stream : public SkTypeface {
public:
    SkTypeface_Stream(SkStream* stream, Style style);
    virtual ~SkTypeface_Stream();

    SkStream* refStream() {
        fStream->ref();
        return fStream;
    }

private:
    SkStream*   fStream;
};

static int32_t gUniqueFontID;

SkTypeface_Stream::SkTypeface_Stream(SkStream* stream, Style style)
: SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
    fStream = stream;
    fStream->ref();
}

SkTypeface_Stream::~SkTypeface_Stream() {
    fStream->unref();
}

static SkTypeface_Stream* create_from_fontres(const FontRes& res) {
    SkStream* stream = SkStream_NSData::CreateFromResource(res.fName, "ttf");
    SkAutoUnref aur(stream);

    return SkNEW_ARGS(SkTypeface_Stream, (stream, res.fStyle));
}

///////////////////////////////////////////////////////////////////////////////

static int compute_style_distance(SkTypeface::Style a, SkTypeface::Style b) {
    int dist = 0;
    int diff = a ^ b;
    if (diff & SkTypeface::kBold) {
        dist += 2;
    }
    if (diff & SkTypeface::kItalic) {
        dist += 1;
    }
    return dist;
}

static SkTypeface_Stream* gFonts[FONTRES_COUNT];

static void assure_init_fonts() {
    static bool gOnce;
    if (!gOnce) {
        for (size_t i = 0; i < FONTRES_COUNT; i++) {
            gFonts[i] = create_from_fontres(gFontRes[i]);
            gOnce = true;
        }
    }
}

static SkTypeface_Stream* get_default_font(SkTypeface::Style style) {
    assure_init_fonts();

    if (style & SkTypeface::kBold) {
        return gFonts[DEFAULT_INDEX_BOLD];
    } else {
        return gFonts[DEFAULT_INDEX_REGULAR];
    }
}

static SkTypeface_Stream* find_by_id(SkFontID fontID) {
    assure_init_fonts();
    
    for (size_t i = 0; i < FONTRES_COUNT; i++) {
        if (gFonts[i]->uniqueID() == fontID) {
            return gFonts[i];
        }
    }
    return NULL;
}

///////////////////////////////////////////////////////////////////////////////

template <typename T> T* ref_and_return(T* obj) {
    obj->ref();
    return obj;
}

SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
                                     const char familyName[],
                                     const void* data, size_t bytelength,
                                     SkTypeface::Style style) {
    assure_init_fonts();

    if (familyName) {
        FontDesign design = find_design_from_name(familyName);
        if (kIllegal_FontDesign != design) {
            familyName = "$#@*&%*#$@ never match any name";
        }

        int bestDistance = 999;
        int bestIndex = -1;
        for (size_t i = 0; i < FONTRES_COUNT; i++) {
            if (design == gFontRes[i].fDesign || !strcmp(gFontRes[i].fName, familyName)) {
                int dist = compute_style_distance(style, gFontRes[i].fStyle);
                if (dist < bestDistance) {
                    bestDistance = dist;
                    bestIndex = i;
                }
            }
        }
        if (bestIndex >= 0) {
            return ref_and_return(gFonts[bestIndex]);
        }
    }

    return ref_and_return(get_default_font(style));
}

SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
    SkASSERT(!"SkFontHost::CreateTypeface unimplemented");
    return NULL;
}

SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
//    SkASSERT(!"SkFontHost::CreateTypefaceFromFile unimplemented");
    return NULL;
}

///////////////////////////////////////////////////////////////////////////////

SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
    SkTypeface_Stream* tf = find_by_id(uniqueID);
    SkASSERT(tf);
    return tf->refStream();
}

size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
                               int32_t* index) {
    SkDebugf("SkFontHost::GetFileName unimplemented\n");
    return 0;
}

///////////////////////////////////////////////////////////////////////////////

void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
    SkASSERT(!"SkFontHost::Serialize unimplemented");
}

SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
    int style = stream->readU8();
    int len = stream->readPackedUInt();
    const char* name = NULL;
    if (len > 0) {
        SkString str;
        str.resize(len);
        stream->read(str.writable_str(), len);
        
        if (str.startsWith("DroidSans")) {
            name = "sans-serif";
        } else if (str.startsWith("DroidSerif")) {
            name = "serif";
        }
        SkDebugf("---- deserialize typeface <%s> %d %s\n", str.c_str(), style, name);
    }
//    name = NULL; style = 0;
    return SkFontHost::CreateTypeface(NULL, name, NULL, NULL,
                                      (SkTypeface::Style)style);
}

SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
    return 0;
}

#define FONT_CACHE_MEMORY_BUDGET    1 * 1024 * 1024

size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
    if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
        return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
    else
        return 0;   // nothing to do
}

///////////////////////////////////////////////////////////////////////////////
int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
    return 0;
}

void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
    tables[0] = NULL;   // black gamma (e.g. exp=1.4)
    tables[1] = NULL;   // white gamma (e.g. exp= 1/1.4)
}

// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
                                                                  uint32_t fontID,
                                                                  SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
    SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
    return NULL;
}

void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
}

SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
    SkASSERT(!"SkFontHost::CreateScalarContext unimplemented");
    return NULL;
}