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

import de.schlichtherle.truezip.file.TFile;
import java.awt.Container;
import java.awt.Component;
import java.io.IOException;
import java.io.InputStream;
import java.io.UTFDataFormatException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import usda.weru.erosion.Erosion;

/**
 *
 * @author wjr
 */
public class FormValidator {

    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        usda.weru.erosion.Erosion ero = new usda.weru.erosion.Erosion();
        FormValidator fv = new FormValidator(Erosion.class.getResourceAsStream("SWEEPLimits.xml"));
        fv.validateForm(ero);
        ero.setVisible(true);
    }

    /**
     * Creates a validator object for a specified form and limits file.
     * The limits file is xml and contains upper and lower bounds for a 
     * property. The property is bound to a JTF or other swing object by
     * placing the property into the object's name field.
     * @param valFile
     * @throws java.io.IOException
     */
    public FormValidator(TFile valFile) throws IOException {
        readXmlLimits(new de.schlichtherle.truezip.file.TFileInputStream(valFile));
    }

    /**
     *
     * @param in
     * @throws IOException
     */
    public FormValidator(InputStream in) throws IOException {
        readXmlLimits(in);
    }

//    int indentCnt = 0;
    private boolean validateContainer(Container base) {
        Component[] children = base.getComponents();
//        for (int idx = 0; idx < indentCnt; idx++) System.out.print("  ");
//        System.out.println(base.getClass() + " " + base.getName());
//        indentCnt += 2;
        String name = base.getName();
        if (name != null) {
            LimitsEntry le = HT_limits.get(name);
//            System.out.println(name + ((le != null) ? " found" : " not found"));
            if (le != null) {
                if (base.isEnabled()) {
                    if (base instanceof javax.swing.JTextField) {
                        String val = ((javax.swing.JTextField) base).getText();
                        boolean tmpFlg = le.inRange(val);
                        if (!tmpFlg) {
                            valFlg = false;
                        }    // can't run with invalid data
                        base.setBackground(tmpFlg ? java.awt.Color.WHITE : java.awt.Color.RED);
                    }
                } else {
                    base.setBackground(java.awt.Color.WHITE);

                }
            }
        }
        for (Component comp : children) {
            if (comp instanceof Container) {
                validateContainer((Container) comp);
            }
        }
//        indentCnt -= 2;
        return true;
    }

    private boolean valFlg;

    /**
     *
     * @param base
     * @return
     */
    public boolean validateForm(Container base) {
        valFlg = true;
        validateContainer(base);
        return valFlg;
    }

    static class LimitsEntry {

//        String name;
        String minValStr;
        String maxValStr;
        String altValStr;
//        String units;
        double minVal = Double.NaN;
        double maxVal = Double.NaN;
        double altVal = Double.NaN;

        LimitsEntry(Element name, Element minVal, Element maxVal, Element units,
                Element altVal) {
            if (name != null) {
//                this.name = name.getText();
            }
            if (minVal != null) {
                minValStr = minVal.getText();
                this.minVal = Double.parseDouble(minValStr);
            }
            if (maxVal != null) {
                maxValStr = maxVal.getText();
                this.maxVal = Double.parseDouble(maxValStr);
            }
            if (units != null) {
//                this.units = units.getText();
            }
            if (altVal != null) {
                altValStr = altVal.getText();
                this.altVal = Double.parseDouble(altValStr);
            }
        }

        boolean inRange(String inpStr) {
            if ("".equals(inpStr.trim())) {
                return false;
            }
            return inRange(Double.parseDouble(inpStr));
        }

        boolean inRange(double inpVal) {
            if (!Double.isNaN(altVal) && inpVal == altVal) {
                return true;
            }
            if (!Double.isNaN(minVal) && inpVal < minVal) {
                return false;
            }
            if (!Double.isNaN(maxVal) && inpVal > maxVal) {
                return false;
            }
            return true;
        }
    }
    java.util.Hashtable<String, LimitsEntry> HT_limits = new java.util.Hashtable<String, LimitsEntry>();

    private boolean readXmlLimits(InputStream in) {
        try {
//            System.out.println("DS_rXSL:");
            //if (!file.exists()) return false;
            SAXBuilder builder = new SAXBuilder();
            Document document = builder.build(in);
//                rangeLimits = document;
            Element root = document.getRootElement();
            for (Object o : root.getChildren("field")) {
                Element element = (Element) o;
                Element name = element.getChild("name");
                Element minValue = element.getChild("minimum");
                Element maxValue = element.getChild("maximum");
                Element units = element.getChild("units");
                Element altValue = element.getChild("alternative");
                LimitsEntry le = new LimitsEntry(name, minValue, maxValue, units, altValue);
                if (name != null) {
                    HT_limits.put(name.getText(), le);
//                    System.out.print(name.getText() + " ");
//                    System.out.print(((minValue != null) ? minValue.getText() : "missing") + " ");
//                    System.out.print(((maxValue != null) ? maxValue.getText() : "missing") + " ");
//                    System.out.println(";");
//                        c_elementTable.put(name.getText(), element);
//                        //ht.put(name.getText(), valueText);
//                        setData(name.getText(), valueText);
                }
            }
//                fireAll();
            return true;
        } catch (UTFDataFormatException udfe) {
//                c_log.logMessage(WepsMessage.ErrorMessage("Unable to load XML configuration file."));
//                c_log.logMessage(new WepsMessage(udfe));
            return false;
        } catch (JDOMException jde) {
//                if (jde.getMessage().indexOf("Content is not allowed in prolog") > 0) return false;//Assume this is not an xml file.
//                
//                c_log.logMessage(WepsMessage.ErrorMessage("Unable to load XML configuration file."));
//                c_log.logMessage(new WepsMessage(jde));
            return false;
        } catch (IOException ioe) {
//                c_log.logMessage(WepsMessage.ErrorMessage("Unable to load XML configuration file."));
//                c_log.logMessage(new WepsMessage(ioe));
            return false;
        }
    }
}
