/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "macro.h"

//=============================================================================

static Value reply = 0.0;
static boolean ready = false;


static void info_cb(svcid* id, request* r, void* data)
{
    char* p = (char*)data;
    print_all_requests(r);
    ready = true;

    request* e = empty_request("STRING");
    set_value(e, "VALUE", "%s", p);


    e->next = r->next;
    reply.SetContent(e);

    e->next = nullptr;
    free_all_requests(e);

    send_reply(id, nullptr);
}

static void close_cb(svcid* id, request* r, void*)
{
    print_all_requests(r);
    ready = true;
    reply = Value();  // Nil
    send_reply(id, nullptr);
}

//=============================================================================

class InputFunction : public Function
{
public:
    InputFunction(const char* n) :
        Function(n, 1, trequest)
    {
        info = "Wait for user input";
    }
    virtual Value Execute(int arity, Value* arg);
};

Value InputFunction::Execute(int, Value* arg)
{
    static int first = 1;
    if (first) {
        ASync::Connect();
        add_service_callback(ASync::Svc, "WINDOW_INFO", info_cb, (void*)"input");
        add_service_callback(ASync::Svc, "CHANGE_WINDOW", info_cb, (void*)"change");
        // add_service_callback(ASync::Svc,"MOVE_CURSOR",   info_cb,0);
        // add_service_callback(ASync::Svc,"CONTENTS",      info_cb,0);
        add_service_callback(ASync::Svc, "CLOSE_WINDOW", close_cb, nullptr);
        first = 0;
    }

    request* r;
    arg[0].GetValue(r);

    const char* id = get_value(r, "VISTOOL_ID", 0);

    if (id == nullptr) {
        request* e = empty_request("REGISTER");


        set_value(e, "SERVICE", "%s", ASync::Name);
        set_subrequest(e, "WINDOW", r);

        add_value(e, "interest", "POSITION");
        add_value(e, "interest", "MOVE_CURSOR");
        add_value(e, "interest", "CHANGE_WINDOW");
        add_value(e, "interest", "CONTENTS");
        add_value(e, "interest", "CLOSE_WINDOW");
        Value v = Value("VisModTrans", e);
        free_all_requests(e);
        v.Sync();

        set_value(r, "VISTOOL_ID", "%s", id);
    }


    while (!ready)
        process_service(ASync::Svc);

    ready = false;
    return reply;
}

//=============================================================================
static void install(Context* c)
{
    c->AddFunction(new InputFunction("input"));
}

static Linkage Link(install);
