/*
 * inquire data information
 *
 inq_data(type1, type2, type3, basetime, member, validtime, plane, element, param)
 *  arguments:
 *   type1, type2, type3, member, plane, element: String
 *   basetime, validtime: Integer (minuits from 00:00 1 Jan 1801)
 *   param: Integer
 *          NuSDaS::N_GRID_SIZE
 *          NuSDaS::N_PC_PACKING
 *          NuSDaS::N_MISSING_MODE
 *          NuSDaS::N_MISSING_VALUE
 *  return:
 *   result
 */
VALUE
rb_inq_data(VALUE self,
            VALUE type1, VALUE type2, VALUE type3,
            VALUE basetime, VALUE member, VALUE validtime,
            VALUE plane, VALUE element,
            VALUE param)
{
  GetFullParams;
  VALUE data;

  N_SI4 cparam, cnelems;
  void* cdata;

  int flag;
  int code;
  int len;

  cparam = (N_SI4)NUM2INT(param);
  switch(cparam) {
  case N_GRID_SIZE:
    cdata = xmalloc(4*2);
    cnelems = 2;
    flag = 1;
    break;
  case N_PC_PACKING:
  case N_MISSING_MODE:
    cdata = xmalloc(4);
    cnelems = 1;
    flag = 2;
    break;
  case N_MISSING_VALUE:
    cdata = xmalloc(4);
    cnelems = 1;
    code = nusdas_inq_data(ctype1, ctype2, ctype3,
                           &cbasetime, cmember, &cvalidtime,
                           cplane, celement,
                           N_PC_PACKING, cdata, &cnelems);
    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 if ( code != 1 )
      rb_raise(rb_eRuntimeError, "bug");
    if ( strncmp((char*)cdata,"1PAC",4) == 0 ){
      len = 1;
      flag = 3;
    } else if ( strncmp((char*)cdata,"2PAC",4) == 0 ) {
      len = 2;
      flag = 4;
    } else if ( strncmp((char*)cdata,"2UPC",4) == 0 ) {
      len = 2;
      flag = 5;
    } else if ( strncmp((char*)cdata,"4PAC",4) == 0 ) {
      len = 4;
      flag = 6;
    } else if ( strncmp((char*)cdata,"N1I2",4) == 0 ) {
      len = 2;
      flag = 4;
    } else if ( strncmp((char*)cdata,"I1  ",4) == 0 ) {
      len = 1;
      flag = 3;
    } else if ( strncmp((char*)cdata,"I2  ",4) == 0 ) {
      len = 2;
      flag = 4;
    } else if ( strncmp((char*)cdata,"I4  ",4) == 0 ) {
      len = 4;
      flag = 7;
    } else if ( strncmp((char*)cdata,"R4  ",4) == 0 ) {
      len = 4;
      flag = 8;
    } else if ( strncmp((char*)cdata,"R8  ",4) == 0 ) {
      len = 8;
      flag = 9;
    } else {
      len = -1;
      flag = -1;
      rb_raise(rb_eRuntimeError, "bug");
    }
    free(cdata);
    cdata = xmalloc(len);
    cnelems = 1;
    break;
  default:
    flag = -1;
    cdata = NULL;
    rb_raise(rb_eArgError, "param is invalid");
  }

  code = nusdas_inq_data(ctype1, ctype2, ctype3,
                         &cbasetime, cmember, &cvalidtime,
                         cplane, celement,
                         cparam, cdata, &cnelems);
  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 != cnelems )
    rb_raise(rb_eRuntimeError, "bug");
  switch (flag) {
  case 1:
    data = rb_ary_new();
    rb_ary_push(data, INT2NUM((int)((N_SI4*)cdata)[0]));
    rb_ary_push(data, INT2NUM((int)((N_SI4*)cdata)[1]));
    break;
  case 2:
    data = rb_str_new((char*)cdata, 4);
    break;
  case 3:
    data = CHR2FIX( ((N_UI1*)cdata)[0] );
    break;
  case 4:
    data = INT2FIX( ((N_SI2*)cdata)[0] );
    break;
  case 5:
    data = UINT2NUM( (unsigned int)(((N_UI2*)cdata)[0]) );
    break;
  case 6:
    data = INT2FIX( ((N_SI4*)cdata)[0] );
    break;
  case 7:
    data = UINT2NUM( (unsigned int)(((N_UI4*)cdata)[0]) );
    break;
  case 8:
    data = rb_float_new( (double)(((float*)cdata)[0]) );
    break;
  case 9:
    data = rb_float_new( ((double*)cdata)[0] );
    break;
  default:
    data = Qnil;
  }

  free(cdata);
  return data;
}