/*
 * DispFileParser.java
 *
 * Created on October 6, 2004, 8:33 AM
 */
package ex1;

import de.schlichtherle.truezip.file.TFile;
import java.io.IOException;
import java.util.*;
import javax.swing.*;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;

/**
 * Loads the crop display xml file to get parameter grouping.
 *
 * @author jrf
 */
public class DispFileParser extends DefaultHandler {

    private boolean grabName;
    private boolean grabcat;
    private final DefnFileParser pNames;
    private String name;
    private String catName;
    private HashMap<ParamDef, String> catparms;
    private ArrayList<HashMap<ParamDef, String>> categories;
    private ArrayList<String> categoryNames;

    /**
     * Creates a new instance of Class
     *
     * @param listing
     * @param isCrop
     * @param dispFile
     */
    public DispFileParser(DefnFileParser listing, String dispFile, boolean isCrop) {
        pNames = listing;
        SAXParserFactory factory;
        SAXParser saxParser;

        grabName = grabcat = false;

        categories = new ArrayList<HashMap<ParamDef, String>>();
        categoryNames = new ArrayList<String>();

        TFile wf = new TFile(dispFile);

        if (wf.exists() == false) {
            JOptionPane.showMessageDialog(null, "Error: File not found",
                    wf.getAbsolutePath(), JOptionPane.INFORMATION_MESSAGE);

        }
        factory = SAXParserFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setXIncludeAware(true);            

        try {
            // Parse the input
            saxParser = factory.newSAXParser();
            saxParser.parse(wf, this);

        } catch (IOException | ParserConfigurationException | SAXException t) {
            t.printStackTrace();
        }
    }

    /**
     * Part of SAX XML processing... Called automatically by SAX parser
     *
     * @throws org.xml.sax.SAXException
     */
    @Override
    public void startDocument()
            throws SAXException {

    }

    /**
     * Part of SAX XML processing... Called automatically by SAX parser
     *
     * @throws org.xml.sax.SAXException
     */
    @Override
    public void endDocument()
            throws SAXException {

    }

    /**
     *
     * Part of SAX processing that gets called at the when an opening xml tag is encountered. We
     * will filter out the ones we are interested and set the flags for what the character function
     * should grab and where it will be stored.
     *
     * @param namespaceURI
     * @param attrs
     * @param lName
     * @param qName
     * @throws org.xml.sax.SAXException
     */
    @Override
    public void startElement(String namespaceURI,
            String lName, // local name
            String qName, // qualified name
            Attributes attrs)
            throws SAXException {
        String eName = lName; // element name
        if ("".equals(eName)) {
            eName = qName;
        }

        switch (eName) {
            case "paramname":
                grabName = true;
                name = "";
                break;
            case "categoryname":
                grabcat = true;
                catName = "";
                catparms = new HashMap<ParamDef, String>();
                break;
        }
    }

    /**
     * Part of SAX processing that gets called when an ending xml tag is encountered.
     *
     * @param namespaceURI
     * @param qName
     * @param sName
     * @throws org.xml.sax.SAXException
     */
    @Override
    public void endElement(String namespaceURI,
            String sName, // simple name
            String qName // qualified name
    )
            throws SAXException {
        String eName = sName; // element name
        if ("".equals(eName)) {
            eName = qName;
        }

        switch (eName) {
            case "paramname":
                name = name.trim();
                grabName = false;
                ParamDef p = pNames.getParamDef(name);
                if (p != null) {
                    catparms.put(p, name);
                } else {
                    // could not find
                    ErrorSink.add("Could not find parameter definition for " + name + " seen in crop display file.");
                }
                break;
            case "categoryname":
                catName = catName.trim();
                grabcat = false;
                categoryNames.add(catName);
                categories.add(catparms);
                break;
        }

    }

    /**
     * Part of SAX processing that gets called to get the contents inside an xml tag. The calls to
     * get the contents may not come in one chunk so we need to accumulate character strings until
     * the ending tag then the string can be assumed to be complete.
     *
     * @param buf
     * @param len
     * @param offset
     * @throws org.xml.sax.SAXException
     */
    @Override
    public void characters(char buf[], int offset, int len)
            throws SAXException {
        String s = new String(buf, offset, len);
        if (grabName) {
            name = name.concat(s);
        } else if (grabcat) {
            catName = catName.concat(s);
        }
    }

    /**
     *
     * @return
     */
    public int getCategoryCount() {
        return categories.size();
    }

    /**
     *
     * @param inx
     * @return
     */
    public String getCategoryName(int inx) {
        if (inx < categoryNames.size()) {
            return categoryNames.get(inx);
        }
        return null;
    }

    /**
     *
     * @param p
     * @param cat
     * @return
     */
    public boolean isInCategory(ParamDef p, int cat) {
        if (cat < categories.size()) {
            HashMap<ParamDef, String> h = categories.get(cat);

            if (h.containsKey(p)) {
                return true;
            }
        }

        return false;
    }
}
