#!/usr/bin/perl -w  # -*- cperl -*- #
#
#  config.pm - A simple `name=value` configuration file reader.
#
#  GNU MP3D - A portable(ish) MP3 server.
#
# Homepage:
#   http://www.gnump3d.org/
#
# Author:
#  Steve Kemp <steve@steve.org.uk>
#
# 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
#  Steve Kemp
#  ---
#  http://www.steve.org.uk/


package gnump3d::config;  # must live in config.pm
require Exporter;
use strict;
use vars       qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

# set the version for version checking
$VERSION     = "0.01";

@ISA         = qw(Exporter);
@EXPORT      = qw( &readConfig &getConfig &configFile &getHash &configUsesEnvironment &isWindows );
%EXPORT_TAGS = ( );

# your exported package globals go here,
# as well as any optionally exported functions
@EXPORT_OK   = ( ) ;


#
#  The hash storing the name and values we read from the
# configuration file.
#
my %HASH     = ();


#
#  The file that we, last, read our configuration values from.
#
my $CONFIG_FILE = "";

#
#  If this is set then environmental variables may override the
# configuration file.
#
my $USE_ENVIRONMENT = 0;



#
#
#  Read the configuration file.
#
#
sub readConfig($)
{
    my ($file) = (@_);

    #
    # Save the name of the configuratione file.
    #
    $CONFIG_FILE = $file;

    open( FILY, "<$file" ) or die "Cannot open file: $file - $!";

    my $line       = ""; 
    my $fieldCount = -1;
    my $lineCount  = 0;

    while (defined($line = <FILY>) ) 
    {
        chomp $line;
	if ($line =~ s/\\$//) 
	{
	    $line .= <FILY>;
	    redo unless eof(FILY);
	}
      
	# Skip lines beginning with comments
	next if ( $line =~ /^([ \t]*)\#/ );

	# Skip blank lines
	next if ( length( $line ) < 1 );

	# Strip trailing comments.
	if ( $line =~ /(.*)\#(.*)/ )
	{
	    $line = $1;
	}

	# Find variable settings
	if ( $line =~ /([^=]+)=([^\n]+)/ )
	{
	    my $key = $1;
	    my $val = $2;

	    # Strip leading and trailing whitespace.
	    $key =~ s/^\s+//;
	    $key =~ s/\s+$//;
	    $val =~ s/^\s+//;
	    $val =~ s/\s+$//;
	    
	    # Store value.
	    $HASH{ $key } = $val;
	}
    }

    close( FILY );
}


#
#  Allow the caller to specify if environmental variables may be used
# to override the configuration file settings.
#
#  Default is not to allow this.
#
sub configUsesEnvironment( $ )
{
    my ( $enabled ) = ( @_ );
    $USE_ENVIRONMENT = $enabled;
}


#
#
#  Return a configuration setting from the config file.
#
#
sub getConfig( $ $ )
{
    my ( $key, $default ) = ( @_ );
    my $value   = undef;

    if ( $USE_ENVIRONMENT )
    {
	$value = $ENV{$key};
    }

    if ( !defined( $value ) )
    {
	if( defined( $HASH{ $key } ) )
	{
	    $value = $HASH{ $key };
	}
	else
	{
	    return( $default );
	}
    }
    return( $value );
}



#
# Return the name of the configuration file we read.
#
sub configFile( )
{
    return( $CONFIG_FILE );
}


#
#  Return the hash of all our configuration options to
# the caller.
#
sub getHash()
{
    return( %HASH );
}


#
#  Return '1' if the system is running under Windows.
#
sub isWindows()
{
  if ( $^O =~ /win/i )
  {
    return 1;
  }
  else
  {
    return 0;
  }
}


#
# End of module
#
1;



=head1 NAME

gnump3d::config - A simple module for reading configuration variables.

=head1 SYNOPSIS

    use gnump3d::config;
    &readConfig( "/some/config.ini" );

    my $val = &getConfig( "key1", "default-value" );

=head1 DESCRIPTION

This module is a simple means of reading in configuration
variables from a standard .ini type configuration file.

The file is assumed to contain lines of the form:

   key = value

Lines beginning with '#' are comments which are ignored.

=head2 Methods

=over 12

=item C<readConfig>

Read in the configuration file specified, and initialize
state.

=item C<getConfig>

Return the value of a given key, if the key isn't present in
the configuration file then return the supplied default.

=item C<configFile>

Return the name of the configuration file which was used to
read in the values from.

=item C<getHash>

Return a hash containing all the configuration keys and values
contained in the file.

=item C<isWindows>

A utility method for detecting whether the module is running
under the Microsoft Windows operating system.

=back

=head1 AUTHOR

  Part of GNUMP3d, the MP3/OGG/Audio streaming server.

Steve - http://www.gnump3d.org/

=head1 SEE ALSO

L<gnump3d>

=cut
