package com.quui.tm2.agents.features;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.quui.tm2.Agent;
import com.quui.tm2.Annotation;
import com.quui.tm2.Annotations;
import com.quui.tm2.ImmutableAnnotation;
import com.quui.tm2.Model;
import com.quui.tm2.agents.features.generator.FeatureGenerator;
import com.quui.tm2.types.FeatureVector;

/**
 * @author fsteeg
 *
 */
public class Features implements Model<String, String>, Agent<String, FeatureVector> {

    private FeatureGenerator generator;
    private HashMap<Annotation<String>, Annotation<String>> relevantData;
    private int context;

    @Override
    public String toString() {
        return String.format("%s using generator %s, context %s", getClass().getSimpleName(),
                generator, context);
    }

    public Features(List<String> vocabulary, String type, int context) {
        this.context = context;
        generator = new FeatureGenerator(vocabulary, type, context);
    }

    public Features() {}

    public Features(String s) {}

    public List<Annotation<FeatureVector>> process(List<Annotation<String>> input) {
        List<String> strings = Annotations.toValues(new ArrayList<Annotation<String>>(relevantData
                .values()));
        List<Annotation<FeatureVector>> result = new ArrayList<Annotation<FeatureVector>>();
        for (int i = 0; i < input.size(); i++) {
            FeatureVector vector = new FeatureVector(generator.getFeatures(i, strings, context * 2), 
            		input.get(i).getValue(), null);
            Annotation<FeatureVector> annotation = ImmutableAnnotation.getInstance(getClass(),
                    vector, input.get(i).getStart(), input.get(i).getEnd());
            result.add(annotation);
        }
        return result;
    }

    /* @Override */public Model<String, String> train(List<Annotation<String>> data,
            List<Annotation<String>> info) {
        relevantData = new HashMap<Annotation<String>, Annotation<String>>();
        for (Annotation<String> d : data) {
            for (Annotation<String> i : info) {
                if (Annotations.fullOverlap(d, i)) {
                    relevantData.put(i, d);
                }
            }
        }
        return this;
    }
}
