package tools;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;

public class Field implements Comparable<Field> {
	public static final String DEFAULT_NAME						=	"DEFAULT_NAME";
	public static final String DEFAULT_PATH						=	"";
	public static final String DEFAULT_TYPE						=	"DEFAULT_TYPE";
	public static final double DEFAULT_IMPORTANCE				=	0.0;
	public static final double DEFAULT_OPTIMIZATION_THRESHOLD	=	0.0;

	public Configuration configuration ;
	public String name;
	public String path;
	public String type;
	public double importance;
	public double optimization_threshold ;
	public int algorithm;
	public boolean sort;
	public Collection<Field> content ;
	public boolean isComplex ;
		
	public Field(Configuration configuration) {
		this.configuration = configuration ;
		this.name = DEFAULT_NAME;
		this.path = DEFAULT_PATH;
		this.type = DEFAULT_TYPE;
		this.importance = DEFAULT_IMPORTANCE;
		this.optimization_threshold = DEFAULT_OPTIMIZATION_THRESHOLD ;
		this.algorithm = CompareUtilities.DEFAULT_DISTANCE_REFERENCE;
		this.sort = false;
		this.content = new ArrayList<Field>() ;
		this.isComplex = false ;
	}

	public Field(Configuration configuration, String name) {
		this(configuration);
		this.name = name;
		configuration.putField(name, this) ;
	}

	public Field(Configuration configuration, String name, String path) {
		this(configuration, name);
		this.path = path;
	}

	public Field(Configuration configuration, String name, String path, String type) {
		this(configuration, name, path);
		this.type = type;
	}

	public Field(Configuration configuration, String name, String path, String type, double importance) {
		this(configuration, name, path, type);
		this.importance = importance;
	}

	public Field(Configuration configuration, String name, String path, String type, double importanceLevel,
			int algorithm) {
		this(configuration, name, path, type, importanceLevel);
		this.algorithm = algorithm;
	}
	
	public String toString() {
		String res = "" ;
		if (isComplex()) {
			res += name + "\n" ;
			for (Iterator<Field> itField = content.iterator() ; itField.hasNext() ; ) {
				res += "\t" + itField.next() + "\n" ;
			}
		}
		else {
			res += name + ":" ; 
		}
		return res ;
	}
	
	public void setComplex() {
		this.isComplex = true ;
	}
	public boolean isComplex() {
		return this.isComplex ;
	}
	public boolean isSortable() {
		return sort;
	}

	public void setSortable() {
		this.sort = true;
	}
	public String getName() {
		return this.name ;
	}
	public void setName(String name) {
		this.name = name ;
	}
	public String getPath() {
		return this.path ;
	}
	public void setPath(String path) {
		this.path = path ;
	}
	public String getType() {
		return this.type ;
	}
	public void setType(String type) {
		this.type = type ;
	}
	public double getImportance() {
		return this.importance ;
	}
	public void setImportance(double importance) {
		this.importance = importance ;
	}
	public void setOptimizationThreshold(double optimization_threshold) {
		this.optimization_threshold = optimization_threshold ;
	}
	public double getOptimizationThreshold() {
		return this.optimization_threshold ;
	}
	public void setValue(String field, Object value) {		
			try {
				if (field.equals("algorithm")) {
					StringTokenizer st = new StringTokenizer((String) value, " ") ;					
					while (st.hasMoreTokens()) {												
						this.algorithm |= CompareUtilities.class.getField(st.nextToken()).getInt(null) ;
					} 
				}
				else 
					if (field.equals("importance")) {
						this.importance = Double.parseDouble((String) value) ;
					}
					else {
						if (field.equals("sort")) {
							this.sort = value.equals("true") ;
						}
						else {
							if (field.equals("type")) {
								if (value.equals("complex")) {
									setComplex() ;
								}
							}
							else {
								if (field.equals("content")) {									
									this.content.add((Field) value) ;
								}
								else 
									if (field.equals("optimization_threshold")) {									
										setOptimizationThreshold(Double.parseDouble((String) value)) ;
									}
									else {
										this.getClass().getField(field).set(this, value) ;
									}
							}
						}
					}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			}

	}

	@Override
	public int compareTo(Field field) {
		if (importance >= field.importance) {
			return -1;
		}
		return 1;
	}

	public Field get(String fieldName) {
		if (this.getName().equals(fieldName)) {
			return this ;
		}
		else {
			for (Iterator<Field> itF = content.iterator() ; itF.hasNext() ; ) {
				Field field = itF.next().get(fieldName) ;
				if (field != null) {
					return field ;
				}
			}
		}
		return null;
	}

}
