/*
 * ManagementListBuilder.java
 *
 * Created on May 24, 2006, 3:55 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package usda.weru.util.diff.listbuilders;

import java.util.Vector;
import usda.weru.mcrew.ManageData;
import usda.weru.mcrew.OperationObject;
import usda.weru.mcrew.RowInfo;
import usda.weru.util.diff.*;

/**
 *
 * @author Joseph Levin
 */
public class ManagementListBuilder extends ObjectListBuilder {

    /**
     *
     */
    public static final int MATCH_DATE = 2;

    /**
     *
     */
    public static final int MATCH_OPERATION = 4;

    /**
     *
     */
    public static final int MATCH_CROP = 8;

    /**
     *
     */
    public static final int MATCH_OR = 16;

    private final int c_flags;

    /**
     *
     * @param flags
     */
    public ManagementListBuilder(int flags) {
        c_flags = flags;
    }

    /**
     *
     */
    public ManagementListBuilder() {
        c_flags = MATCH_DATE + MATCH_OPERATION;
    }

    /**
     *
     * @param engine
     * @param a
     * @param b
     * @return
     * @throws IncomparableObjectsException
     */
    @Override
    public DiffNode buildList(DiffEngine engine, Object a, Object b) throws IncomparableObjectsException {
        test(ManageData.class, a, b);
        return applyExtras(buildList(engine, (ManageData) a, (ManageData) b));
    }

    private Object[][] matchList(ManageData man, boolean matchOnDate, boolean matchOnOperation, boolean matchOnCrop) {
        int numMatchColumns = 0;
        if (matchOnDate) {
            numMatchColumns++;
        }
        if (matchOnOperation) {
            numMatchColumns++;
        }
        if (matchOnCrop) {
            numMatchColumns++;
        }

        Vector<RowInfo> rows = man.getRows();

        Object[][] temp = new Object[rows.size()][numMatchColumns + 1];

        for (int i = 0; i < rows.size(); i++) {
            RowInfo row = rows.get(i);
            temp[i][0] = row;

            int column = 1;
            if (matchOnDate) {
                temp[i][column] = row.getDate().toString();
                column++;
            }

            if (matchOnOperation) {
                temp[i][column] = ((OperationObject) row.getDataObject("operation")).getOperationName();
                column++;
            }

            if (matchOnCrop) {
                temp[i][column] = ((OperationObject) row.getDataObject("operation")).getCropName();
                column++;
            }
        }
        return temp;
    }

    private DiffNode buildList(DiffEngine engine, ManageData manA, ManageData manB) throws IncomparableObjectsException {
        DiffNode node = new DiffNode("Management File", manA, manB);

        if (manA != null) {
            node.setA(manA.manFile.getName());
        }
        if (manB != null) {
            node.setB(manB.manFile.getName());
        }

        if (manA == null || manB == null) {
            return node;
        }

        //Notes
        String notesA = manA.getWepsManFileNotes();
        String notesB = manB.getWepsManFileNotes();
        node.addChild("Notes", notesA, notesB);

        //Rotation Years
        Integer yearsA = manA.getRotationYears();
        Integer yearsB = manB.getRotationYears();
        node.addChild("Rotation Years", yearsA, yearsB);

        //Determine the matching flags
        boolean matchOnDate = DiffEngine.bitFlag(c_flags, MATCH_DATE);
        boolean matchOnOperation = DiffEngine.bitFlag(c_flags, MATCH_OPERATION);
        boolean matchOnCrop = DiffEngine.bitFlag(c_flags, MATCH_CROP);

        boolean matchOnOr = DiffEngine.bitFlag(c_flags, MATCH_OR);

        Object[][] listA = matchList(manA, matchOnDate, matchOnOperation, matchOnCrop);
        Object[][] listB = matchList(manB, matchOnDate, matchOnOperation, matchOnCrop);

        Object[] matches = match(listA, listB, matchOnOr, true);
        for (Object o : matches) {
            Object[] match = (Object[]) o;
            node.queueChild(match[0], match[1]);
        }

        return node;
    }

}
