/*
 * Created on Nov 24, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package gov.nasa.jsc.plum.DBManager;

import java.util.Iterator;
import java.util.TreeMap;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author randrews
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class Table implements Cloneable, Serializable{
    private TreeMap fields;
    private String name;
    
    /**
     * Makes a new table with no name
     */
    public Table() {
        super();
        name="";
        fields=new TreeMap();
    }

    public Object clone() throws CloneNotSupportedException{
        return super.clone();
    }
    
    /**
     * @param name The name of the table
     */
    public Table(String name) {
        super();
        this.name = name;
        fields=new TreeMap();
    }
    
    
    /**
     * @param name name of the table
     * @param conn connection to the database
     */
    public Table(String name,Connection conn){
        super();
        this.name=name;
        fields=new TreeMap();
        try {
            ResultSet res = conn.createStatement().executeQuery("describe "+name);
            while(res.next())
            {
                Field field=new Field(res.getString("Field"),
                        res.getString("Type"),
                        !(res.getString("Null").equals("")),
                        res.getString("Key").equals("PRI"),
                        res.getString("Key").equals("UNI"),
                        res.getString("Default"),
                        res.getString("Extra")
                );
                addField(field);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
    }
    
    /**
     * @return the value of the primary key field.
     */
    public Field getIndex(){
        Iterator i=fields.keySet().iterator();
        while(i.hasNext())
        {
            Field f=(Field) fields.get(i.next());
            if(f.getKey())return f;
        }
        return null;
    }
    
    /**
     * @return Returns the name.
     */
    public String getName() {
        return name;
    }
    /**
     * @param name The name to set.
     */
    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * @return A query that will create this table
     */
    public String toString(){
        if(name=="")return "";
        String str ="create table "+name+" (";

        boolean comma=false;

        Iterator i=fields.keySet().iterator();

        while(i.hasNext()){
            Field f=(Field) fields.get(i.next());
            
            if(comma)str+=", ";
            else comma=true;
            
            str+=f.toString();
        }

        return str+")";
    }
    
    /**
     * @return an iterator over the fields in the table.
     */
    public Iterator getIterator(){
        return fields.keySet().iterator();
    }
    
    /**
     * Gets a field.
     * @param name the name of the field to get
     * @return the field, or null
     */
    public Field getField(String name){
        return (Field) fields.get(name);
    }

    /**
     * Adds a field to the table
     * @param field the field to add
     * @return true iff the field was added. It can only be added if a field with the same name isn't already there.
     */
    public boolean addField(Field field){
        if(getField(field.getName())!=null)
            return false;
        fields.put(field.getName(),field);
        return true;
    }
    
    /**
     * Adds a field, replacing one with the same name if it was already there
     * @param field The field to add
     */
    public void forceAddField(Field field){
        fields.put(field.getName(),field);
    }
    
    /**
     * Deletes a field from the table
     * @param name the name of the field to delete
     * @return true iff the field was found and deleted.
     */
    public boolean deleteField(String name){
        if(!fields.containsKey(name))
            return false;
        fields.remove(name);
        return true;
    }


    /**
     * @return the number of fields in the table.
     */
    public int getNumFields() {
        return fields.size();
    }
    
}
