#include <iiimp-data.h>
#include <iiimp.h>

#include "input-method.h"
#include "input-context.h"
#include "sequence.h"
#include "stream.h"
#include "opcode-reply.h"


IIIMF_status
iiimf_request_send(
    IIIMF_im *		im,
    IIIMF_ic *		ic,
    IIIMP_message *	message)
{
    IIIMF_status	status;
    int			opcode_reply;
    IIIMP_message *	message_receive;

    message_receive = NULL;

    status = iiimf_message_sequence(im, ic, message, IIIMF_MESSAGE_ATTR_SEND);
    if (IIIMF_STATUS_SUCCESS != status) return status;

    status = iiimf_stream_send(im->stream, im->data_s, message);
    if (IIIMF_STATUS_SUCCESS != status) return status;

    opcode_reply = iiimf_opcode_reply_internal(message->opcode);
    if (IM_NOP == opcode_reply) return IIIMF_STATUS_SUCCESS;

    for (;;) {
	if (NULL != message_receive) {
	    iiimp_message_delete(im->data_s, message_receive);
	}

	status = iiimf_stream_receive(im->stream, im->data_s, &message_receive);
	if (IIIMF_STATUS_SUCCESS != status) break;

	status = iiimf_message_sequence(im, ic, message_receive,
					IIIMF_MESSAGE_ATTR_RECEIVE);
	if (IIIMF_STATUS_SUCCESS != status) break;

	if (IM_CREATEIC_REPLY == message_receive->opcode) {
	    ic->ic_id = message_receive->ic_id;
	}

	status = (im->message_handler_call)(im, message_receive);
	if (IIIMF_STATUS_SUCCESS != status) {
	    break;
	}

	if (opcode_reply == message_receive->opcode) {
	    break;
	}

	status = iiimf_request_reply(im, ic, message_receive);
	if (IIIMF_STATUS_SUCCESS != status) break;
    }

    if (NULL != message_receive) {
	iiimp_message_delete(im->data_s, message_receive);
    }

    return status;
}


IIIMF_status
iiimf_request_loop(IIIMF_im * im)
{
    IIIMF_ic *		ic;
    IIIMP_message *	message;
    IIIMF_status	status;
    IIIMP_data_s *	data_s;

    ic = NULL;
    message = NULL;
    data_s = im->data_s;

    for (;;) {
	if (NULL != message) {
	    iiimp_message_delete(data_s, message);
	}

	status = iiimf_stream_receive(im->stream, data_s, &message);
	if (IIIMF_STATUS_SUCCESS != status) return status;

	status = iiimf_message_sequence(im, ic, message,
					IIIMF_MESSAGE_ATTR_RECEIVE);
	if (IIIMF_STATUS_SUCCESS != status) break;

	status = (im->message_handler_call)(im, message);
	if (IIIMF_STATUS_SUCCESS != status) {
	    break;
	}

	if (-1 == message->ic_id) {
	    ic = NULL;
	} else {
	    for (ic = im->ic_list; NULL != ic; ic = ic->next) {
		if (message->ic_id == ic->ic_id) break;
	    }
	    if (NULL == ic) return IIIMF_STATUS_IC_INVALID;
	}

	status = iiimf_request_reply(im, ic, message);
	if (IIIMF_STATUS_SUCCESS != status) break;
    }

    if (NULL != message) {
	iiimp_message_delete(data_s, message);
    }

    return status;
}

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
