/*
 * $Id: p_header,v 1.4 2000/11/27 01:57:01 keiko Exp $
 */

#include <stdio.h>
#include "ruby.h"
#include "libtinyf2c.h"
#include "narray.h"

#define DFLT_SIZE 32

extern char    *dcl_obj2ccharary(VALUE, int, int);
extern integer *dcl_obj2cintegerary(VALUE);
extern real    *dcl_obj2crealary(VALUE);
extern complex *dcl_obj2ccomplexary(VALUE);
extern logical *dcl_obj2clogicalary(VALUE);

extern VALUE dcl_ccharary2obj(char *, int, int);
extern VALUE dcl_cintegerary2obj(integer *, int, int, int *);
extern VALUE dcl_crealary2obj(real *, int, int, int *);
extern VALUE dcl_ccomplexary2obj(complex *, int, char *);
extern VALUE dcl_clogicalary2obj(logical *, int, int, int *);

extern void dcl_freeccharary(char *);
extern void dcl_freecintegerary(integer *);
extern void dcl_freecrealary(real *);
extern void dcl_freeccomplexary(complex *);
extern void dcl_freeclogicalary(logical *);

/* for functions which return doublereal */
/* fnclib */
extern doublereal rd2r_(real *);
extern doublereal rr2d_(real *);
extern doublereal rexp_(real *, integer *, integer *);
extern doublereal rfpi_(void);
extern doublereal rmod_(real *, real *);
/* gnmlib */
extern doublereal rgnlt_(real *);
extern doublereal rgnle_(real *);
extern doublereal rgngt_(real *);
extern doublereal rgnge_(real *);
/* rfalib */
extern doublereal rmax_(real *, integer *, integer *);
extern doublereal rmin_(real *, integer *, integer *);
extern doublereal rsum_(real *, integer *, integer *);
extern doublereal rave_(real *, integer *, integer *);
extern doublereal rvar_(real *, integer *, integer *);
extern doublereal rstd_(real *, integer *, integer *);
extern doublereal rrms_(real *, integer *, integer *);
extern doublereal ramp_(real *, integer *, integer *);
/* rfblib */
extern doublereal rprd_(real *, real *, integer *, integer *, integer *);
extern doublereal rcov_(real *, real *, integer *, integer *, integer *);
extern doublereal rcor_(real *, real *, integer *, integer *, integer *);


VALUE mDCL;

static VALUE
dcl_uxsaxz(obj, cside, roffx)
    VALUE obj, cside, roffx;
{
    char *i_cside;
    real i_roffx;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(roffx) != T_FLOAT) {
      roffx = rb_funcall(roffx, rb_intern("to_f"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_roffx = (real)NUM2DBL(roffx);


    uxsaxz_(i_cside, &i_roffx, (ftnlen)strlen(i_cside));

    return Qnil;

}

static VALUE
dcl_uxsaxs(obj, cside)
    VALUE obj, cside;
{
    char *i_cside;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }

    i_cside = STR2CSTR(cside);


    uxsaxs_(i_cside, (ftnlen)strlen(i_cside));

    return Qnil;

}

static VALUE
dcl_uxpaxs(obj, cside, islct)
    VALUE obj, cside, islct;
{
    char *i_cside;
    integer i_islct;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if ((TYPE(islct) != T_BIGNUM) || (TYPE(islct) != T_FIXNUM)) {
      islct = rb_funcall(islct, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_islct = NUM2INT(islct);


    uxpaxs_(i_cside, &i_islct, (ftnlen)strlen(i_cside));

    return Qnil;

}

static VALUE
dcl_uxptmk(obj, cside, islct, ux, n)
    VALUE obj, cside, islct, ux, n;
{
    char *i_cside;
    integer i_islct;
    real *i_ux;
    integer i_n;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if ((TYPE(islct) != T_BIGNUM) || (TYPE(islct) != T_FIXNUM)) {
      islct = rb_funcall(islct, rb_intern("to_i"), 0);
    }
    if (TYPE(ux) == T_FLOAT) {
      ux = rb_Array(ux);
    }
    /* if ((TYPE(ux) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if ((TYPE(n) != T_BIGNUM) || (TYPE(n) != T_FIXNUM)) {
      n = rb_funcall(n, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_islct = NUM2INT(islct);
    i_n = NUM2INT(n);
    i_ux = dcl_obj2crealary(ux);


    uxptmk_(i_cside, &i_islct, i_ux, &i_n, (ftnlen)strlen(i_cside));

    dcl_freecrealary(i_ux);

    return Qnil;

}

static VALUE
dcl_uxplbl(obj, cside, islct, ux, ch, nc, n)
    VALUE obj, cside, islct, ux, ch, nc, n;
{
    char *i_cside;
    integer i_islct;
    real *i_ux;
    char *i_ch;
    integer i_nc;
    integer i_n;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if ((TYPE(islct) != T_BIGNUM) || (TYPE(islct) != T_FIXNUM)) {
      islct = rb_funcall(islct, rb_intern("to_i"), 0);
    }
    if (TYPE(ux) == T_FLOAT) {
      ux = rb_Array(ux);
    }
    /* if ((TYPE(ux) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if (TYPE(ch) == T_STRING) {
      ch = rb_Array(ch);
    }
    if (TYPE(ch) != T_ARRAY) {
      rb_raise(rb_eTypeError, "invalid type");
    }
    if ((TYPE(nc) != T_BIGNUM) || (TYPE(nc) != T_FIXNUM)) {
      nc = rb_funcall(nc, rb_intern("to_i"), 0);
    }
    if ((TYPE(n) != T_BIGNUM) || (TYPE(n) != T_FIXNUM)) {
      n = rb_funcall(n, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_islct = NUM2INT(islct);
    i_nc = NUM2INT(nc);
    i_n = NUM2INT(n);
    i_ux = dcl_obj2crealary(ux);
    i_ch = dcl_obj2ccharary(ch, (i_n*DFLT_SIZE), DFLT_SIZE);


    uxplbl_(i_cside, &i_islct, i_ux, i_ch, &i_nc, &i_n, (ftnlen)strlen(i_cside), (ftnlen)DFLT_SIZE);

    dcl_freecrealary(i_ux);
    dcl_freeccharary(i_ch);

    return Qnil;

}

static VALUE
dcl_uxpnum(obj, cside, islct, ux, n)
    VALUE obj, cside, islct, ux, n;
{
    char *i_cside;
    integer i_islct;
    real *i_ux;
    integer i_n;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if ((TYPE(islct) != T_BIGNUM) || (TYPE(islct) != T_FIXNUM)) {
      islct = rb_funcall(islct, rb_intern("to_i"), 0);
    }
    if (TYPE(ux) == T_FLOAT) {
      ux = rb_Array(ux);
    }
    /* if ((TYPE(ux) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if ((TYPE(n) != T_BIGNUM) || (TYPE(n) != T_FIXNUM)) {
      n = rb_funcall(n, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_islct = NUM2INT(islct);
    i_n = NUM2INT(n);
    i_ux = dcl_obj2crealary(ux);


    uxpnum_(i_cside, &i_islct, i_ux, &i_n, (ftnlen)strlen(i_cside));

    dcl_freecrealary(i_ux);

    return Qnil;

}

static VALUE
dcl_uxpttl(obj, cside, islct, cttl, px)
    VALUE obj, cside, islct, cttl, px;
{
    char *i_cside;
    integer i_islct;
    char *i_cttl;
    real i_px;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if ((TYPE(islct) != T_BIGNUM) || (TYPE(islct) != T_FIXNUM)) {
      islct = rb_funcall(islct, rb_intern("to_i"), 0);
    }
    if (TYPE(cttl) != T_STRING) {
      cttl = rb_funcall(cttl, rb_intern("to_str"), 0);
    }
    if (TYPE(px) != T_FLOAT) {
      px = rb_funcall(px, rb_intern("to_f"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_islct = NUM2INT(islct);
    i_cttl = STR2CSTR(cttl);
    i_px = (real)NUM2DBL(px);


    uxpttl_(i_cside, &i_islct, i_cttl, &i_px, (ftnlen)strlen(i_cside), (ftnlen)strlen(i_cttl));

    return Qnil;

}

static VALUE
dcl_uxaxlb(obj, cside, ux1, n1, ux2, ch, nc, n2)
    VALUE obj, cside, ux1, n1, ux2, ch, nc, n2;
{
    char *i_cside;
    real *i_ux1;
    integer i_n1;
    real *i_ux2;
    char *i_ch;
    integer i_nc;
    integer i_n2;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(ux1) == T_FLOAT) {
      ux1 = rb_Array(ux1);
    }
    /* if ((TYPE(ux1) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux1, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if ((TYPE(n1) != T_BIGNUM) || (TYPE(n1) != T_FIXNUM)) {
      n1 = rb_funcall(n1, rb_intern("to_i"), 0);
    }
    if (TYPE(ux2) == T_FLOAT) {
      ux2 = rb_Array(ux2);
    }
    /* if ((TYPE(ux2) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux2, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if (TYPE(ch) == T_STRING) {
      ch = rb_Array(ch);
    }
    if (TYPE(ch) != T_ARRAY) {
      rb_raise(rb_eTypeError, "invalid type");
    }
    if ((TYPE(nc) != T_BIGNUM) || (TYPE(nc) != T_FIXNUM)) {
      nc = rb_funcall(nc, rb_intern("to_i"), 0);
    }
    if ((TYPE(n2) != T_BIGNUM) || (TYPE(n2) != T_FIXNUM)) {
      n2 = rb_funcall(n2, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_n1 = NUM2INT(n1);
    i_nc = NUM2INT(nc);
    i_n2 = NUM2INT(n2);
    i_ux1 = dcl_obj2crealary(ux1);
    i_ux2 = dcl_obj2crealary(ux2);
    i_ch = dcl_obj2ccharary(ch, (i_n2*DFLT_SIZE), DFLT_SIZE);


    uxaxlb_(i_cside, i_ux1, &i_n1, i_ux2, i_ch, &i_nc, &i_n2, (ftnlen)strlen(i_cside), (ftnlen)DFLT_SIZE);

    dcl_freecrealary(i_ux1);
    dcl_freecrealary(i_ux2);
    dcl_freeccharary(i_ch);

    return Qnil;

}

static VALUE
dcl_uxaxnm(obj, cside, ux1, n1, ux2, n2)
    VALUE obj, cside, ux1, n1, ux2, n2;
{
    char *i_cside;
    real *i_ux1;
    integer i_n1;
    real *i_ux2;
    integer i_n2;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(ux1) == T_FLOAT) {
      ux1 = rb_Array(ux1);
    }
    /* if ((TYPE(ux1) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux1, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if ((TYPE(n1) != T_BIGNUM) || (TYPE(n1) != T_FIXNUM)) {
      n1 = rb_funcall(n1, rb_intern("to_i"), 0);
    }
    if (TYPE(ux2) == T_FLOAT) {
      ux2 = rb_Array(ux2);
    }
    /* if ((TYPE(ux2) != T_ARRAY) && 
           (rb_obj_is_kind_of(ux2, cNArray) != Qtrue)) {
         rb_raise(rb_eTypeError, "invalid type");
       }  -- no check since obj2c*ary will do that */
    if ((TYPE(n2) != T_BIGNUM) || (TYPE(n2) != T_FIXNUM)) {
      n2 = rb_funcall(n2, rb_intern("to_i"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_n1 = NUM2INT(n1);
    i_n2 = NUM2INT(n2);
    i_ux1 = dcl_obj2crealary(ux1);
    i_ux2 = dcl_obj2crealary(ux2);


    uxaxnm_(i_cside, i_ux1, &i_n1, i_ux2, &i_n2, (ftnlen)strlen(i_cside));

    dcl_freecrealary(i_ux1);
    dcl_freecrealary(i_ux2);

    return Qnil;

}

static VALUE
dcl_uxaxdv(obj, cside, dx1, dx2)
    VALUE obj, cside, dx1, dx2;
{
    char *i_cside;
    real i_dx1;
    real i_dx2;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(dx1) != T_FLOAT) {
      dx1 = rb_funcall(dx1, rb_intern("to_f"), 0);
    }
    if (TYPE(dx2) != T_FLOAT) {
      dx2 = rb_funcall(dx2, rb_intern("to_f"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_dx1 = (real)NUM2DBL(dx1);
    i_dx2 = (real)NUM2DBL(dx2);


    uxaxdv_(i_cside, &i_dx1, &i_dx2, (ftnlen)strlen(i_cside));

    return Qnil;

}

static VALUE
dcl_uxmttl(obj, cside, cttl, px)
    VALUE obj, cside, cttl, px;
{
    char *i_cside;
    char *i_cttl;
    real i_px;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(cttl) != T_STRING) {
      cttl = rb_funcall(cttl, rb_intern("to_str"), 0);
    }
    if (TYPE(px) != T_FLOAT) {
      px = rb_funcall(px, rb_intern("to_f"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_cttl = STR2CSTR(cttl);
    i_px = (real)NUM2DBL(px);


    uxmttl_(i_cside, i_cttl, &i_px, (ftnlen)strlen(i_cside), (ftnlen)strlen(i_cttl));

    return Qnil;

}

static VALUE
dcl_uxsttl(obj, cside, cttl, px)
    VALUE obj, cside, cttl, px;
{
    char *i_cside;
    char *i_cttl;
    real i_px;

    if (TYPE(cside) != T_STRING) {
      cside = rb_funcall(cside, rb_intern("to_str"), 0);
    }
    if (TYPE(cttl) != T_STRING) {
      cttl = rb_funcall(cttl, rb_intern("to_str"), 0);
    }
    if (TYPE(px) != T_FLOAT) {
      px = rb_funcall(px, rb_intern("to_f"), 0);
    }

    i_cside = STR2CSTR(cside);
    i_cttl = STR2CSTR(cttl);
    i_px = (real)NUM2DBL(px);


    uxsttl_(i_cside, i_cttl, &i_px, (ftnlen)strlen(i_cside), (ftnlen)strlen(i_cttl));

    return Qnil;

}

static VALUE
dcl_uxsfmt(obj, cfmt)
    VALUE obj, cfmt;
{
    char *i_cfmt;

    if (TYPE(cfmt) != T_STRING) {
      cfmt = rb_funcall(cfmt, rb_intern("to_str"), 0);
    }

    i_cfmt = STR2CSTR(cfmt);


    uxsfmt_(i_cfmt, (ftnlen)strlen(i_cfmt));

    return Qnil;

}

static VALUE
dcl_uxqfmt(obj)
    VALUE obj;
{
    char *o_cfmt;
    VALUE cfmt;

    o_cfmt= ALLOCA_N(char, (DFLT_SIZE+1));
    memset(o_cfmt, '\0', DFLT_SIZE+1);

    uxqfmt_(o_cfmt, (ftnlen)DFLT_SIZE);

    cfmt = rb_str_new2(o_cfmt);


    return cfmt;

}
void
init_grph2_uxpack(mDCL)
VALUE mDCL;
{
    rb_define_module_function(mDCL, "uxsaxz", dcl_uxsaxz, 2);
    rb_define_module_function(mDCL, "uxsaxs", dcl_uxsaxs, 1);
    rb_define_module_function(mDCL, "uxpaxs", dcl_uxpaxs, 2);
    rb_define_module_function(mDCL, "uxptmk", dcl_uxptmk, 4);
    rb_define_module_function(mDCL, "uxplbl", dcl_uxplbl, 6);
    rb_define_module_function(mDCL, "uxpnum", dcl_uxpnum, 4);
    rb_define_module_function(mDCL, "uxpttl", dcl_uxpttl, 4);
    rb_define_module_function(mDCL, "uxaxlb", dcl_uxaxlb, 7);
    rb_define_module_function(mDCL, "uxaxnm", dcl_uxaxnm, 5);
    rb_define_module_function(mDCL, "uxaxdv", dcl_uxaxdv, 3);
    rb_define_module_function(mDCL, "uxmttl", dcl_uxmttl, 3);
    rb_define_module_function(mDCL, "uxsttl", dcl_uxsttl, 3);
    rb_define_module_function(mDCL, "uxsfmt", dcl_uxsfmt, 1);
    rb_define_module_function(mDCL, "uxqfmt", dcl_uxqfmt, 0);
}
