package TWiki::Prefs::TopicPrefs;

=pod

---++ TopicPrefs Object

This Prefs-internal class is used to cache preferences read in from a single
topic.

---+++ sub $config->{TWiki}->{Prefs}->{TopicPrefs}->new ( $web, $topic )

Reads preferences from the specified topic into a new TopicPrefs object.

=cut

sub new
{
 
	my $dummy = shift;
	my $config = shift;
	unshift @_,$dummy ;

    my ($class, $theWeb, $theTopic) = @_;
    my $self = {};

	$self->{config}=$config;
    bless $self, $class;


    $self->{web} = $theWeb;
    $self->{topic} = $theTopic;

    $self->readPrefs();

    return $self;
}

=pod

---+++ sub $config->{TWiki}->{Prefs}->{TopicPrefs}->readPrefs () 

Rereads preferences from the topic, updating the TopicPrefs object.

=cut

sub readPrefs
{
    my $self = shift;
	my $config = $self->{config} ;

    
    my $theWeb = $self->{web};
    my $theTopic = $self->{topic};
    
    $self->{prefsHash} = {};
    $self->{prefsKeys} = [];
    $self->{prefsVals} = [];

    my $parser = TWiki::Prefs::Parser->new($config ) ;
    my( $meta, $text ) = $config->{TWiki}->{Store}->readTopic ( $theWeb, $theTopic, 1 );

    foreach my $setting ( @{ $parser->parseText($text) } ) {
	$self->insertPrefsValue( $setting->[0], $setting->[1] );
    }
    foreach my $setting ( @{ $parser->parseMeta($meta) } ) {
	$self->insertPrefsValue( $setting->[0], $setting->[1] );
    }

}

=pod

---+++ sub $config->{TWiki}->{Prefs}->{TopicPrefs}->insertPrefsValue ( $key, $value )

Adds a key-value pair to the TopicPrefs object.

=cut

sub insertPrefsValue {
    my ( $self, $theKey, $theValue ) = @_;
	my $config = $self->{config} ;


    return if exists $self->{finalHash}{$theKey}; # key is final, may not be overridden

    $theValue =~ s/\t/ /g;                 # replace TAB by space
    $theValue =~ s/([^\\])\\n/$1\n/g;      # replace \n by new line
    $theValue =~ s/([^\\])\\\\n/$1\\n/g;   # replace \\n by \n
    $theValue =~ s/`//g;                   # filter out dangerous chars

    if (exists $self->{prefsHash}{$theKey}) {
	# key exists, need to deal with existing preference
	my $valueRef = $self->{prefsHash}{$theKey};
	if ($theKey eq $config->{TWiki}->{Prefs}->{finalPrefsName}) {
	    $$valueRef .= ", $theValue"; # merge final preferences lists
	} else {
	    $$valueRef = $theValue; # simply replace all other values
	}
    } else {
	# new preference setting, no previous value
	my $newIndex = scalar @{ $self->{prefsKeys} };
	$self->{prefsKeys}[$newIndex] = $theKey;
	$self->{prefsVals}[$newIndex] = $theValue;
	$self->{prefsHash}{$theKey} = \$self->{prefsVals}[$newIndex];
    }
}

=pod

---+++ sub $config->{TWiki}->{Prefs}->{TopicPrefs}->getTopicPrefs () 

Returns a list  =( \@keys, \@values )= listing the preference settings in the
current topic.  Changing entries in the =@values= array will change cached
preference settings.  Changing entries in the =@keys= array will result in
unspecified behavior -- don't do that.

=cut

sub getTopicPrefs
{
    my $self = shift;
	my $config = $self->{config} ;

    return ($self->{prefsKeys}, $self->{prefsVals}) if wantarray;
    return [$self->{prefsKeys}, $self->{prefsVals}]; # return array ref in scalar context
}


# =============================================================================

1;
