/* Author: Clauirton Siebra
 * Updated: Thu May 15 13:40:56 2003 by Clauirton Siebra
 * Copyright: (c) 2001 - 2003, AIAI, University of Edinburgh
 */

package ix.ip2;

import javax.swing.*;
import java.util.*;
import java.awt.Component;
import java.awt.event.*;

import ix.util.*;
import ix.util.lisp.*;
import ix.icore.domain.*;
import ix.icore.process.event.*;
import ix.iface.util.*;

import ix.ip2.map.MapTool;

public class StateViewMap extends ToolFrame implements StateViewer {

    protected Ip2 ip2;
    public MapTool mapTool;
    StateViewTable svt = null;

    /**
     * Constructs a viewer for the indicated agent.
     */
    public StateViewMap(Ip2 ip2) {
        super();
        svt = new StateViewTable(ip2);
        this.ip2 = ip2;
        //(ip2.getModelManager()).addProcessStatusListener(this);
	(ip2.getModelManager()).addProcessStatusListener(svt);

        // Configures the map tool
        mapTool = new MapTool(this,ip2.getAgentDisplayName()+" Map Tool");   
        ip2.addTool(new MapToolController("Map Tool"));
    }

    /**
     * Returns a component that represents a state table
     */
    public Component getView(PanelFrame frame) {
        return svt.getView(frame);
    }

    /**
     * Sends a constraint to agent
     * @param list of parameters 
     */
    public void sendConstraint(PatternAssignment pa){
        Vector v = new Vector();
        v.add(pa);
        Constraint c = new Constraint(Symbol.intern("world-state"),Symbol.intern("effect"),v);
        ((Ip2ModelManager)ip2.getModelManager()).addConstraint(c);
    }

    /**
     * Sets the viewer back to something approximating its initial state.
     */
    public void reset() {
        svt.reset();
        mapTool.reset();
    }
    
    //Methods in ProcessStatusListener interface
     
    /** Ignored by this viewer. */
    public void statusUpdate(ProcessStatusEvent event) { }

    /** Ignored by this viewer. */
    public void newBindings(ProcessStatusEvent event, Map bindings) { }

    /** 
     * Deletes the states no more used by the agent.
     */
     
    public void stateDeletion(ProcessStatusEvent event, Map delta) {
        for (Iterator i = delta.entrySet().iterator(); i.hasNext();) {
            Map.Entry e = (Map.Entry)i.next();
            LList pattern = (LList)e.getKey();
            Object value = e.getValue();
            mapTool.deletePatternValue(pattern,value);
        }
    }

    /** 
     * Updates the viewers according to the current state of the agent.
     */
    public void stateChange(ProcessStatusEvent event, Map delta) {
        for (Iterator i = delta.entrySet().iterator(); i.hasNext();) {
            Map.Entry e = (Map.Entry)i.next();
            LList pattern = (LList)e.getKey();
            Object value = e.getValue();
            recordNewValue(pattern, value);
            mapTool.changePatternValue(pattern,value);
        }
    }

    protected void recordNewValue(LList pattern, Object value) {
        //Debug.noteln("State viewer sees " + pattern + " = " + value);
        mapTool.addPatternValue(pattern,value);
    }

    /** 
     * Auxiliar class to add the map tool into the agent frame.
     */
    protected class MapToolController extends ToolController {
        public MapToolController(String name) {
            super(name);
        }
        
        public Object createTool(){ 
            return mapTool;
        }
        
        public void setToolVisible(boolean t){
            mapTool.setVisible(t);
        }
    }
}
