/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.commons.csv.writer;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * The CSVConfig is used to configure the CSV writer
 *
 * @author Martin van den Bemt
 * @version $Id: $
 */
public class CSVConfig {

    /** specifies if it is a fixed width csv file **/
    private boolean fixedWidth;
    /** list of fields **/
    private List fields;

    /** Do no do any filling **/
    public static final int FILLNONE = 0;
    /** Fill content the the left. Mainly usable together with fixedWidth **/
    public static final int FILLLEFT = 1;
    /** Fill content to the right. Mainly usable together with fixedWidth **/
    public static final int FILLRIGHT = 2;
    
    /** The fill pattern */
    private int fill;
    /** The fill char. Defaults to a space */
    private char fillChar = ' ';
    /** The seperator character. Defaults to , */
    private char delimiter = ',';
    /** Should we ignore the delimiter. Defaults to false */
    private boolean ignoreDelimiter = false;
    /** the value delimiter. Defaults to " */
    private char valueDelimiter = '"';
    /** Should we ignore the value delimiter. Defaults to true */
    private boolean ignoreValueDelimiter = true;
    /** Specifies if we want to use a field header */
    private boolean fieldHeader = false;
    /** Specifies if the end of the line needs to be trimmed */
    private boolean endTrimmed = false;
    /**
     * 
     */
    public CSVConfig() {
        super();
    }
    
    /**
     * @return if the CSV file is fixedWidth
     */
    public boolean isFixedWidth() {
        return fixedWidth;
    }
    
    /**
     * Specify if the CSV file is fixed width.
     * Defaults to false
     * @param fixedWidth the fixedwidth
     */
    public void setFixedWidth(boolean fixedWidth) {
        this.fixedWidth = fixedWidth;
    }
    
    public void addField(CSVField field) {
        if (fields == null) {
            fields = new ArrayList();
        }
        fields.add(field);
    }
    
    /**
     * Set the fields that should be used by the writer.
     * This will overwrite currently added fields completely!
     * @param csvFields the csvfields array. If null it will do nothing
     */
    public void setFields(CSVField[] csvFields) {
        if (csvFields == null) {
            return;
        }
        fields = new ArrayList(Arrays.asList(csvFields));
    }
    
    /**
     * Set the fields that should be used by the writer
     * @param csvField a collection with fields. If null it will do nothing
     */
    public void setFields(Collection csvField) {
        if (csvField == null) {
            return;
        }
        fields = new ArrayList(csvField);
    }

    /**
     * @return an array with the known fields (even if no fields are specified)
     */
    public CSVField[] getFields() {
        CSVField[] csvFields = new CSVField[0];
        if (fields != null) {
            return (CSVField[]) fields.toArray(csvFields);
        }
        return csvFields;
    }
    
    public CSVField getField(String name) {
        if (fields == null || name == null) {
            return null;
        }
        for(int i = 0; i < fields.size(); i++) {
            CSVField field = (CSVField) fields.get(i);
            if (name.equals(field.getName())) {
                return field;
            }
        }
        return null;
    }

    /**
     * @return the fill pattern.
     */
    public int getFill() {
        return fill;
    }

    /**
     * Set the fill pattern. Defaults to {@link #FILLNONE}
     * <br/>Other options are : {@link #FILLLEFT} and {@link #FILLRIGHT}
     * @param fill the fill pattern.
     */
    public void setFill(int fill) {
        this.fill = fill;
    }

    /**
     * 
     * @return the fillchar. Defaults to a space.
     */
    public char getFillChar() {
        return fillChar;
    }

    /**
     * Set the fill char
     * @param fillChar the fill char
     */
    public void setFillChar(char fillChar) {
        this.fillChar = fillChar;
    }

    /**
     * @return the delimeter used.
     */
    public char getDelimiter() {
        return delimiter;
    }

    /**
     * Set the delimiter to use
     * @param delimiter the delimiter character.
     */
    public void setDelimiter(char delimiter) {
        this.delimiter = delimiter;
    }

    /**
     * @return if the writer should ignore the delimiter character.
     */
    public boolean isDelimiterIgnored() {
        return ignoreDelimiter;
    }

    /**
     * Specify if the writer should ignore the delimiter. 
     * @param ignoreDelimiter defaults to false.
     */
    public void setIgnoreDelimiter(boolean ignoreDelimiter) {
        this.ignoreDelimiter = ignoreDelimiter;
    }

    /**
     * @return the value delimeter used. Defaults to "
     */
    public char getValueDelimiter() {
        return valueDelimiter;
    }

    /**
     * Set the value delimiter to use
     * @param valueDelimiter the value delimiter character.
     */
    public void setValueDelimiter(char valueDelimiter) {
        this.valueDelimiter = valueDelimiter;
    }

    /**
     * @return if the writer should ignore the value delimiter character.
     *         Defaults to true.
     */
    public boolean isValueDelimiterIgnored() {
        return ignoreValueDelimiter;
    }

    /**
     * Specify if the writer should ignore the value delimiter. 
     * @param ignoreValueDelimiter defaults to false.
     */
    public void setIgnoreValueDelimiter(boolean ignoreValueDelimiter) {
        this.ignoreValueDelimiter = ignoreValueDelimiter;
    }

    /**
     * @return if a field header is used. Defaults to false
     */
    public boolean isFieldHeader() {
        return fieldHeader;
    }
    /**
     * Specify if you want to use a field header.
     * @param fieldHeader true or false.
     */
    public void setFieldHeader(boolean fieldHeader) {
        this.fieldHeader = fieldHeader;
    }
    
    /**
     * TODO..
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        if (obj == null && !(obj instanceof CSVConfig)) {
            return false;
        }
        return super.equals(obj);
//        CSVConfig config = (CSVConfig) obj;
//        getFill() == config.getFill()
//        getFields().equals(config.getFields())
    }

    /**
     * Creates a config based on a stream. It tries to guess<br/>
     * NOTE : The stream will be closed.
     * @param inputStream the inputstream. 
     * @return the guessed config. 
     */
    public static CSVConfig guessConfig(InputStream inputStream) {
        return null;
    }

    /**
     * @return if the end of the line should be trimmed. Default is false.
     */
    public boolean isEndTrimmed() {
        return endTrimmed;
    }

    /**
     * Specify if the end of the line needs to be trimmed. Defaults to false.
     * @param endTrimmed
     */
    public void setEndTrimmed(boolean endTrimmed) {
        this.endTrimmed = endTrimmed;
    }

    
}
