/*
 *  CAUTION: EXPERIMENTAL CODE
 *
 *  This code is not to be used and will not be supported
 *  if it fails on you. DO NOT USE!
 *
 */

#include "SkPathUtils.h"

#include "SkPath.h"
#include "SkPathOps.h" // this can't be found, how do I link it?
#include "SkRegion.h"

typedef void (*line2path)(SkPath*, const char*, int, int);
#define SQRT_2 1.41421356237f
#define ON  0xFF000000 // black pixel
#define OFF 0x00000000 // transparent pixel

// assumes stride is in bytes
/*
static void FillRandomBits( int chars, char* bits ){
    SkTime time;
    SkRandom rand = SkRandom( time.GetMSecs() );

    for (int i = 0; i < chars; ++i){
        bits[i] = rand.nextU();
    }
}OA
*/

static int GetBit( const char* buffer, int x ) {
    int byte = x >> 3;
    int bit = x & 7;

    return buffer[byte] & (128 >> bit);
}

/*
static void Line2path_pixel(SkPath* path, const char* line,
                            int lineIdx, int width) {
    for (int i = 0; i < width; ++i) {
        // simply makes every ON pixel into a rect path
        if (GetBit(line,i)) {
            path->addRect(SkRect::MakeXYWH(i, lineIdx, 1, 1),
                          SkPath::kCW_Direction);
        }
    }
}

static void Line2path_pixelCircle(SkPath* path, const char* line,
                                  int lineIdx, int width) {
    for (int i = 0; i < width; ++i) {
        // simply makes every ON pixel into a circle path
        if (GetBit(line,i)) {
            path->addCircle(i + SK_ScalarHalf,
                            lineIdx + SK_ScalarHalf,
                            SQRT_2 / 2.0f);
        }
    }
}
*/

static void Line2path_span(SkPath* path, const char* line,
                           int lineIdx, int width) {
    bool inRun = 0;
    int start = 1;

    for (int i = 0; i < width; ++i) {
        int curPixel = GetBit(line,i);

        if ( (curPixel!=0) != inRun ) { // if transition
            if (curPixel) { // if transition on
                inRun = 1;
                start = i; // mark beginning of span
            }else { // if transition off add the span as a path
                inRun = 0;
                path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx),
                                               SkIntToScalar(i-start), SK_Scalar1),
                              SkPath::kCW_Direction);
            }
        }
    }

    if (inRun==1) { // close any open spans
        int end = 0;
        if ( GetBit(line,width-1) ) ++end;
        path->addRect(SkRect::MakeXYWH(SkIntToScalar(start), SkIntToScalar(lineIdx),
                                       SkIntToScalar(width - 1 + end - start), SK_Scalar1),
                      SkPath::kCW_Direction);
    } else if ( GetBit(line, width - 1) ) { // if last pixel on add
        path->addRect(SkRect::MakeXYWH(width - SK_Scalar1, SkIntToScalar(lineIdx),
                                       SK_Scalar1, SK_Scalar1),
                      SkPath::kCW_Direction);
    }
}

void SkPathUtils::BitsToPath_Path(SkPath* path,
                        const char* bitmap,
                        int w, int h, int stride) {
    // loop for every line in bitmap
    for (int i = 0; i < h; ++i) {
        // fn ptr handles each line separately
        //l2p_fn(path, &bitmap[i*stride], i, w);
        Line2path_span(path, &bitmap[i*stride], i, w);
    }
    Simplify(*path, path); // simplify resulting path.
}

void SkPathUtils::BitsToPath_Region(SkPath* path,
                               const char* bitmap,
                               int w, int h, int stride) {
    SkRegion region;

    // loop for each line
    for (int y = 0; y < h; ++y){
        bool inRun = 0;
        int start = 1;
        const char* line = &bitmap[y * stride];

        // loop for each pixel
        for (int i = 0; i < w; ++i) {
            int curPixel = GetBit(line,i);

            if ( (curPixel!=0) != inRun ) { // if transition
                if (curPixel) { // if transition on
                    inRun = 1;
                    start = i; // mark beginning of span
                }else { // if transition off add the span as a path
                    inRun = 0;
                    //add here
                    region.op(SkIRect::MakeXYWH(start, y, i-start, 1),
                              SkRegion::kUnion_Op );
                }
            }
        }
        if (inRun==1) { // close any open spans
            int end = 0;
            if ( GetBit(line,w-1) ) ++end;
            // add the thing here
            region.op(SkIRect::MakeXYWH(start, y, w-1-start+end, 1),
                      SkRegion::kUnion_Op );

        } else if ( GetBit(line,w-1) ) { // if last pixel on add rect
            // add the thing here
            region.op(SkIRect::MakeXYWH(w-1, y, 1, 1),
                      SkRegion::kUnion_Op );
        }
    }
    // convert region to path
    region.getBoundaryPath(path);
}
