/******************************************************************************
*		       							      *
* gnome/conf.c (part of rcalc)					       	      *
* Copyright (C) 2001 Free Software Foundation, Inc.			      *
*								       	      *
* This program is free software; you can redistribute it and/or modify 	      *
* it under the terms of the GNU General Public License as published by 	      *
* the Free Software Foundation; either version 2 of the License, or    	      *
* (at your option) any later version.				       	      *
*								       	      *
* This program is distributed in the hope that it will be useful,      	      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       	      *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	       	      *
* GNU General Public License for more details.			       	      *
*								       	      *
* You should have received a copy of the GNU General Public License    	      *
* along with this program; if not, write to the Free Software	       	      *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.	       	      *
*								       	      *
******************************************************************************/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include "conf.h"		/* This file's header	     		*/

#include <gnome.h>

/*****************************************************************************/

/* Class definition.
*/
struct _RcGnomeUiCfg
{
	RcScrollbarPos	scrollbar_pos;
	guint		scrollback_lines;
	gboolean	scroll_on_keystroke;
	gboolean	scroll_on_output;
	gboolean	blinking_cursor;
	gboolean	terminal_bell;
	gchar	       *font_name;
	gushort		colours[_RC_NUMBER_OF_COLOURS][3];
};

/* Some of the less-convenient defaults.
*/
#define DEFAULT_FONT		"courier Medium 12"

static gushort DEFAULT_PALETTE[_RC_NUMBER_OF_COLOURS][3]=
{
	{ 0x0000, 0x0000, 0x0000 },	/* Foreground			*/
	{ 0xFFFF, 0xFFFF, 0xFFFF },	/* Background			*/
	{ 0x0000, 0x0000, 0xCF3C },	/* Prompt			*/
	{ 0xCF3C, 0x0000, 0x0000 },	/* Errors			*/
};

/* Names for the entries in RcScrollbarPos and RcColour.
*/
static gchar *scrollbar_positions[_RC_NUMBER_OF_SCROLLBAR_POSES]=
{
	"left", "right", "hidden"
};
static gchar *colour_names[_RC_NUMBER_OF_COLOURS]=
{
	"foreground", "background", "prompt", "error"
};
static gchar *gun_names = "rgb";

/*****************************************************************************/

/* Constructor
*/
RcGnomeUiCfg* rcg_conf_new( void )
{
	RcGnomeUiCfg *cfg;
	int i;
	
	/* Allocate the memory.
	*/
	cfg = g_new0( RcGnomeUiCfg, 1 );

	/* Set the defaults.
	*/
	rcg_conf_set_scrollbar_pos( cfg, RC_SCROLLBAR_RIGHT );
	rcg_conf_set_scrollback( cfg, 100 );
	rcg_conf_set_scroll_on_key( cfg, TRUE );
	rcg_conf_set_scroll_on_out( cfg, TRUE );
	rcg_conf_set_blink( cfg, FALSE );
	rcg_conf_set_bell( cfg, TRUE );

	cfg->font_name = g_strdup( DEFAULT_FONT );

	for( i=0; i<_RC_NUMBER_OF_COLOURS; i++ )
		rcg_conf_set_colour( cfg, i, DEFAULT_PALETTE[i] );

	return cfg;
}

/* Destructor
*/
void rcg_conf_delete( RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	g_assert( cfg->font_name );
	g_free( cfg->font_name );
	g_free( cfg );
}

/*****************************************************************************/

/* Load the state.
*/
void rcg_conf_load_state( RcGnomeUiCfg *cfg )
{
	gint config_version;
	gchar *scrollbar_pos;
	int i,j;
	
	g_assert( cfg );
	gnome_config_push_prefix( "/" PACKAGE "/GnomeUI/" );
	
	/* Configuration version control.
	*/
	config_version = gnome_config_get_int( "config_version=3" );
	g_assert( config_version==3 );

	/* Behaviour settings.
	*/
	scrollbar_pos = gnome_config_get_string( "scrollbar_position=right" );
	for( i=0; ; i++ )
	{
		g_assert( i<_RC_NUMBER_OF_SCROLLBAR_POSES );

		if( strcmp( scrollbar_pos, scrollbar_positions[i] ) ) continue;

		rcg_conf_set_scrollbar_pos( cfg, i );
		break;
	}
	g_free( scrollbar_pos );

	rcg_conf_set_scrollback(
		cfg, gnome_config_get_int( "scrollback_lines=100" ) );
	rcg_conf_set_scroll_on_key(
		cfg, gnome_config_get_bool( "scroll_on_key=true" ) );
	rcg_conf_set_scroll_on_out(
		cfg, gnome_config_get_bool( "scroll_on_output=true" ) );
	rcg_conf_set_blink(
		cfg, gnome_config_get_bool( "blinking_cursor=false" ) );
	rcg_conf_set_bell(
		cfg, gnome_config_get_bool( "terminal_bell=true" ) );

	/* Appearance settings
	*/
	rcg_conf_set_font_name(
		cfg, gnome_config_get_string( "font_name=" DEFAULT_FONT ) );
	
	for( i=0; i<_RC_NUMBER_OF_COLOURS; i++ )
	{
		gushort colour[3];
		for( j=0; j<3; j++ )
		{
			gchar key[32];

			sprintf( key, "colour[%s].%c=%d",
				 colour_names[i], gun_names[j],
				 DEFAULT_PALETTE[i][j] );

			colour[j] = gnome_config_get_int( key );
		}
		rcg_conf_set_colour( cfg, i, colour );
	}
	
	gnome_config_pop_prefix();
}

/* Save the state.
*/
void rcg_conf_save_state( const RcGnomeUiCfg *cfg )
{
	int i,j;

	g_assert( cfg );

	gnome_config_clean_section( "/" PACKAGE "/GnomeUI/" );
	gnome_config_push_prefix( "/" PACKAGE "/GnomeUI/" );
	
	/* Configuration version control.
	*/
	gnome_config_set_int( "config_version", 3 );

	/* Behaviour settings.
	*/
	gnome_config_set_string(
		"scrollbar_position",
		scrollbar_positions[ rcg_conf_get_scrollbar_pos(cfg) ] );	
	gnome_config_set_int(
		"scrollback_lines", rcg_conf_get_scrollback(cfg) );
	gnome_config_set_bool(
		"scroll_on_key", rcg_conf_get_scroll_on_key(cfg) );
	gnome_config_set_bool(
		"scroll_on_output", rcg_conf_get_scroll_on_out(cfg) );
	gnome_config_set_bool(
		"blinking_cursor", rcg_conf_get_blink(cfg) );
	gnome_config_set_bool(
		"terminal_bell", rcg_conf_get_bell(cfg) );

	/* Appearance settings.
	*/
	gnome_config_set_string( "font_name", rcg_conf_get_font_name(cfg) );
	for( i=0; i<_RC_NUMBER_OF_COLOURS; i++ )
	{
		const gushort *colour = rcg_conf_get_colour( cfg, i );
		for( j=0; j<3; j++ )
		{
			gchar key[32];
			
			sprintf( key, "colour[%s].%c",
				 colour_names[i], gun_names[j] );
			
			gnome_config_set_int( key, colour[j] );
		}
	}

	gnome_config_pop_prefix();
}

/*****************************************************************************/

/* Get and set the position of the scrollbar.
*/
RcScrollbarPos rcg_conf_get_scrollbar_pos( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->scrollbar_pos;
}
void rcg_conf_set_scrollbar_pos( RcGnomeUiCfg *cfg, RcScrollbarPos pos )
{
	g_assert( cfg );
	g_assert( pos>=0 && pos<_RC_NUMBER_OF_SCROLLBAR_POSES );

	cfg->scrollbar_pos = pos;
}

/*****************************************************************************/

/* Get and set the number of scrollback lines.
*/
guint rcg_conf_get_scrollback( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->scrollback_lines;
}
void rcg_conf_set_scrollback( RcGnomeUiCfg *cfg, guint lines )
{
	g_assert( cfg );
	cfg->scrollback_lines = lines;
}

/*****************************************************************************/

/* Get and set whether the terminal should scroll to the bottom when a
** key is pressed.
*/
gboolean rcg_conf_get_scroll_on_key( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->scroll_on_keystroke;
}
void rcg_conf_set_scroll_on_key( RcGnomeUiCfg *cfg, gboolean state )
{
	g_assert( cfg );
	cfg->scroll_on_keystroke = state;
}

/*****************************************************************************/

/* Get and set whether the terminal should scroll to the bottom when
** output happens.
*/
gboolean rcg_conf_get_scroll_on_out( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->scroll_on_output;
}
void rcg_conf_set_scroll_on_out( RcGnomeUiCfg *cfg, gboolean state )
{
	g_assert( cfg );
	cfg->scroll_on_output = state;
}

/*****************************************************************************/

/* Get and set whether the cursor should flash.
*/
gboolean rcg_conf_get_blink( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->blinking_cursor;
}
void rcg_conf_set_blink( RcGnomeUiCfg *cfg, gboolean state )
{
	g_assert( cfg );
	cfg->blinking_cursor = state;
}

/*****************************************************************************/

/* Get and set whether the bell should sound.
*/
gboolean rcg_conf_get_bell( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	return cfg->terminal_bell;
}
void rcg_conf_set_bell( RcGnomeUiCfg *cfg, gboolean state )
{
	g_assert( cfg );
	cfg->terminal_bell = state;
}

/*****************************************************************************/

/* Get and set the name of the font.
*/
const gchar* rcg_conf_get_font_name( const RcGnomeUiCfg *cfg )
{
	g_assert( cfg );
	g_assert( cfg->font_name );

	return cfg->font_name;
}
void rcg_conf_set_font_name( RcGnomeUiCfg *cfg, const gchar *font )
{
	g_assert( cfg );
	g_assert( font );

	g_free( cfg->font_name );
	cfg->font_name = g_strdup( font );
}

/*****************************************************************************/

/* Get and set the colours.
*/
const gushort* rcg_conf_get_colour( const RcGnomeUiCfg *cfg, RcColour colour )
{
	g_assert( cfg );
	g_assert( colour>=0 && colour<_RC_NUMBER_OF_COLOURS );
	
	return cfg->colours[colour];
}
void rcg_conf_set_colour(
	RcGnomeUiCfg *cfg, RcColour colour, const gushort *rgb )
{
	int i;
	
	g_assert( cfg );
	g_assert( colour>=0 && colour<_RC_NUMBER_OF_COLOURS );
	g_assert( rgb );

	for( i=0; i<3; i++ ) cfg->colours[colour][i] = rgb[i];
}

/*** end of gnome/conf.c *****************************************************/
