/*
 * © 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"

void mars_grib_index_add(mars_grib_index* idx, const char* name, boolean s_ok, const char* s, boolean l_ok, long l, boolean d_ok, double d)
{
	mars_grib_map* m  = NEW_CLEAR(mars_grib_map);
	m->name = strcache(name);
	m->s_ok = s_ok;
	m->s_value = strcache(s);
	m->l_ok = l_ok;
	m->l_value = l;
	m->d_ok = d_ok;
	m->d_value = d;

	if(idx->head == NULL) 
		idx->head = m;
	else
		idx->tail->next = m;

	idx->tail = m;
}

mars_grib_index* mars_grib_index_new( off_t offset, long length )
{
	mars_grib_index* idx = NEW_CLEAR( mars_grib_index );
	idx->offset = offset;
	idx->length = length;
	return idx;
}

static void send_map( mstream* s, mars_grib_map* m )
{
	while( m )
	{
		stream_write_int(s,1);
		stream_write_string(s, m->name);

		stream_write_int(s,m->s_ok);
		if(m->s_ok) stream_write_string(s, m->s_value);

		stream_write_int(s,m->l_ok);
		if(m->l_ok) stream_write_long(s, m->l_value);

		stream_write_int(s,m->d_ok);
		if(m->d_ok) stream_write_double(s, m->d_value);

		m = m->next;
	}
	stream_write_int(s,0);
}

err mars_grib_index_send(mars_grib_index* idx, mstream* s)
{
	unsigned long count = 0;
	mars_grib_index* p = idx;
	while( p )
	{	
		count++;
		p = p->next;
	}
	stream_write_ulong(s, count);

	p = idx;
	while( p )
	{
		stream_write_ulonglong(s,p->offset);	
		stream_write_ulonglong(s,p->length);	

		send_map(s, p->head);

		p = p->next;
	}
	
	if(s->error)
	{
		marslog(LOG_EROR,"Error occurred when sending GRIB index to server");
	}

	return s->error;
}

static void free_map( mars_grib_map* m )
{
	while( m )
	{
		mars_grib_map* next = m->next;
		strfree(m->name);
		strfree(m->s_value);
		FREE( m );
		m = next;
	}
}

void mars_grib_index_free( mars_grib_index* idx )
{
	while( idx )
	{
		mars_grib_index* next = idx->next;
		free_map( idx->head);
		FREE( idx );
		idx = next;
	}
}

static void print_map( mars_grib_map* m )
{
	while( m )
	{
		mars_grib_map* next = m->next;
		printf(" %s", m->name);
		if(m->s_ok) printf(" s: %s",m->s_value);
		if(m->l_ok) printf(" l: %ld",m->l_value);
		if(m->d_ok) printf(" d: %g",m->d_value);
		m = next;
	}
}

void mars_grib_index_print( mars_grib_index* idx )
{
	while( idx )
	{
		mars_grib_index* next = idx->next;
		
		printf( "offset = %lld length = %ld", idx->offset, idx->length );
		print_map( idx->head );
		printf("\n");

		idx = next;
	}
}




