/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Sample.h"
#include "SkLua.h"
#include "SkCanvas.h"
#include "Resources.h"
#include "SkData.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

//#define LUA_FILENAME    "lua/test.lua"
#define LUA_FILENAME    "lua/slides.lua"

static const char gDrawName[] = "onDrawContent";
static const char gClickName[] = "onClickHandler";
static const char gUnicharName[] = "onCharHandler";

static const char gMissingCode[] = ""
    "local paint = Sk.newPaint()"
    "paint:setAntiAlias(true)"
    "paint:setTextSize(30)"
    ""
    "function onDrawContent(canvas)"
    "   canvas:drawText('missing \"test.lua\"', 20, 50, paint)"
    "end"
    ;

class LuaView : public Sample {
public:
    LuaView() : fLua(nullptr) {}

    ~LuaView() override { delete fLua; }

    void setImageFilename(lua_State* L) {
        SkString str = GetResourcePath("images/mandrill_256.png");

        lua_getglobal(L, "setImageFilename");
        if (lua_isfunction(L, -1)) {
            fLua->pushString(str.c_str());
            if (lua_pcall(L, 1, 0, 0) != LUA_OK) {
                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
            }
        }
    }

    lua_State* ensureLua() {
        if (nullptr == fLua) {
            fLua = new SkLua;

            sk_sp<SkData> data = GetResourceAsData(LUA_FILENAME);
            if (data) {
                fLua->runCode(data->data(), data->size());
                this->setImageFilename(fLua->get());
            } else {
                fLua->runCode(gMissingCode);
            }
        }
        return fLua->get();
    }

protected:
    bool onQuery(Sample::Event* evt) override {
        if (Sample::TitleQ(*evt)) {
            Sample::TitleR(evt, "Lua");
            return true;
        }
        SkUnichar uni;
        if (Sample::CharQ(*evt, &uni)) {
            lua_State* L = this->ensureLua();
            lua_getglobal(L, gUnicharName);
            if (lua_isfunction(L, -1)) {
                SkString str;
                str.appendUnichar(uni);
                fLua->pushString(str.c_str());
                if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
                    SkDebugf("lua err: %s\n", lua_tostring(L, -1));
                } else {
                    if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
                        return true;
                    }
                }
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    void onDrawContent(SkCanvas* canvas) override {
        lua_State* L = this->ensureLua();

        lua_getglobal(L, gDrawName);
        if (!lua_isfunction(L, -1)) {
            int t = lua_type(L, -1);
            SkDebugf("--- expected %s function %d, ignoring.\n", gDrawName, t);
            lua_pop(L, 1);
        } else {
            // does it make sense to try to "cache" the lua version of this
            // canvas between draws?
            fLua->pushCanvas(canvas);
            fLua->pushScalar(this->width());
            fLua->pushScalar(this->height());
            if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
            }
        }
    }

    virtual Sample::Click* onFindClickHandler(SkScalar x, SkScalar y,
                                              unsigned modi) override {
        lua_State* L = this->ensureLua();
        lua_getglobal(L, gClickName);
        if (lua_isfunction(L, -1)) {
            fLua->pushScalar(x);
            fLua->pushScalar(y);
            fLua->pushString("down");
            if (lua_pcall(L, 3, 1, 0) != LUA_OK) {
                SkDebugf("lua err: %s\n", lua_tostring(L, -1));
            } else {
                if (lua_isboolean(L, -1) && lua_toboolean(L, -1)) {
                    return new Click(this);
                }
            }
        }
        return this->INHERITED::onFindClickHandler(x, y, modi);
    }

    bool onClick(Click* click) override {
        const char* state = nullptr;
        switch (click->fState) {
            case Click::kMoved_State:
                state = "moved";
                break;
            case Click::kUp_State:
                state = "up";
                break;
            default:
                break;
        }
        if (state) {
            lua_State* L = fLua->get();
            lua_getglobal(L, gClickName);
            fLua->pushScalar(click->fCurr.x());
            fLua->pushScalar(click->fCurr.y());
            fLua->pushString(state);
            lua_pcall(L, 3, 1, 0);
            return lua_isboolean(L, -1) && lua_toboolean(L, -1);
        }
        return true;
    }

private:
    SkLua* fLua;

    typedef Sample INHERITED;
};

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

DEF_SAMPLE( return new LuaView(); )
