/*  
 *  src/org/thalia/bio/util/TabulatedReader.java
 * 
 *  $Author: veyrieras $, $Date: 2006-10-17 15:41:55 $, $Version$
 *
 *  MetaQTL : a Java package for QTL Meta-Analysis
 * 
 *  Copyright (C) 2003-2006  Jean-Baptiste Veyrieras, INRA, France.
 *
 *  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.
 *
 *  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.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * 
 */
package org.metaqtl.bio.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Hashtable;
import java.util.Set;

/**
 * This class can be used to parse tabulated file in which the first line
 * contains the label of the tabulated fields. To use this class is very simple :
 * <br>
 * <blockquote>
 * 
 * <pre>
 * 
 *  
 *   
 *    
 *        try {
 *     	  	TabulatedFileReader reader
 *     			= new TabulatedFileReader(new FileInputStream(&quot;mytabulatedfile.tab&quot;));
 *    
 *   
 *  
 * <br>
 * 
 *  
 *   
 *    
 *          ArrayList keys = tab.getKeys();
 *          ... do something with keys 
 *         	while (tab.hasNext()) {
 *            // new line
 *            String value = tab.get(&quot;key&quot;);
 *     		  ...	 
 *         	}
 *        } catch (IOException) {
 *     		...
 *     	  }
 *        ...
 *     
 *    
 *   
 *  
 * </pre>
 * 
 * </blockquote>
 * 
 * @author Jean-Baptiste
 */
public final class TabulatedReader {

	private String[] keyStrs;

    private Hashtable keys;

    private BufferedReader buffer;

    private String token = "\t";

    public TabulatedReader(Reader reader) throws IOException {
        buffer = new BufferedReader(reader);
        readKeysFromHeader(buffer.readLine());
    }

    public TabulatedReader(InputStream stream) throws IOException {
        InputStreamReader is = new InputStreamReader(stream);
        buffer = new BufferedReader(is);
        readKeysFromHeader(buffer.readLine());
    }

    private void readKeysFromHeader(String line) {
        keyStrs = line.split(token);
        keys = new Hashtable(keyStrs.length);
        for (int i = 0; i < keyStrs.length; i++) {
            keys.put(keyStrs[i], "");
        }
    }

    /**
     * Returns true if the given string is a key of the tabulated file. False
     * otherwise.
     * 
     * @param string
     * @return
     */
    public boolean containsKey(String string) {
        return keys.containsKey(string);
    }

    /**
     * Returns the number of keys, i.e the number of columns in the file.
     * 
     * @return
     */
    public int size() {
        return keys.size();
    }

    /**
     * Returns the set of the keys.
     * 
     * @return
     */
    public Set getKeys() {
        return keys.keySet();
    }

    /**
     * Returns true if there is still a line to read. False otherwise.
     * 
     * @return
     * @throws IOException
     */
    public boolean hasNext() throws IOException {
        String line;
        if ((line = buffer.readLine()) != null) {
            String[] values = line.split(token);
            for (int i = 0; i < values.length; i++) {
            	if (notEmptyField(values[i])) 
            		keys.put(keyStrs[i], values[i]);
            	else {
            		keys.put(keyStrs[i], "");
            	}
            }
            return true;
        } else {
            return false;
        }
    }

    /**
	 * @param string
	 * @return
	 */
	private boolean notEmptyField(String string) {
		if (string == null) return false;
		if (string.equals("")) return false;
		
		for(int i=0;i<string.length();i++)
			if (string.charAt(i)!=' ')
				return true;
		
		return false;
	}

	/**
     * Returns the value of the field which belongs to the given key.
     * 
     * @param key
     * @return
     */
    public String get(String key) {
        return (String) keys.get(key);
    }

    /**
     * Closes the stream.
     * 
     * @throws IOException
     */
    public void close() throws IOException {
        buffer.close();
    }

    /**
     * @return Returns the token.
     */
    public String getToken() {
        return token;
    }

    /**
     * @param token
     *            The token to set.
     */
    public void setToken(String token) {
        this.token = token;
    }

}