/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package usda.weru.mcrew;

import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;

/**
 * Classifies operations into planting, harvest or other 
 * 
 * See http://wind.weru.ksu.edu/wiki/Operation_Classification
 * 
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public enum OperationClassification {

	/**
	 *
	 */
	Planting {

        @Override
        public boolean is(OperationObject op) {
            return hasProcess(op.getAllActions(), 51);
        }
    },

	/**
	 *
	 */
	Harvest {

        @Override
        public boolean is(OperationObject op) {
            if (hasAnyProcess(op.getAllActions(), 42, 43, 47, 48, 62)) {
                //must also have selpool not set to 4
                for (Action action : op.getAllActions()) {
                    if (isHarvestReported(action) && isNotResidue(action)) {
                        return true;
                    }
                }
            }
            return false;
        }
    },

	/**
	 *
	 */
	Other {

        @Override
        public boolean is(OperationObject op) {
            //can not be any other classification
            for (OperationClassification c : OperationClassification.values()){
                if(c == Other){
                    continue;
                }
                else if (c.is(op)){
                    return false;
                }
            }
            
            return true;
        }
    };

	/**
	 *
	 * @param op
	 * @return
	 */
	public boolean is(OperationObject op) {
        throw new UnsupportedOperationException();
    }

	/**
	 *
	 * @param op
	 * @return
	 */
	public static EnumSet<OperationClassification> classify(OperationObject op) {

        List <OperationClassification> result = new LinkedList<OperationClassification>();
        
        for (OperationClassification c : OperationClassification.values()){                
                if (c.is(op)){
                    result.add(c);
                }
            }
        
        return EnumSet.copyOf(result);
    }

    private static boolean isNotResidue(Action action) {
        Parameter selpool = action.getParameter("selpool");
        if (selpool != null) {
            Object value = selpool.getValue();
            if (value != null && Integer.valueOf(value.toString().trim()).equals(4)) {
                return false;
            }
        }
        return true;
    }

    private static boolean isHarvestReported(Action action) {
        Parameter harv_report_flg = action.getParameter("harv_report_flg");
        if (harv_report_flg != null) {
            Object value = harv_report_flg.getValue();
            if (value != null && Integer.valueOf(value.toString().trim()).equals(1)) {
                return true;
            }
        }
        return false;
    }

    private static boolean hasAnyProcess(Collection<Action> actions, int... ids) {
        for (int id : ids) {
            if (hasProcess(actions, id)) {
                return true;
            }
        }
        return false;
    }

//    private static boolean hasAllProcess(Collection<Action> actions, int... ids){
//        for(int id : ids){
//            if(!hasProcess(actions, id)){
//                return false;
//            }
//        }
//        return true;
//    }
    private static boolean hasProcess(Collection<Action> actions, int id) {
        for (Action action : actions) {
            if (action.getIdentity().equals(new Identity(id, "P"))) {
                return true;
            }
        }
        return false;
    }
}
