# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/
#
# Copyright (C) 1999-2007 TWiki Contributors.
# All Rights Reserved. TWiki Contributors
# are listed in the AUTHORS file in the root of this distribution.
# NOTE: Please extend that file, not this notice.
#
# 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. For
# more details read LICENSE in the root of this distribution.
#
# 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.
#
# As per the GPL, removal of this notice is prohibited.

package TWiki::Data::DelimitedFile;

use Data::Dumper;
use Error qw( :try );
use FileHandle;

sub read {
    my (%settings) = @_;
    my $filename = $settings{filename};
    my $content = $settings{content};
    my $delimiter = $settings{delimiter} || "\t";
    my $rowstart = $settings{rowstart} || '';
    my $rowend = $settings{rowend} || "\n";
    my %data;
    
    local $/ = "\x0d\x0a";
    unless ($content) {
        my $fh   = new FileHandle($filename);
        local $/;
        $content = <$fh>;
        close $fh;
    }
    my @content = split $rowend, $content;
    
    my $headerRow  = shift @content;
    until ($headerRow =~ /\Q$delimiter\E/ ) {
       $headerRow  = shift @content;
    }

    $headerRow =~ s/\x0a*//g;
    $headerRow =~ s/\x0d*//g;
    
    @fieldNames = (split /\s*\Q$delimiter\E\s*/, $headerRow); 

    # Target:
    # $data{$rowNumber}{$fieldName} = $fieldValue
    
    # Remove any blank field definitions
    while (!defined($fieldNames[$#fieldNames])) {
        #     print "popping ".pop @fieldNames;
    }
    
    foreach my $rowNumber (0..$#content) {
        my $line = shift @content;
        $line =~ s/\x0a*//;
        $line =~ s/\n*//;
        # not \s - tab delimiter
        my @fieldValues = (split / *\Q$delimiter\E */, $line); 
        
        # print Dumper(\@fieldValues);
        
        foreach my $colNumber (0..$#fieldNames) { #use a counter as incr thru headers
            my $value = $fieldValues[$colNumber] || '';
            my $field = $fieldNames[$colNumber];
            
            $value =~ s/\s+$//;
            $value =~ s/\"//g; #Excel sometimes puts in quotes
            #      print "'$field ($colNumber)'='$value'\n";
            if ($field ne '') {
                $data{$rowNumber}{$field} = $value;
            }
        }
        #  print Dumper(\$data{$rowNumber});
        #  print $rowNumber. "\n";
    }
    
    # now the data is out, only pass valid field names.
    @fieldNames = grep /\S/, @fieldNames; 
    
    return (\@fieldNames, %data);
}

sub save {
    my (%settings) = @_;
    my $filename = $settings{filename} ||
      throw Error::Simple( 'Save: filename parameter is mandatory' );
    my $delimiter = $settings{delimiter} || "\t";
    my $rowstart = $settings{rowstart} || '';
    my $rowend = $settings{rowend} || "\n";
    my %data = %{$settings{data} ||
                   throw Error::Simple( 'Save: data parameter is mandatory' )};
    my @fieldNames = @{$settings{fieldNames} ||
                         throw Error::Simple( 'Save: fieldNames parameter is mandatory' )};

    my $fh = new FileHandle('> '.$filename) ||
      throw Error::Simple( 'Cannot write file: '.$! );
    my $headerRow = $rowstart.join($delimiter, @fieldNames).$rowend;
    print $fh $headerRow;
    
    foreach my $row (keys %data) {
        print "r=$row\n";
        print Dumper($data{$row});
        print $fh $rowstart;
        foreach my $field (@fieldNames) {
            my $value = $data{$row}{$field} || '';
            print $fh $value;
            print $fh $delimiter; # SMELL I know this adds an extra delimiter. I don't care.
        }
        print $fh $rowend;
    }
    close $fh;
}

1;
