/*
 * ModifySlot.java - userfunction
 */

package jess.runa;

import java.util.*;
import jess.*;

public class ModifySlot implements Userfunction {

	public String getName() { return "modify-slot"; }
	private String getSlotName(ValueVector svp, Context c)
						throws JessException
	{
		return svp.get(0).stringValue(c);
	}
	Value getSlotValue(ValueVector svp, Context c, int type)
						throws JessException
	{
    		if (type == RU.SLOT)
		{
			Value v = svp.get(1).resolveValue(c);
			while (v.type() == RU.LIST)
				v = v.listValue(c).get(0).resolveValue(c);
			return v;
		} 
		else // MULTISLOT
		{
			ValueVector vv = new ValueVector();
			for (int i=1; i<svp.size(); i++)
			{
				Value listItem = svp.get(i).resolveValue(c);
				if (listItem.type() == RU.LIST)
				{
					ValueVector sublist = listItem.listValue(c);
					for (int j=0; j<sublist.size(); j++)
						vv.add(sublist.get(j).resolveValue(c));
				} 
				else
					vv.add(listItem);
			}
			return new Value(vv, RU.LIST);
      		}
	}
	public Value call(ValueVector vv, Context context) 
						throws JessException
	{
       		Rete engine = context.getEngine();
       		Fact fact;
		int factId = vv.get(1).factIDValue(context);
	        if ((fact = engine.findFactByID(factId)) == null)
         			throw new JessException("modify-slot", "no such fact", String.valueOf(factId));
		Deftemplate dt = fact.getDeftemplate();
               	for (int i= 2; i < vv.size(); i++)
		{
			Funcall fc = vv.get(i).funcallValue(context);
             		ValueVector svp = new ValueVector (2);
			svp.add (fc.get(0));
			svp.add (fc.get(1));
               		String slotName = getSlotName(svp, context);
               		int idx  = dt.getSlotIndex(slotName);
               		int type = dt.getSlotType(idx);
	                fact.setSlotValue(slotName, getSlotValue(svp, context, type));                
		}
		return new Value(factId, RU.FACT_ID);        
	}
}

/*
 * end of ModifySlot.java
 */
