package usda.weru.weps.location;

import java.util.EnumSet;
import usda.weru.weps.RunFileBean;
import usda.weru.weps.location.chooser.StationChooser;
import usda.weru.weps.location.mode.FileHandler;
import usda.weru.weps.location.mode.GISHandler;
import usda.weru.weps.location.mode.ChoiceHandler;
import usda.weru.weps.location.mode.InterpolatedHandler;
import usda.weru.weps.location.mode.NRCSHandler;
import usda.weru.weps.location.mode.NearestHandler;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public enum StationMode implements StationModeController {

    /**
     * The station data is generated from historical values.  The user will specify
     * the station to use, typically from a combo box.
     */
    Choice(new ChoiceHandler()),
    /**
     * The nearest station is used.  No choice is given to the user.
     */
    Nearest(new NearestHandler()),
    /**
     * The station data is provided by a file.  User will specify the file.
     */
    File(new FileHandler()),
    /**
     * The station data is generated either by historical values or interpolation
     * based on the GIS polygon for the simulation lat/long.
     */
    GIS(new GISHandler()),
    /**
     * The station data is generated by interpolating a virtual station based on
     * the simulation lat/long.
     */
    Interpolated(new InterpolatedHandler()),
    /**
     * Explicit NRCS mode to make it easier to update any logic that NRCS/ARS
     * wants without affecting the other modes used by researchers.
     */
    NRCS(new NRCSHandler());
    private final StationModeController c_handler;

    public static StationMode[] parseStationModes(String modes) {
        if (modes == null || modes.trim().length() == 0) {
            return new StationMode[0];
        }
        EnumSet<StationMode> c_allowedModes = null;
        String[] parts = modes.split(",");
        for (String part : parts) {
            StationMode mode = StationMode.parse(part.trim());
            if (mode != null) {
                if (c_allowedModes == null) {
                    c_allowedModes = EnumSet.of(mode);
                } else {
                    c_allowedModes.add(mode);
                }
            }
        }

        return c_allowedModes.toArray(new StationMode[c_allowedModes.size()]);
    }
    
    
    StationMode(StationModeController handler) {
        c_handler = handler;
    }

    @Override
    public String getName() {
        return c_handler.getName();
    }

    @Override
    @Deprecated
    public int getId() {
        return c_handler.getId();
    }

    @Override
    public void installModel(RunFileBean bean, RunFileBean.StationType type) {
        c_handler.installModel(bean, type);
    }

    @Override
    public void uninstallModel(RunFileBean bean, RunFileBean.StationType type) {
        c_handler.uninstallModel(bean, type);
    }

    @Override
    public void installView(StationChooser chooser) {
        c_handler.installView(chooser);
    }

    @Override
    public void uninstallView(StationChooser chooser) {
        c_handler.uninstallView(chooser);
    }

    @Override
    public String getDisplayName() {
        return c_handler.getDisplayName();
    }

    /**
     * Search order for the StationMode:
     * 1. name
     * 2. enum value
     * 3. id (deprecated and will be removed)
     * @param text
     * @return matching StationMode or null.
     */
    public static StationMode parse(String text) {
        //try by name
        for (StationMode mode : StationMode.values()) {
            if (mode.getName().equalsIgnoreCase(text)) {
                return mode;
            }
        }

        //try by enum name
        try {
            return StationMode.valueOf(text);
        } catch (Exception e) {
            //do nothing
        }

        //try by id        
        try {
            int id = Integer.valueOf(text.trim());
            for (StationMode mode : StationMode.values()) {
                if (mode.getId() == id) {
                    return mode;
                }
            }
        } catch (NumberFormatException e) {
            //do nothing
        }
        return null;
    }

}
