#ifndef _ROVM_CLASS_H
#define _ROVM_CLASS_H

/** 만약 Class 를 찾을 수 없을 경우, 이 값을 반환하게 됩니다.  */
#define NULL_CLASS              (RvClass *) 0
/** 만약 찾고자 하는 Class 가 이 ROVM 서버가 아닌 원격에 있는 Class 일 경우,
    이 값을 반환하게 됩니다.  */
#define REMOTE_CLASS            (RvClass *) 1

#define NULL_METHOD             (RvMethod *) 0
#define NULL_OBJECT             (RvObject *) 0

typedef unsigned short u2;
typedef unsigned char u1;
typedef unsigned int u4;
typedef struct eclass RvClass;
typedef struct eclass_method RvMethod;
typedef struct eobject RvObject;

#define MTYPE_STR(NODE)                 ((NODE)->str)
#define MTYPE_ARGC(NODE)                ((NODE)->argc)
#define MTYPE_ARGV(NODE)                ((NODE)->argv)
#define MTYPE_RET(NODE)                 ((NODE)->ret)

/**
   Method 의 Type 을 분석하여 그에 대한 세부 정보를 가지고 있는 구조체입니다.
 */
struct eclass_method_type
{
  /** Method 의 Type 정보입니다.  */
  u1 *str;

  /** Type 에서 Argument 의 갯수를 가지고 있습니다.  */
  u2 argc;
  /** Type 에서 각각의 Argument 의 위치 관련 offset 정보를 가지고 있습니다.  */
  u2 *argv;
  /** Type 에서 Return 관련 정보의 위치 offset 정보를 가지고 있습니다.  */
  u2 ret;
};

#define METHOD_NAME(NODE)               ((NODE)->name)
#define METHOD_TYPE(NODE)               ((NODE)->type)
#define METHOD_OPLEN(NODE)              ((NODE)->oplen)
#define METHOD_OP(NODE)                 ((NODE)->op)
#define METHOD_NEXT(NODE)               ((NODE)->next)

/**
   하나의 Method 를 나타내는 구조체입니다.
 */
struct eclass_method
{
  u1 *name;
  struct eclass_method_type *type;

  u4 oplen;
  rc_opcode_t *op;

  struct eclass_method *next;
};

#define CLASS_ROVM(NODE)                ((NODE)->r)
#define CLASS_NAME(NODE)                ((NODE)->name)
#define CLASS_METHOD(NODE)              ((NODE)->m)

/**
   ENVLANG File Format 에 정의되어 있는 클래스를 C 언어로 표현한 구조체
   입니다.

   (20050206) 현재 구조는 매우 간단하며, field, exception 은 지원도 하지 
              않습니다.
 */
struct eclass
{
  /** ROVM 구조체에 대한 빠른 접근을 위해서, 이에 대한 포인터를 간직한다.  */
  struct rovm *r;

  /** 현재 RvClass 의 이름을 가지고 있습니다.  */
  u1 *name;

  /** 현재 RvClass 에 정의되어 있는 method 들에 대한 linked list 입니다.  */
  struct eclass_method *m;
};

#define OBJECT_TYPE(NODE)               ((NODE)->type)
/** 현재 ObjectRef 가 local 용임을 가르킵니다.  */
#define LOCAL_OBJECT                    0
/** 현재 ObjectRef 가 remote 용임을 가르킵니다.  */
#define REMOTE_OBJECT                   1
#define OBJECT_CTIME(NODE)              ((NODE)->ctime)
#define OBJECTL_CLASS(NODE)             ((NODE)->cls)

/**
   RvObject 구조체에 대해서 정의합니다.
 */
struct eobject
{
  /** 현재 이 RvObject 가 local 클래스 참조를 위한 ObjectRef 인지 remote
      ObjectRef 를 위한 참조인지를 나타내는 변수입니다.  만약 값이 0 일 경우,
      local 을 의미하며, 1 일 경우 remote 를 의미합니다.  */
  unsigned type : 1;
  unsigned unused : 31;

  /** 이 ObjectRef 가 *생성된 시각*에 대한 기록을 가지고 있습니다.  이 정보는
      Garbage Collector 가 유용하게 사용하기 위해서 존재합니다.  */
  rc_time_t ctime;

  RvClass *cls;
};

extern RvClass *rc_getclassbyhost (request_rec *, int, char *, unsigned short, char *);
extern RvObject *NewRemoteRvObject (request_rec *, int, char *, unsigned short, char *);
extern RvObject *NewRvObject (RvClass *);
extern int rc_callmethod (request_rec *, struct ticket *, char *, char *, u2, u2 *);

#endif

