/**
* Copyright 1981-2012 ECMWF.
*
* This software is licensed under the terms of the Apache Licence 
* Version 2.0 which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
*
* In applying this licence, ECMWF does not waive the privileges and immunities 
* granted to it by virtue of its status as an intergovernmental organisation 
* nor does it submit to any jurisdiction.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/fortint.h"

#define LINESIZE 80
#define format 0x666F726D
#define table 0x7461626C
#define parameter 0x70617261
#define truncation 0x7472756E
#define accuracy 0x61636375
#define grid 0x67726964
#define gaussian 0x67617573
#define area 0x61726561
#define scan 0x7363616E
#define reduced 0x72656475
#define uselsm 0x7573656C
#define usewind 0x75736577
#define useprecip 0x75736570
#define lsm_param 0x6C736D5F

/*
// defines for FORTRAN subroutine
*/
#ifdef FORTRAN_NO_UNDERSCORE
#define CLEAR_C clear_c
#define IAINIT iainit
#define INIT_CM init_cm
#define RDDEFS rddefs
#else
#define CLEAR_C clear_c_
#define IAINIT iainit_
#define INIT_CM init_cm_
#define RDDEFS rddefs_
#endif

#define NIFORM 1
#define NOFORM 2
#define NITABLE 3
#define NIPARAM 4
#define NIRESO 5
#define NORESO 6
#define NOACC 7
#define NIGRID1 8
#define NIGRID2 9
#define NOGRID1 10
#define NOGRID2 11
#define NIGAUSS 12
#define NOGAUSS 13
#define NIAREA1 14
#define NIAREA2 15
#define NIAREA3 16
#define NIAREA4 17
#define NOAREA1 18
#define NOAREA2 19
#define NOAREA3 20
#define NOAREA4 21
#define NISCNM  22
#define NOSCNM  23
#define LSM     24
#define LWIND   25
#define LPREC   26
#define NIREDU  27
#define NOREDU  28
#define LSMPAR  29

/*
// Prototypes
*/
void set_format(char * inputval, char * outputval);
void set_table(char * inputval, char * outputval);
void set_parameter(char * inputval, char * outputval);
void set_truncation(char * inputval, char * outputval);
void set_accuracy(char * inputval, char * outputval);
void set_grid(char * inputval, char * outputval);
void set_gaussian(char * inputval, char * outputval);
void set_area(char * inputval, char * outputval);
void set_scan(char * inputval, char * outputval);
void set_reduced(char * inputval, char * outputval);
void set_uselsm(char * inputval, char * outputval);
void set_usewind(char * inputval, char * outputval);
void set_useprecip(char * inputval, char * outputval);
void set_lsm_param(char * inputval, char * outputval);
void INIT_CM( fortint *, fortint *);

fortint RDDEFS()
{
/*
// The file handling is currently not used!
//
// char * fallback_defaults_file = "/home/ma/mac/public/gp2gp/request_defaults";
// char * fallback_defaults_file = "/home/ma/mac/public/gp2gp/no_chance";
// char * defaults_file;
*/
FILE * file;
int i_status;
char line[LINESIZE+1];
char keyword[LINESIZE];
char inputval[LINESIZE];
char outputval[LINESIZE];
int count = 0, i;
unsigned long code=0;
int kpr = 0;
int kerr = 1;

/*
//  Clear the common block
*/
    CLEAR_C();
    IAINIT( &kpr, kerr);

/*
// The file handling is currently not used!
//
// Open the file defining the defaults
//
// defaults_file = getenv("REQUEST_DEFAULTS");
//  if( defaults_file == NULL )
//      defaults_file = fallback_defaults_file;
//
//  file = fopen( defaults_file, "r");
//
//
//  If no file, set the defaults here
*/
    file = NULL;                        /* file handling currently not used! */
    if( file == NULL ) {
      set_format("grib","grib");
      set_table("128","");
      set_parameter("0","");
      set_area("0/0/0/0","0/0/0/0");
      set_scan("0","0");
      return 0;
    }

/*
//  Ignore the 2 title lines, then a line at a time from the file
*/
    while( fgets( line, LINESIZE, file) != NULL ) {
      count++;
      if ( count > 2 ) {
/*
//      Split the line up
*/
        i_status = sscanf( line, "%s%s%s", keyword, inputval, outputval);
        if ( (i_status != 3) && (i_status != EOF ) ) {
          perror("sscanf failed");
          exit(1);
        }
/*
//      Move first 4 characters of the keyword into the switch variable
*/
        for( i = 0; i < 4; i++ )
          code = ( (code << 8) + *(keyword+i) ) & 0xFFFFFFFF;

/*
//      Handle the keywords individually
*/
        switch( code ) {

          case format:     set_format(inputval, outputval);
                           break;

          case table:      set_table(inputval, outputval);
                           break;

          case parameter:  set_parameter(inputval, outputval);
                           break;

          case truncation: set_truncation(inputval, outputval);
                    break;

          case accuracy:   set_accuracy(inputval, outputval);
                           break;

          case grid:       set_grid(inputval, outputval);
                           break;

          case gaussian:   set_gaussian(inputval, outputval);
                           break;

          case area:       set_area(inputval, outputval);
                           break;

          case scan:       set_scan(inputval, outputval);
                           break;

          case reduced:    set_reduced(inputval, outputval);
                           break;

          case uselsm:     set_uselsm(inputval, outputval);
                           break;

          case usewind:    set_usewind(inputval, outputval);
                           break;

          case useprecip:  set_useprecip(inputval, outputval);
                           break;

          case lsm_param:  set_lsm_param(inputval, outputval);
                           break;

          default:         printf("Invalid code: %x\n", code);
                           break;
        }
      }
    }

    return 0;
}

void set_format(char * inputval, char * outputval)
{
fortint p1, p_1 = 1, p_0 = 0;

    p1 = NIFORM;
    if ( strcmp( inputval, "grib") == 0 )
        INIT_CM( &p1, &p_1);
    else
        INIT_CM( &p1, &p_0);

    p1 = NOFORM;
    if ( strcmp( outputval, "grib") == 0 )
        INIT_CM( &p1, &p_1);
    else
        INIT_CM( &p1, &p_0);

    return;
}

void set_table(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;

    p1 = NITABLE;
    q2 = atoi( inputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    return;
}

void set_parameter(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;

    p1 = NIPARAM;
    q2 = atoi( inputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    return;
}

void set_truncation(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;

    p1 = NIRESO;
    q2 = atoi( inputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    p1 = NORESO;
    q2 = atoi( outputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    return;
}

void set_accuracy(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;
 
    p1 = NOACC;
    q2 = atoi( outputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);
 
    return;
}

void set_grid(char * inputval, char * outputval)
{
fortint p1,p2,p3;
int q2,q3;

    p1 = NIGRID1;
    sscanf( inputval, "%d/%d", &q2, &q3);
    p2 = (fortint) q2;
    p3 = (fortint) q3;
    INIT_CM( &p1, &p2);

    p1 = NIGRID2;
    INIT_CM( &p1, &p3);
    
    p1 = NOGRID1;
    sscanf( outputval, "%d/%d", &q2, &q3);
    p2 = (fortint) q2;
    p3 = (fortint) q3;
    INIT_CM( &p1, &p2);

    p1 = NOGRID2;
    INIT_CM( &p1, &p3);
    
    return;
}

void set_gaussian(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;

    p1 = NIGAUSS;
    q2 = atoi( inputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    p1 = NOGAUSS;
    q2 = atoi( outputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);

    return;
}

void set_area(char * inputval, char * outputval)
{
fortint p1,p2,p3,p4,p5;
int q2, q3, q4, q5;

    p1 = NIAREA1;
    sscanf( inputval, "%d/%d/%d/%d", &q2, &q3,&q4,&q5);
    p2 = (fortint) q2;
    p3 = (fortint) q3;
    p4 = (fortint) q4;
    p5 = (fortint) q5;
    INIT_CM( &p1, &p2);

    p1 = NIAREA2;
    INIT_CM( &p1, &p3);

    p1 = NIAREA3;
    INIT_CM( &p1, &p4);

    p1 = NIAREA4;
    INIT_CM( &p1, &p5);
    
    p1 = NOAREA1;
    sscanf( outputval, "%d/%d/%d/%d", &q2, &q3,&q4,&q5);
    p2 = (fortint) q2;
    p3 = (fortint) q3;
    p4 = (fortint) q4;
    p5 = (fortint) q5;
    INIT_CM( &p1, &p2);

    p1 = NOAREA2;
    INIT_CM( &p1, &p3);

    p1 = NOAREA3;
    INIT_CM( &p1, &p4);

    p1 = NOAREA4;
    INIT_CM( &p1, &p5);
    
    return;
}

void set_scan(char * inputval, char * outputval)
{
fortint p1, p2;
int q2;
 
    p1 = NISCNM;
    q2 = atoi( inputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);
 
    p1 = NOSCNM;
    q2 = atoi( outputval );
    p2 = (fortint) q2;
    INIT_CM( &p1, &p2);
 
    return;
}

void set_reduced(char * inputval, char * outputval)
{
fortint p1, p2;
 
    p1 = NIREDU;
    if ( strcmp( inputval, "standard" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);
 
    p1 = NOREDU;
    if ( strcmp( outputval, "standard" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);

    return;
}

void set_uselsm(char * inputval, char * outputval)
{
fortint p1, p2;
 
    p1 = LSM;
    if ( strcmp( inputval, "yes" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);
 
    return;
}

void set_usewind(char * inputval, char * outputval)
{
fortint p1, p2;
 
    p1 = LWIND;
    if ( strcmp( inputval, "yes" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);
 
    return;
}

void set_useprecip(char * inputval, char * outputval)
{
fortint p1, p2;
 
    p1 = LPREC;
    if ( strcmp( inputval, "yes" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);
 
    return;
}

void set_lsm_param(char * inputval, char * outputval)
{
fortint p1, p2;
 
    p1 = LSMPAR;
    if ( strcmp( inputval, "yes" ) == 0 )
        p2 = 1;
    else
        p2 = 0;
    INIT_CM( &p1, &p2);

    return;
}

