/*
 * IDL Compiler
 *
 * Copyright 2004 Ove Kaaven
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
#include <signal.h>

#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "header.h"
#include "typelib.h"

int in_typelib = 0;
static FILE* typelib;

/* Copied from wtypes.h. Not included directly because that would create a
 * circular dependency (after all, wtypes.h is generated by widl...) */

enum VARENUM {
    VT_EMPTY = 0,
    VT_NULL = 1,
    VT_I2 = 2,
    VT_I4 = 3,
    VT_R4 = 4,
    VT_R8 = 5,
    VT_CY = 6,
    VT_DATE = 7,
    VT_BSTR = 8,
    VT_DISPATCH = 9,
    VT_ERROR = 10,
    VT_BOOL = 11,
    VT_VARIANT = 12,
    VT_UNKNOWN = 13,
    VT_DECIMAL = 14,
    VT_I1 = 16,
    VT_UI1 = 17,
    VT_UI2 = 18,
    VT_UI4 = 19,
    VT_I8 = 20,
    VT_UI8 = 21,
    VT_INT = 22,
    VT_UINT = 23,
    VT_VOID = 24,
    VT_HRESULT = 25,
    VT_PTR = 26,
    VT_SAFEARRAY = 27,
    VT_CARRAY = 28,
    VT_USERDEFINED = 29,
    VT_LPSTR = 30,
    VT_LPWSTR = 31,
    VT_RECORD = 36,
    VT_FILETIME = 64,
    VT_BLOB = 65,
    VT_STREAM = 66,
    VT_STORAGE = 67,
    VT_STREAMED_OBJECT = 68,
    VT_STORED_OBJECT = 69,
    VT_BLOB_OBJECT = 70,
    VT_CF = 71,
    VT_CLSID = 72,
    VT_BSTR_BLOB = 0xfff,
    VT_VECTOR = 0x1000,
    VT_ARRAY = 0x2000,
    VT_BYREF = 0x4000,
    VT_RESERVED = 0x8000,
    VT_ILLEGAL = 0xffff,
    VT_ILLEGALMASKED = 0xfff,
    VT_TYPEMASK = 0xfff
};

/* List of oleauto types that should be recognized by name.
 * (most of) these seem to be intrinsic types in mktyplib. */

static struct oatype {
  const char *kw;
  unsigned short vt;
} oatypes[] = {
  {"BSTR",      VT_BSTR},
  {"CURRENCY",  VT_CY},
  {"DATE",      VT_DATE},
  {"DECIMAL",   VT_DECIMAL},
  {"HRESULT",   VT_HRESULT},
  {"LPSTR",     VT_LPSTR},
  {"LPWSTR",    VT_LPWSTR},
  {"SCODE",     VT_ERROR},
  {"VARIANT",   VT_VARIANT}
};
#define NTYPES (sizeof(oatypes)/sizeof(oatypes[0]))
#define KWP(p) ((struct oatype *)(p))

static int kw_cmp_func(const void *s1, const void *s2)
{
        return strcmp(KWP(s1)->kw, KWP(s2)->kw);
}

static unsigned short builtin_vt(const char *kw)
{
  struct oatype key, *kwp;
  key.kw = kw;
#ifdef KW_BSEARCH
  kwp = bsearch(&key, oatypes, NTYPES, sizeof(oatypes[0]), kw_cmp_func);
#else
  {
    int i;
    for (kwp=NULL, i=0; i < NTYPES; i++)
      if (!kw_cmp_func(&key, &oatypes[i])) {
        kwp = &oatypes[i];
        break;
      }
  }
#endif
  if (kwp) {
    return kwp->vt;
  }
  return 0;
}

static int match(const char*n, const char*m)
{
  if (!n) return 0;
  return !strcmp(n, m);
}

unsigned short get_type_vt(type_t *t)
{
  unsigned short vt;

  if (t->name) {
    vt = builtin_vt(t->name);
    if (vt) return vt;
  }

  switch (t->type) {
  case RPC_FC_BYTE:
  case RPC_FC_USMALL:
    return VT_UI1;
  case RPC_FC_CHAR:
  case RPC_FC_SMALL:
    return VT_I1;
  case RPC_FC_WCHAR:
    return VT_I2; /* mktyplib seems to parse wchar_t as short */
  case RPC_FC_SHORT:
    return VT_I2;
  case RPC_FC_USHORT:
    return VT_UI2;
  case RPC_FC_LONG:
    if (t->ref && match(t->ref->name, "int")) return VT_INT;
    return VT_I4;
  case RPC_FC_ULONG:
    if (t->ref && match(t->ref->name, "int")) return VT_UINT;
    return VT_UI4;
  case RPC_FC_HYPER:
    if (t->sign < 0) return VT_UI8;
    if (t->ref && match(t->ref->name, "MIDL_uhyper")) return VT_UI8;
    return VT_I8;
  case RPC_FC_FLOAT:
    return VT_R4;
  case RPC_FC_DOUBLE:
    return VT_R8;
  case RPC_FC_RP:
  case RPC_FC_UP:
  case RPC_FC_OP:
  case RPC_FC_FP:
    /* it's a pointer... */
    if (t->ref && t->ref->type == RPC_FC_IP) {
      /* it's to an interface, which one? */
      if (match(t->ref->name, "IDispatch"))
        return VT_DISPATCH;
      if (match(t->ref->name, "IUnknown"))
        return VT_UNKNOWN;
    }
    /* FIXME: should we recurse and add a VT_BYREF? */
    /* Or just return VT_PTR? */
    error("get_type_vt: unknown-deref-type: %d\n", t->ref->type);
    break;
  default:
    error("get_type_vt: unknown-type: %d\n", t->type);
  }
  return 0;
}

unsigned short get_var_vt(var_t *v)
{
  unsigned short vt;

  if (v->tname) {
    vt = builtin_vt(v->tname);
    if (vt) return vt;
  }

  return get_type_vt(v->type);
}

void start_typelib(char *name, attr_t *attrs)
{
  in_typelib++;
  if (!do_everything && !typelib_only) return;
  typelib = fopen(typelib_name, "wb");
}

void end_typelib(void)
{
  if (typelib) fclose(typelib);
  in_typelib--;
}

void add_interface(type_t *iface)
{
  if (!typelib) return;

  /* FIXME: add interface and dependent types to typelib */
  printf("add interface: %s\n", iface->name);
}

void add_coclass(class_t *cls)
{
  ifref_t *lcur = cls->ifaces;
  ifref_t *cur;

  if (lcur) {
    while (NEXT_LINK(lcur)) lcur = NEXT_LINK(lcur);
  }

  if (!typelib) return;

  /* install interfaces the coclass depends on */
  cur = lcur;
  while (cur) {
    add_interface(cur->iface);
    cur = PREV_LINK(cur);
  }

  /* FIXME: add coclass to typelib */
  printf("add coclass: %s\n", cls->name);
}

void add_module(type_t *module)
{
  if (!typelib) return;

  /* FIXME: add module to typelib */
  printf("add module: %s\n", module->name);
}
