/*
 * inquire control information
 *
 * inq_cntl(type1, type2, type3, basetime, member, validtime, param)
 *  arguments:
 *   type1, type2, type3, member: String
 *   basetime, validtime: Integer (minuits from 00:00 1 Jan 1801)
 *   param: Integer
 *          NuSDaS::N_MEMBER_NUM      : number of members
 *          NuSDaS::N_MEMBER_LIST     : list of members
 *          NuSDaS::N_VALIDTIME_NUM   : number of validtimes
 *          NuSDaS::N_VALIDTIME_LIST  : list of validtime
 *          NuSDaS::N_VALIDTIME_LIST2 : list of validtime2
 *          NuSDaS::N_PLANE_NUM       : number of planes
 *          NuSDaS::N_PLANE_LIST      : list of planes
 *          NuSDaS::N_ELEMENT_NUM     : number of elements
 *          NuSDaS::N_ELEMENT_LIST    : list of elements
 *          NuSDaS::N_PROJECTION      : projection
 *  return:
 *   result
 */
VALUE
rb_inq_cntl(VALUE self,
            VALUE type1, VALUE type2, VALUE type3,
            VALUE basetime, VALUE member, VALUE validtime,
            VALUE param)
{
  GetTypes;
  GetTimesAndMember;

  VALUE data;

  N_SI4 cparam;
  void* cdata;
  N_SI4 cdatasize;

  N_SI4 cparam2, len;
  int flag, i;
  N_SI4 code;

  cparam = (N_SI4)NUM2INT(param);
  cparam2 = 0;
  flag = -1;
  len = 0;
  switch( cparam ) {
  case N_MEMBER_NUM:
  case N_VALIDTIME_NUM:
  case N_PLANE_NUM:
  case N_ELEMENT_NUM:
    cdatasize = 1;
    cdata = xmalloc( sizeof(N_SI4) );
    flag = 1;
    break;
  case N_MEMBER_LIST:
  case N_VALIDTIME_LIST:
  case N_PLANE_LIST:
  case N_ELEMENT_LIST:
    switch( cparam ) {
    case N_MEMBER_LIST:
      cparam2 = N_MEMBER_NUM;
      len = 4;
      flag = 2;
      break;
    case N_VALIDTIME_LIST:
      cparam2 = N_VALIDTIME_NUM;
      len = 4;
      flag = 4;
      break;
    case N_PLANE_LIST:
      cparam2 = N_PLANE_NUM;
      len = 6;
      flag = 2;
      break;
    case N_ELEMENT_LIST:
      cparam2 = N_ELEMENT_NUM;
      len = 6;
      flag = 2;
      break;
    }
    cdatasize = 1;
    cdata = xmalloc(4);
    code = nusdas_inq_cntl(ctype1, ctype2, ctype3,
                           &cbasetime, cmember, &cbasetime,
                           cparam2, cdata, &cdatasize);
    if (code == 1)
      cdatasize = ((N_SI4*)cdata)[0];
    else if (code == -1)
      rb_raise(rb_eRuntimeError, "bug");
    else if (code == -2)
      rb_raise(rb_eRuntimeError, "bug");
    else if (code == -3)
      rb_raise(rb_eRuntimeError, "bug");
    else
      rb_raise(rb_eRuntimeError, "failed: nusdas_inq_cntl, code=%d",code);
    free(cdata);
    cdata = xmalloc( sizeof(char)*len*cdatasize );
    break;
  case N_PROJECTION:
    cdatasize = 1;
    cdata = xmalloc( sizeof(char)*4 );
    flag = 3;
    break;
  default:
    rb_raise(rb_eArgError, "param is invalid");
  }

  code = nusdas_inq_cntl(ctype1, ctype2, ctype3,
                         &cbasetime, cmember, &cvalidtime,
                         cparam, cdata, &cdatasize);
  if (code == -1)
    rb_raise(rb_eRuntimeError, "bug");
  else if (code == -2)
    rb_raise(rb_eRuntimeError, "bug");
  else if (code == -3)
    rb_raise(rb_eRuntimeError, "param is invalid");
  else if (code != cdatasize)
    rb_raise(rb_eRuntimeError, "failed: nusdas_inq_cntl, code=%d",code);
  switch (flag) {
  case 1:
    data = INT2NUM( ((int*)cdata)[0] );
    break;
  case 2:
    data = rb_ary_new();
    for (i=0;i<cdatasize;i++)
      rb_ary_push(data, rb_str_new(((char*)cdata)+i*len, len));
    break;
  case 3:
    data = rb_str_new((char*)cdata, 4);
    break;
  case 4:
    data = rb_ary_new();
    for (i=0;i<cdatasize;i++)
      rb_ary_push(data, INT2NUM((int)(((N_SI4*)cdata)[i])));
    break;
    data = INT2NUM( (int)(((N_SI4*)cdata)[0]) );
    break;
  default:
    data = Qnil;
  }
  free(cdata);
  return data;
}