/*
 * © Copyright 1996-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 "mars.h"

#define P_INST 0
#define P_TAVG 1
#define P_TACC 3

#define TYPE_AN  2
#define TYPE_FC  9
#define TYPE_CF 10
#define TYPE_PF 11
#define TYPE_FF 25
#define TYPE_OF 26
#define TYPE_OR 70
#define TYPE_FX 71

int grib_ocean_fix_section_1 (gribsec1 *s1,request *r)
{
    int ierror =0;
	fortint mars_type = s1->local.mars_type;

    static char *iproduct[] = {
	/* 0*/ "INST",
	/* 1*/ "TAVG",
	/* 2*/ "2",
	/* 3*/ "TACC",
	};

    static char *isection[] = {
    /*  */ "0",
    /* 1*/ "1",
    /* 2*/ "H",
	/* 3*/ "M",
	/* 4*/ "Z",
	};

    static char *tsection[] = {
	/*  */ "0",
	/* 1*/ "1",
	/* 2*/ "2",
	/* 3*/ "V",
	/* 4*/ "Z",
	/* 5*/ "M",
	};

    /* gribsec1_extra *extra_s1 = grib_extra_section_1(s1); */

	/* EM, STD, CF, PB, PD do not have NUMBER */
	/* This is for old Monthly Forecast, present in MARS archive only.
	   They have been superseed by new Monthly Forecast */
	if(s1->local.mars_type != 17 && 
	   s1->local.mars_type != 18 && 
	   s1->local.mars_type != 29 && 
	   s1->local.mars_type != 36 && 
	   s1->local.mars_type != 10)	
	{
		set_value(r,"NUMBER","%"D"",s1->local.u.ocean.mars_number);
	}

	/* This is very ugly, but I didn't know anywhere else
	   where to put it */
	if(s1->local.mars_stream != GRIB_STREAM_ENFO &&
	   s1->local.mars_stream != GRIB_STREAM_ENFO_HINDCAST_OBSOLETE &&
	   s1->local.mars_stream != GRIB_STREAM_ENFH_HINDCAST &&
	   s1->local.mars_stream != GRIB_STREAM_EFHO_HINDCAST)
	{
		set_value(r,"METHOD","%"D"",s1->local.u.ocean.method);

		if(s1->local.mars_class == GRIB_CLASS_OD)
			set_value(r,"SYSTEM","%"D"",s1->local.u.ocean.system);
	}
	set_value(r,"_TOTAL_NUMBER","0");

    if(s1->local.u.ocean.horizontal_coordinates == 0)
    {
		fortfloat coord1 = s1->local.u.ocean.coordinate_1_start_position;
		fortfloat coord2 = s1->local.u.ocean.coordinate_2_start_position;

		if(s1->local.u.ocean.coordinate_1_locating == 1 )    /* instantaneously valid fields */
        {
			if(s1->local.u.ocean.coordinate_1_averaging >= 0 && 
                s1->local.u.ocean.coordinate_1_averaging < NUMBER(iproduct))
			{
				set_value(r,"PRODUCT","%s",
					iproduct[s1->local.u.ocean.coordinate_1_averaging]);
			}

			/* Especial case for OR products. */
			/* The GRIB header does not fit the standards of MARS */

			/* TYPE=OR 
			   PRODUCT=TAVG or TACC */
		    if(mars_type == TYPE_OR && (s1->local.u.ocean.coordinate_1_averaging == P_TAVG ||
			s1->local.u.ocean.coordinate_1_averaging == P_TACC))
		    {
				basedate_to_verifydate(s1,r);
                if(s1->local.u.ocean.coordinate_1_averaging == P_TAVG)
                {
                   set_value(r,"RANGE","%"D"",
                             (s1->local.u.ocean.coordinate_1_end_position -
                             s1->local.u.ocean.coordinate_1_start_position)/3600);
                }
		    }
			/* TYPE=FC,CF,FF or OF   PRODUCT=TAVG or TACC */
            else if ((mars_type == TYPE_FC || mars_type == TYPE_CF || mars_type == TYPE_PF ||
					  mars_type == TYPE_FF || mars_type == TYPE_OF) && 
					 s1->local.u.ocean.coordinate_1_averaging == P_TAVG ||
                     s1->local.u.ocean.coordinate_1_averaging == P_TACC)
            {
				/* TYPE=FC, PRODUCT=TAVG needs RANGE */
				if ((mars_type == TYPE_FC || mars_type == TYPE_FF) && (s1->local.u.ocean.coordinate_1_averaging == P_TAVG))
				{
                   set_value(r,"RANGE","%"D"",
                             (s1->local.u.ocean.coordinate_1_end_position -
                             s1->local.u.ocean.coordinate_1_start_position)/3600);
				}
            }
			/* TYPE=AN/OR, PRODUCT=INST */
            else if ((mars_type == TYPE_AN || mars_type == TYPE_OR) && s1->local.u.ocean.coordinate_1_averaging == P_INST)
            {
            }
			/* TYPE=FC,CF,FF or OF   PRODUCT=INST */
            else if ((mars_type == TYPE_FC || mars_type == TYPE_CF || mars_type == TYPE_PF ||
					  mars_type == TYPE_FF || mars_type == TYPE_OF) && 
					  s1->local.u.ocean.coordinate_1_averaging == P_INST)
            {
            }
			/* TYPE=FX, PRODUCT=TAVG */
            else if (mars_type == TYPE_FX && s1->local.u.ocean.coordinate_1_averaging == P_TAVG)
            {
				basedate_to_verifydate(s1,r);
                set_value(r,"RANGE","%"D"",
                         (s1->local.u.ocean.coordinate_1_end_position -
                          s1->local.u.ocean.coordinate_1_start_position)/3600);
            }
			else
			{
				ierror=1;
				marslog(LOG_WARN,"Unknown coordinate 1 averaging value : %"D"",
				s1->local.u.ocean.coordinate_1_averaging);
			}

			if(s1->local.u.ocean.coordinate_2_locating > 0 &&
				s1->local.u.ocean.coordinate_2_locating < NUMBER(isection))
			{
				set_value(r,"SECTION","%s",
					isection[s1->local.u.ocean.coordinate_2_locating]);
			}
			else
			{
				ierror=1;
				marslog(LOG_WARN,"Unknown section configuration : %"D"",
				s1->local.u.ocean.coordinate_2_locating);
			}

            switch((int)s1->local.u.ocean.coordinate_2_locating)
            {
				case GRIB_DEPTH:                       /* 2 horizontal fields */
			         set_value(r,"LEVELIST", "%.3f",round_decimal(coord2/1.0e3));
                     break;
                case GRIB_LONGITUDE:                   /* 3 meridional fields */
                     set_value(r,"LONGITUDE", "%.3f",round_decimal(coord2/1.0e6));
			         /* set_value(r,"LEVELIST", "OFF"); */
                     break;
                case GRIB_LATITUDE:                    /* 4 longitudinal fields */
                     set_value(r,"LATITUDE", "%.3f",round_decimal(coord2/1.0e6));
			         /* set_value(r,"LEVELIST", "OFF"); */
                     break;
            }
        }
	   else                                               /* time series */
       {
            set_value(r,"PRODUCT","TIMS");

			/* Especial case for OR products. */
			/* The GRIB header does not fit the standards of MARS */

		    if((mars_type == TYPE_OR || mars_type == TYPE_FC || mars_type == TYPE_CF || mars_type == TYPE_PF ||
				mars_type == TYPE_FF || mars_type == TYPE_OF) && 
				s1->local.u.ocean.coordinate_1_averaging == 0)
		    {
				if(mars_type == TYPE_OR)
					basedate_to_verifydate(s1,r);

                set_value(r,"RANGE","%"D"",(s1->local.u.ocean.coordinate_3_end_grid_point -
                                          s1->local.u.ocean.coordinate_3_start_grid_point)/3600);
                if( s1->local.u.ocean.coordinate_4_axis == 1)
                {
                   set_value(r,"RANGE","%"D"",(s1->local.u.ocean.coordinate_4_end_grid_point -
                                             s1->local.u.ocean.coordinate_4_start_grid_point)/3600);
                }
		    }

  			if(s1->local.u.ocean.coordinate_3_axis > 0 &&
  			   s1->local.u.ocean.coordinate_4_axis > 0 &&
			   s1->local.u.ocean.coordinate_3_axis +
  			   s1->local.u.ocean.coordinate_4_axis
                < NUMBER(tsection))
			{
				set_value(r,"SECTION","%s",
                tsection[s1->local.u.ocean.coordinate_3_axis + s1->local.u.ocean.coordinate_4_axis]);
			}
			else
			{
				ierror=1;
				marslog(LOG_WARN,"Unknown ocean axis coordinates : %"D" x %"D"",
				s1->local.u.ocean.coordinate_3_axis,
                s1->local.u.ocean.coordinate_4_axis);
			}

            if(s1->local.u.ocean.coordinate_3_axis + s1->local.u.ocean.coordinate_4_axis == 3)
            {
				set_value(r,"LATITUDE", "%.3f",round_decimal(coord1/1.0e6));
                set_value(r,"LONGITUDE", "%.3f",round_decimal(coord2/1.0e6));
            }
            else if(s1->local.u.ocean.coordinate_3_axis + s1->local.u.ocean.coordinate_4_axis == 4)
            {
			    set_value(r,"LEVELIST", "%.3f",round_decimal(coord1/1.0e3));
                set_value(r,"LATITUDE", "%.3f",round_decimal(coord2/1.0e6));
            }
            else if(s1->local.u.ocean.coordinate_3_axis + s1->local.u.ocean.coordinate_4_axis == 5) 
            {
			    set_value(r,"LEVELIST", "%.3f",round_decimal(coord1/1.0e3));
                set_value(r,"LONGITUDE", "%.3f",round_decimal(coord2/1.0e6));
            }
			else {
				ierror = 1;
				marslog(LOG_WARN,"Unknown ocean axis : %"D" x %"D"",
				s1->local.u.ocean.coordinate_3_axis,
				s1->local.u.ocean.coordinate_4_axis);
			   	 }
        }
    }

    return (ierror);
}

