/*-----------------------------------------------------------------------
 *     Copyright (C) 2000-2022 GFD Dennou Club. All rights reserved.
 *----------------------------------------------------------------------*/
#ifndef WIN32
#include <stdlib.h>
#endif
#include "../../../config.h"

static float **cxs, **cys;

/*--- PRIVATE ---*/
static float **alloc_2d(int n, int m)  
{
    /* Allocate a 2D array of shape [n][m].
     * Use free_2d to free the array */
    float **b;
    int i;
    b = (float **)malloc((unsigned int) n*sizeof(float*));
    b[0] = (float *)malloc((unsigned int) n*m*sizeof(float));
    for(i=1;i<n;i++) {b[i] = b[i-1]+m;}
    return(b);
}
static void free_2d(float **b)
{
    free(b[0]);
    free(b);
}

/*--- PUBLIC ---*/
#ifndef WINDOWS
void g2qgrd_(DCL_INT *i, DCL_INT *j, 
             DCL_REAL *cx11, DCL_REAL *cx21, DCL_REAL *cx12, DCL_REAL *cx22, 
             DCL_REAL *cy11, DCL_REAL *cy21, DCL_REAL *cy12, DCL_REAL *cy22)
#else
void G2QGRD(DCL_INT *i, DCL_INT *j, 
             DCL_REAL *cx11, DCL_REAL *cx21, DCL_REAL *cx12, DCL_REAL *cx22, 
             DCL_REAL *cy11, DCL_REAL *cy21, DCL_REAL *cy12, DCL_REAL *cy22)
#endif
{
    /* NOTE: C indices are 1 smaller than Fortran indices */
    *cx11 = cxs[*j-1][*i-1];
    *cx21 = cxs[*j-1][*i];
    *cx12 = cxs[*j][*i-1];
    *cx22 = cxs[*j][*i];
    *cy11 = cys[*j-1][*i-1];
    *cy21 = cys[*j-1][*i];
    *cy12 = cys[*j][*i-1];
    *cy22 = cys[*j][*i];
}

#ifndef WINDOWS
void g2sgrd_(DCL_REAL *rundef, 
             DCL_INT *iuxinc, DCL_INT *iuyinc, DCL_INT *nx, DCL_INT *ny, 
             DCL_REAL *cx, DCL_REAL *cy, DCL_REAL *uxs, DCL_REAL *uys)
#else
void G2SGRD(DCL_REAL *rundef, 
             DCL_INT *iuxinc, DCL_INT *iuyinc, DCL_INT *nx, DCL_INT *ny, 
             DCL_REAL *cx, DCL_REAL *cy, DCL_REAL *uxs, DCL_REAL *uys)
#endif
{
    static int first = 1;
    int i,j;
    int cxundef, cyundef;

    /* free if not first time */
    if(!first){
	free_2d(cxs);
	free_2d(cys);
    }

    /* store CX and CY */

    cxs = alloc_2d(*ny, *nx);
    cys = alloc_2d(*ny, *nx);
    first = 0;

    if (cx[0]==(*rundef)) {
	/* Assume cx[j][i] == ux[i] */
	cxundef = 1;
	for(j=0;j<*ny;j++){
	    for(i=0;i<*nx;i++){
		cxs[j][i] = uxs[i];
	    }
	}
    } else {
	cxundef = 0;
    }

    if (cy[0]==(*rundef)) {
	/* Assume cy[j][i] == uy[j] */
	cyundef = 1;
	for(j=0;j<*ny;j++){
	    for(i=0;i<*ny;i++){
		cys[j][i] = uys[j];
	    }
	}
    } else {
	cyundef = 0;
    }

    if((*iuxinc) && (*iuyinc) ){
	for(j=0;j<*ny;j++){
	    for(i=0;i<*nx;i++){
		if(!cxundef) cxs[j][i] = cx[*nx*j+i];
		if(!cyundef) cys[j][i] = cy[*nx*j+i];
	    }
	}
    } else if ( !(*iuxinc) && (*iuyinc) ) {
	for(j=0;j<*ny;j++){
	    for(i=0;i<*nx;i++){
		if(!cxundef) cxs[j][*nx-1-i] = cx[*nx*j+i];
		if(!cyundef) cys[j][*nx-1-i] = cy[*nx*j+i];
	    }
	}
    } else if ( (*iuxinc) && !(*iuyinc) ) {
	for(j=0;j<*ny;j++){
	    for(i=0;i<*nx;i++){
		if(!cxundef) cxs[*ny-1-j][i] = cx[*nx*j+i];
		if(!cyundef) cys[*ny-1-j][i] = cy[*nx*j+i];
	    }
	}
    } else {
	for(j=0;j<*ny;j++){
	    for(i=0;i<*nx;i++){
		if(!cxundef) cxs[*ny-1-j][*nx-1-i] = cx[*nx*j+i];
		if(!cyundef) cys[*ny-1-j][*nx-1-i] = cy[*nx*j+i];
	    }
	}
    }

}
