
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include <jni.h>
#include <sys/time.h>
#include <time.h>
#include <android/log.h>
#include <stdint.h>

#include "GrContext.h"
#include "SkGpuCanvas.h"
#include "SkPaint.h"
#include "SkString.h"
#include "SkTime.h"

#include "gl/GrGLConfig.h"

static GrContext* make_context() {
    SkDebugf("---- before create\n");
    GrContext* ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, 0);
    SkDebugf("---- after create %p\n", ctx);
    return ctx;
}

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

void gr_run_unittests() {}

#include "FlingState.h"
#include "SkTouchGesture.h"
#include "SkView.h"

typedef SkView* (*SkViewFactory)();

// these values must match those in Ganesh.java
enum TouchState {
    kUnknown_TouchState,
    kDown_TouchState,
    kMoved_TouchState,
    kUp_TouchState
};

struct State {
    State();
    ~State();

    int countSlides() const { return fFactory.count(); }
    const char* getSlideTitle(int index) const;
    void chooseSlide(int index) {
        SkDebugf("----- index %d\n", index);
        if (index < fFactory.count()) {
            this->setView(fFactory[index]());
        }
    }

    void setViewport(int w, int h);
    int getWidth() const { return fViewport.fX; }
    int getHeight() const { return fViewport.fY; }
    
    void handleTouch(void*, TouchState, float x, float y);
    void applyMatrix(SkCanvas*);

    SkView* getView() const { return fView; }

private:
    SkView*     fView;
    SkIPoint    fViewport;
    
    SkTouchGesture fGesture;

    SkTDArray<SkViewFactory> fFactory;

    void setView(SkView* view) {
        SkSafeUnref(fView);
        fView = view;

        view->setVisibleP(true);
        view->setClipToBounds(false);
        view->setSize(SkIntToScalar(fViewport.fX),
                      SkIntToScalar(fViewport.fY));
    }
};

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

#include "SampleCode.h"

SkViewRegister* SkViewRegister::gHead;
SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
    static bool gOnce;
    if (!gOnce) {
        gHead = NULL;
        gOnce = true;
    }
    
    fChain = gHead;
    gHead = this;
}

static const char gCharEvtName[] = "SampleCode_Char_Event";
static const char gKeyEvtName[] = "SampleCode_Key_Event";
static const char gTitleEvtName[] = "SampleCode_Title_Event";
static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
static const char gFastTextEvtName[] = "SampleCode_FastText_Event";

bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
        if (outUni) {
            *outUni = evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
        if (outKey) {
            *outKey = (SkKey)evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::TitleQ(const SkEvent& evt) {
    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
}

void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    GrAssert(evt && TitleQ(*evt));
    evt->setString(gTitleEvtName, title);
}

bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
}

void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
    GrAssert(evt && PrefSizeQ(*evt));
    SkScalar size[2];
    size[0] = width;
    size[1] = height;
    evt->setScalars(gPrefSizeEvtName, 2, size);
}

bool SampleCode::FastTextQ(const SkEvent& evt) {
    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
}

static SkMSec gAnimTime;
static SkMSec gAnimTimePrev;

SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
SkScalar SampleCode::GetAnimSecondsDelta() {
    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
}

SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
    // since gAnimTime can be up to 32 bits, we can't convert it to a float
    // or we'll lose the low bits. Hence we use doubles for the intermediate
    // calculations
    double seconds = (double)gAnimTime / 1000.0;
    double value = SkScalarToDouble(speed) * seconds;
    if (period) {
        value = ::fmod(value, SkScalarToDouble(period));
    }
    return SkDoubleToScalar(value);
}

static void drawIntoCanvas(State* state, SkCanvas* canvas) {
    gAnimTime = SkTime::GetMSecs();
    SkView* view = state->getView();
    view->draw(canvas);
}

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

static void resetGpuState();

State::State() {
    fViewport.set(0, 0);

    const SkViewRegister* reg = SkViewRegister::Head();
    while (reg) {
        *fFactory.append() = reg->factory();
        reg = reg->next();
    }

    SkDebugf("----- %d slides\n", fFactory.count());
    fView = NULL;
    this->chooseSlide(0);
}

State::~State() {
    SkSafeUnref(fView);
}

void State::setViewport(int w, int h) {
    fViewport.set(w, h);
    if (fView) {
        fView->setSize(SkIntToScalar(w), SkIntToScalar(h));
    }
    resetGpuState();
}

const char* State::getSlideTitle(int index) const {
    SkEvent evt(gTitleEvtName);
    evt.setFast32(index);
    {
        SkView* view = fFactory[index]();
        view->doQuery(&evt);
        view->unref();
    }
    return evt.findString(gTitleEvtName);
}

void State::handleTouch(void* owner, TouchState state, float x, float y) {
    switch (state) {
        case kDown_TouchState:
            fGesture.touchBegin(owner, x, y);
            break;
        case kMoved_TouchState:
            fGesture.touchMoved(owner, x, y);
            break;
        case kUp_TouchState:
            fGesture.touchEnd(owner);
            break;
    }
}

void State::applyMatrix(SkCanvas* canvas) {
    const SkMatrix& localM = fGesture.localM();
    if (localM.getType() & SkMatrix::kScale_Mask) {
        canvas->setExternalMatrix(&localM);
    }
    canvas->concat(localM);
    canvas->concat(fGesture.globalM());
}

static State* get_state() {
    static State* gState;
    if (NULL == gState) {
        gState = new State;
    }
    return gState;
}

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

static GrContext* gContext;
static int gWidth;
static int gHeight;
static float gX, gY;

static void resetGpuState() {
    if (NULL == gContext) {
        SkDebugf("creating context for first time\n");
        gContext = make_context();
    } else {
        SkDebugf("------ gContext refcnt=%d\n", gContext->refcnt());
        gContext->abandonAllTextures();
        gContext->unref();
        gContext = make_context();
    }
}

static void doDraw() {
    if (NULL == gContext) {
        gContext = make_context();
    }

    State* state = get_state();
    SkBitmap viewport;
    viewport.setConfig(SkBitmap::kARGB_8888_Config,
                       state->getWidth(), state->getHeight());

    SkGpuCanvas canvas(gContext);

    canvas.setBitmapDevice(viewport);
    state->applyMatrix(&canvas);

    drawIntoCanvas(state, &canvas);

    GrGLCheckErr();
    GrGLClearErr();
//    gContext->checkError();
//    gContext->clearError();

    if (true) {
        static const int FRAME_COUNT = 32;
        static SkMSec gDuration;

        static SkMSec gNow;
        static int gFrameCounter;
        if (++gFrameCounter == FRAME_COUNT) {
            gFrameCounter = 0;
            SkMSec now = SkTime::GetMSecs();

            gDuration = now - gNow;
            gNow = now;
        }

        int fps = (FRAME_COUNT * 1000) / gDuration;
        SkString str;
        str.printf("FPS=%3d MS=%3d", fps, gDuration / FRAME_COUNT);
        
        SkGpuCanvas c(gContext);
        c.setBitmapDevice(viewport);

        SkPaint p;
        p.setAntiAlias(true);
        SkRect r = { 0, 0, 110, 16 };
        p.setColor(SK_ColorWHITE);
        c.drawRect(r, p);
        p.setColor(SK_ColorBLACK);
        c.drawText(str.c_str(), str.size(), 4, 12, p);
    }
}

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

extern "C" {
    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
                                                           JNIEnv*, jobject);
    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
                                                                             jint w, jint h);
    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject);
    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
                                        jint id, jint type, jfloat x, jfloat y);

    JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject);
    JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv*, jobject, jint index);
    JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index);
}

JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeSurfaceCreated(
                                                            JNIEnv*, jobject) {
    SkDebugf("------ nativeSurfaceCreated\n");
    resetGpuState();
    SkDebugf("------ end nativeSurfaceCreated\n");
}

JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeViewport(JNIEnv*, jobject,
                                                       jint w, jint h) {
    State* state = get_state();
    SkDebugf("---- state.setviewport %p %d %d\n", state, w, h);
    state->setViewport(w, h);
    SkDebugf("---- end setviewport\n");
}

JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeDrawFrame(JNIEnv*, jobject) {
    doDraw();
}

union IntPtr {
    jint    fInt;
    void*   fPtr;
};
static void* int2ptr(jint n) {
    IntPtr data;
    data.fInt = n;
    return data.fPtr;
}

JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeTouch(JNIEnv*, jobject,
                                      jint id, jint type, jfloat x, jfloat y) {
    get_state()->handleTouch(int2ptr(id), (TouchState)type, x, y);
}

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

JNIEXPORT int JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeCountSlides(JNIEnv*, jobject) {
    return get_state()->countSlides();
}

JNIEXPORT jobject JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeGetSlideTitle(JNIEnv* env, jobject, jint index) {
    return env->NewStringUTF(get_state()->getSlideTitle(index));
}

JNIEXPORT void JNICALL Java_com_tetrark_ganesh_MyRenderer_nativeChooseSlide(JNIEnv*, jobject, jint index) {
    get_state()->chooseSlide(index);
}





