/* Title:		OperationMeta.java
 * Version	
 * Author		Sada
 * Company: USDA-ARS
 * Date:    July, 2003
 * Description: This class holds information which DEFINES an operation (through actionMeta).
 * 
 */
package usda.weru.mcrew;

import java.util.Enumeration;
import java.util.Hashtable;

import org.w3c.dom.*;
import org.w3c.dom.traversal.*;

/**
 * j
 */
public class OperationMeta extends ObjectMeta {

    private Hashtable<Identity, ActionMeta> mActions; //holds as many actionMetas as there are actions
    ActionMeta mDefaultAction;

    /**
     * j
     */
    public OperationMeta() {
        mActions = new Hashtable<>();
        mDefaultAction = null;
        //System.out.println("Operation Meta : NO Argument CONSTRUCTOR with mActions NEW Hashtable");
    }

    /**
     *
     * @param pObjectName
     */
    public OperationMeta(String pObjectName) {
        mActions = new Hashtable<>();
        mObjectName = pObjectName;
        //System.out.println("Operation Meta : 1 Argument CONSTRUCTOR with mActions NEW Hashtable");
    }

    /**
     *
     * @param pNode
     */
    @Override
    public void initialize(Node pNode) {
        DocumentTraversal traversable;
        Node node;

        if (pNode.getOwnerDocument() == null) {
            traversable = (DocumentTraversal) pNode;
        } else {
            traversable = (DocumentTraversal) pNode.getOwnerDocument();
        }

        TreeWalker walker = traversable.createTreeWalker(pNode, NodeFilter.SHOW_ALL, null, false);

        node = walker.firstChild(); // the node is one of the action (operationdefn) or paramdefn (crop_defn) from 

        while (node != null) {
            String nodeName = node.getNodeName();
            if (nodeName.equals(XMLConstants.saction)) {
                ActionMeta actionMeta = new ActionMeta();
                actionMeta.initialize(node);

                addAction(actionMeta);
            }

            node = walker.nextSibling();
        } // end while(node != null)
    }

    /**
     *
     * @param pNode
     */
    @Override
    public void update(Node pNode) {
        DocumentTraversal traversable;
        Node node;

        if (pNode.getOwnerDocument() == null) {
            traversable = (DocumentTraversal) pNode;
        } else {
            traversable = (DocumentTraversal) pNode.getOwnerDocument();
        }

        TreeWalker walker = traversable.createTreeWalker(pNode, NodeFilter.SHOW_ALL, null, false);

        node = walker.firstChild(); // The node is one of the action (operationlang) or paramlang (croplang) 
        // or categoryname (cropdisplay)

        while (node != null) {
            String nodeName = node.getNodeName();

            if (nodeName.equals(XMLConstants.saction)) {
                Node identityNode = walker.firstChild();

                Node codeNode = walker.firstChild();
				//String codeValue = walker.firstChild().getNodeValue();
                //walker.parentNode(); // move walker to level of id/code
                String codeValue = XMLDoc.getTextData(codeNode); //getTextData return the text data of the text Child like 'P', 'O', 'G'

                Node idNode = walker.nextSibling();
				//String idValue = walker.firstChild().getNodeValue();
                //walker.parentNode(); // move walker to level of id/code
                String idValue = XMLDoc.getTextData(idNode);

                ActionMeta actionMeta = getActionMeta(new Identity((new Integer(idValue)).intValue(), codeValue));
                if (actionMeta != null) {
                    actionMeta.update(node); // updates the definition with all other values such as alt unit, conversion...
                    //System.out.println("OperationMeta : update() : Action found, action id = " + idValue + " code = " + codeValue);
                } else {
                    //System.out.println("Action not found, action id = " + idValue + "code = " + codeValue + " @OperationMeta:update()");
                }

                walker.parentNode(); /// move one more level to identity/ actionname/ paramlang/ paramdisplay 
                walker.parentNode(); //move to the level of action
            }

            node = walker.nextSibling();
        } // end while(node != null)
    }

    /**
     *
     * @param pAction
     */
    public void addAction(ActionMeta pAction) {
        if (mActions == null) {
            mActions = new Hashtable<>();
        }
        Identity identity = pAction != null ? pAction.getIdentity() : null;
        if (identity != null) {
            mActions.put(identity, pAction);
        }

    }

    /* Not used currently
     */
    /**
     *
     * @param pMeta
     */
    public void addParameterMeta(ParameterMeta pMeta) //for objects with no Action such as cropdefn.xml
    {
        if (mDefaultAction == null) {
            mDefaultAction = new ActionMeta();
        }

        mDefaultAction.addParameterMeta(pMeta);
    }

    /**
     *
     * @param pIdentity
     * @return
     */
    @Override
    public ActionMeta getActionMeta(Identity pIdentity) {
        return mActions.get(pIdentity);
    }

    /**
     *
     * @return
     */
    public ActionMeta getDefaultAction() {
        return mDefaultAction;
    }

    /**
     *
     * @return
     */
    public String getObjectName() {
        return mObjectName;
    }

    /**
     *
     * @param pParamName
     * @param pValueName
     * @return
     */
    @Override
    public String getValue(String pParamName, String pValueName) {
        if (pParamName.equals(XMLConstants.sobjectname)) {
            return mObjectName;
        }

		////System.out.println("OperationObject" + "Trying to get value for col " + pColName);  	
		/* If pColName is not operation name, then its one of the parameters in one of the Actions
         * Search all the actions until you get the first parameterwith name = pColName
         */
        Enumeration<ActionMeta> e = mActions.elements();
        while (e.hasMoreElements()) {
            ActionMeta actionMeta = e.nextElement();
            String value = actionMeta.get(pParamName, pValueName);
            if (value != null) {
                return value;
            }
        }

        return null;
    }

}
