package net.sf.flatpack.writer;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.flatpack.structure.ColumnMetaData;
import net.sf.flatpack.util.FPConstants;

/**
 * 
 * @author Dirk Holmes and Holger Holger Hoffstatte
 */
public class DelimiterWriter extends AbstractWriter {
    private char delimiter;
    private char qualifier;
    private List columnTitles = null;
    private boolean columnTitlesWritten = false;

    protected DelimiterWriter(final Map columnMapping, final java.io.Writer output, final char delimiter, final char qualifier) throws IOException {
        super(output);
        this.delimiter = delimiter;
        this.qualifier = qualifier;

        columnTitles = new ArrayList();
        final List columns = (List) columnMapping.get(FPConstants.DETAIL_ID);
        final Iterator columnIter = columns.iterator();
        while (columnIter.hasNext()) {
            final ColumnMetaData element = (ColumnMetaData) columnIter.next();
            columnTitles.add(element.getColName());
        }
        // write the column headers
        this.nextRecord();
    }

    protected void writeWithDelimiter(final Object value) throws IOException {
        this.write(value);
        this.write(delimiter);
    }

    protected void write(final Object value) throws IOException {
        String stringValue = "";

        if (value != null) {
            // TODO DO: format the value
            stringValue = value.toString();
        }

        final boolean needsQuoting = (stringValue.indexOf(delimiter) != -1);

        if (needsQuoting) {
            super.write(qualifier);
        }

        super.write(stringValue);

        if (needsQuoting) {
            super.write(qualifier);
        }
    }

    protected void addColumnTitle(final String string) {
        if (string == null) {
            throw new IllegalArgumentException("column title may not be null");
        }
        columnTitles.add(string);
    }

    protected void writeColumnTitles() throws IOException {
        final Iterator titleIter = columnTitles.iterator();
        while (titleIter.hasNext()) {
            final String title = (String) titleIter.next();

            if (titleIter.hasNext()) {
                this.writeWithDelimiter(title);
            } else {
                this.write(title);
            }
        }
    }

    protected void writeRow() throws IOException {
        final Iterator titlesIter = columnTitles.iterator();
        while (titlesIter.hasNext()) {
            final String columnTitle = (String) titlesIter.next();
            if (titlesIter.hasNext()) {
                this.writeWithDelimiter(this.getRowMap().get(columnTitle));
            } else {
                this.write(this.getRowMap().get(columnTitle));
            }
        }
    }

    public final void nextRecord() throws IOException {
        if (!columnTitlesWritten) {
            this.writeColumnTitles();
            columnTitlesWritten = true;
        } else {
            this.writeRow();
        }

        super.nextRecord();
    }

    public void printFooter() {
        // TODO DO: implement footer handling
    }

    public void printHeader() {
        // TODO DO: implement header handling
    }

    protected boolean validateColumnTitle(final String columnTitle) {
        return columnTitles.contains(columnTitle);
    }
}

@@ -2636,32 +2636,75 @@
 lesIter.next();%0A
+            if (getRowMap() != null) %7B%0A    
             if (
@@ -2735,37 +2735,36 @@
                 
+    
-this.
 writeWithDelimit
@@ -2766,21 +2766,16 @@
 limiter(
-this.
 getRowMa
@@ -2801,32 +2801,36 @@
 ));%0A            
+  
+  
 %7D else %7B%0A       
@@ -2842,24 +2842,18 @@
     
-this.
+    
 write(
-this.
 getR
@@ -2871,32 +2871,50 @@
 (columnTitle));%0A
+                %7D%0A
             %7D%0A  

Fix an NPE