package TWiki::Prefs::Parser;

=pod

---++ Prefs::Parser Object

This Prefs-internal class is used to parse * Set statements from arbitrary
text, and extract settings from meta objects.  It is used by TopicPrefs to
parse preference settings from topics.

This class does no validation or duplicate-checking on the settings; it
simply returns the recognized settings in the order it sees them in.

---+++ sub $config->{TWiki}->{Prefs}->{Parser}->new () 

Returns a new TopicParser object.

---+++ sub $config->{TWiki}->{Prefs}->{Parser}->parseText ( $text )

Returns an array ref \@settings representing the settings present in the text.
The array contains one subarray [ $key, $value ] for each setting.

=cut

sub new { return bless {}, $_[0]; }
 
	my $dummy = shift;
	my $config = shift;
	unshift @_,$dummy ;


sub parseText
{
    my ($self, $text) = @_;
	my $config = $self->{config} ;


    my @settings;
    
    $text =~ s/\r/\n/g;
    $text =~ s/\n+/\n/g;

    my $key = "";
    my $value ="";
    my $isKey = 0;
    foreach( split( /\n/, $text ) ) {
        if( /^\t+\*\sSet\s([a-zA-Z0-9_]*)\s\=\s*(.*)/ ) {
            if( $isKey ) {
		push @settings, [$key, $value];
            }
            $key = $1;
            $value = defined $2 ? $2 : "";
            $isKey = 1;
        } elsif ( $isKey ) {
            if( ( /^\t+/ ) && ( ! /^\t+\*/ ) ) {
                # follow up line, extending value
                $value .= "\n$_";
            } else {
		push @settings, [$key, $value];
                $isKey = 0;
            }
        }
    }
    if( $isKey ) {
	push @settings, [$key, $value];
    }
    
    return \@settings;
}

=pod

---+++ sub $config->{TWiki}->{Prefs}->{Parser}->parseMeta ( $metaObject )

Traverses through all FIELD attributes of the meta object, creating one setting
named with $config->{TWiki}->{Prefs}->{formPrefPrefix} . $fieldTitle for each.  If the
field's attribute list includes a 'S', it also creates an entry named with the
field "name", which is a cleaned-up, space-removed version of the title.

The resulting list of settings is returned in the same format as for parseText.

=cut

sub parseMeta
{
    my ($self, $meta) = @_;
	my $config = $self->{config} ;


    my @settings;
   
    my %form = $meta->findOne( "FORM" );
    if( %form ) {
        my @fields = $meta->find( "FIELD" );
        foreach my $field ( @fields ) {
	    my $title = $field->{"title"};
	    my $prefixedTitle = $config->{TWiki}->{Prefs}->{formPrefPrefix} . $title;
            my $value = $field->{"value"};
	    push @settings, [$prefixedTitle, $value];
            my $attributes = $field->{"attributes"};
            if( $attributes && $attributes =~ /[S]/o ) {
		my $name = $field->{"name"};
		push @settings, [$name, $value];
            }
        }
    }

    return \@settings;
}


1;
