package Common::Config;

########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####

use strict;

sub new {
	my $class = shift;
	my $config_file = shift;
	my $self = {
							'config'	=> {},
							'path' => $config_file,
						 };
	return bless($self);
}

sub read_config() {
  my $this = shift;
	my $conf_file = $this->Path( shift, 'stat' );

  open (FILE, '<', $conf_file) or 
    die "Unable to open configuration file '$conf_file': $!\n";

	$this->{'config'} = {}; ## clean

	no strict 'refs';

	my ($key, $var, $ptrKey, $i, $bin );
  while ( <FILE> ) {
		$i++;
		chomp;

		next if /^\s*(#|$)/; ## skip empty line & comment

    ($key, $var) = $this->string_to_var_( $_ );
		if ( defined $key ) {
			$$this{'config'}{$key} = $var;
			$ptrKey = 'main::'.$key;

			if ( $key =~ /bin_(\S+)/ ){
				$main::bin{$1} = $var;
			}

			unless ( ${$ptrKey} eq $var ) {

				warn "Error parsing of '$conf_file'\n\t$i: $_\n".
					"\tkey: $key, old value: ${$ptrKey}, new value: $var\n";

				${$ptrKey} = $var; ## set up global variable
			}
		}
  }

	use strict 'refs';

  close(FILE);

}

sub Path(){
  my $this = shift;
  if ( @_ ) {
		my ($path,$stat) = @_;
    if ( -T $path ) {
      $this->{'path'} = $path;
			if ( $stat ) {
				if (my ($dev,$ino) = stat( $path ) ) {
					$this->{'id'} = "$dev.$ino";
				}else{
					$this->{'id'} = undef;
					die "Unable to call stat for '$path': $!\n";
				}
			}
    }
  }
  return $this->{'path'};
}

sub IsReaded(){
  my $this = shift;
  my $ret = 0;
  if (my $path = shift){
    if ( -T $path ) {
      if ( defined( $this->{'id'} ) ) {
				if (my ($dev,$ino) = stat( $path ) ) {
					$ret = ("$dev.$ino" eq $this->{'id'})?1:0;
				}
      }
    }
  }
  return $ret;
}

sub write_config () {
}

sub string_to_var_() {
	my $this = shift;
	
	my $string = shift;
	if ( !$string || ## empty string
			 $string=~/^\s*#/ ## comment
		 ) {
		return (undef,undef);
	}

	if ($string =~ /^\$(\S+)\s*=\s*(.+)\s*;/) {
		my $key = $1;
		my $var = $2;
		if ( $var =~ s/^('|")(.*)\1$/$2/ ){ ## strip begin/end quotes
			$var =~ s/\\(['"\\\/])/$1/g; ## unslash quotes, slashes
		} else {
			unless ( $var =~ /^\d+$/ ) {
				warn "parse error in confixx_main.conf: $string\nkey: $key, value: $var\n";
				$key = undef;
				$var = undef;
			}
		}

		return ($key, $var);

	} else {
		return (undef,undef);
	}
}

sub get_param ($) {
	my $this = shift;
	my ($param) = @_;

	return $$this{'config'}{$param};
}

sub set_param ($$) {
	my $this = shift;

	return $this->Value( @_ );
}

sub Value(){
  my $this = shift;
  my $key = shift;
  if ( $key ) {
    if ( @_ ) {
			my $val = shift;
      $$this{'config'}{$key} = $val;

#
# set value to global variable
#
			no strict 'refs';
			${"main::$key"} = $val;
			use strict 'refs';

			if ( $key =~ /^bin_(.+)$/) { ## $bin_* -> $bin{*}
				$main::bin{$1} = $val;
			}

    }
    return $$this{'config'}{$key};
  }
  return undef;
}

sub Param(){ ## alias for Param
  my $this = shift;
	return $this->Value( @_ );
}

sub numParams () {
	my $this = shift;
	return scalar(keys %{$$this{'config'}});
}

1;


