/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.lang.reflect.*;
import java.io.*;

public class DomainModelManager implements Externalizable{
    protected TreeMap actionMapping;
    protected TreeMap objectMapping;
    private DomainAction lastAction;
    private DomainObject lastObject;
    private String alastName=null;
    private String olastName=null;
    private DomainAction [] actions; //Vector would have been better
    private String [] anames;
    private DomainObject [] objects; //Vector would have been better
    private String [] onames;
    
    protected JDialog actionDialog;
    protected Field [] actionFields;
    protected JComponent [] actionComp;

    protected JDialog objectDialog;
    protected Field [] objectFields;
    protected JComponent [] objectComps;
    
    public static String oldActionName;
    public static String newActionName;
    public static DomainAction actionBuff;
    
    //value for domain object cardinality
    public static final String CARDINALITY_CONTENTS[] = {"singular", "plural", "mass noun"};
	public TreeMap cardinalityMapping; 
    
    //private JPanel fieldsPanel; ).toLowerCase()

    public DomainModelManager(){
    	cardinalityMapping= new TreeMap();
    	for ( int i =0; i<CARDINALITY_CONTENTS.length; i++)
    		cardinalityMapping.put(CARDINALITY_CONTENTS[i],new Integer(i));
 	
    	actionMapping=new TreeMap();
    //	actionMapping.put(DomainDefault.DEFAULT,DomainDefault.getDefaultDomainAction());
    	actionMapping.put((DomainDefault.DEFAULT).toLowerCase(),DomainDefault.getDefaultDomainAction());
    	objectMapping=new TreeMap();
    //	objectMapping.put(DomainDefault.DEFAULTUSER,DomainDefault.getDefaultDomainObject());
    //	objectMapping.put(DomainDefault.DEFAULTSYSTEM,DomainDefault.getDefaultDomainObject());
        objectMapping.put((DomainDefault.DEFAULTUSER).toLowerCase(),DomainDefault.getDefaultDomainObject());
        objectMapping.put((DomainDefault.DEFAULTSYSTEM).toLowerCase(),DomainDefault.getDefaultSystemObject());
    }
    
    public void writeExternal(ObjectOutput out) throws IOException{
    	out.writeObject(actionMapping);
    	out.writeObject(objectMapping);
    }
    
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{
        actionMapping=(TreeMap)in.readObject();
        objectMapping=(TreeMap)in.readObject();
    	if (!actionMapping.containsKey(DomainDefault.DEFAULT)) actionMapping.put(DomainDefault.DEFAULT,DomainDefault.getDefaultDomainAction());
    	if (!objectMapping.containsKey(DomainDefault.DEFAULTUSER)) objectMapping.put(DomainDefault.DEFAULTUSER,DomainDefault.getDefaultDomainObject());
    }

    public void register(String name,Object o){
    	//if (o instanceof DomainAction) actionMapping.put(name,o);
    	//else if (o instanceof DomainObject) objectMapping.put(name,o);
    	String lCase = name.toLowerCase();
    	if (o instanceof DomainAction) actionMapping.put(lCase,o);
    	else if (o instanceof DomainObject) objectMapping.put(lCase,o);
    }
    public void unRegister(String name){
    	//if (isDmActionKey(name)) actionMapping.remove(name);
    	//else if (isDmObjKey( name)) objectMapping.remove(name);
    	String lCase = name.toLowerCase();
    	if (isDmActionKey(lCase)) actionMapping.remove(lCase);
    	else if (isDmObjKey( lCase)) objectMapping.remove(lCase);
    }



    public boolean isDmObjKey(String name){
       //if (objectMapping.containsKey(name)) return true; 
       if (objectMapping.containsKey(name.toLowerCase())) return true; 
       else return false;
       }
       
    public boolean isDmActionKey(String name){
   		//if (actionMapping.containsKey(name)) return true; 
   		if (actionMapping.containsKey(name.toLowerCase())) return true; 
    	else return false;
    }
  



    
    public void editor(){
    	Set keys=actionMapping.keySet();
    	anames=new String[keys.size()];
    	actions=new DomainAction[keys.size()];
    	int i=0;
    	String s;
    	for (Iterator it=keys.iterator();it.hasNext();){
    	    s=(String)it.next();
    	    anames[i]=s;
    	    actions[i++]=(DomainAction)actionMapping.get(s);
    	}
    	keys=objectMapping.keySet();
    	onames=new String[keys.size()];
    	objects=new DomainObject[keys.size()];
        i=0;
    	for (Iterator it=keys.iterator();it.hasNext();){
    	    s=(String)it.next();
    	    onames[i]=s;
    	    objects[i++]=(DomainObject)objectMapping.get(s);
    	}
    	
    	
    	
        final JList alist=new JList(anames);
        alist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane alistScrollPane = new JScrollPane(alist);
        final JList olist=new JList(onames);
        olist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        JScrollPane olistScrollPane = new JScrollPane(olist);
        
        final JPanel afieldsPanel=new JPanel();
        JScrollPane apanelScrollPane = new JScrollPane(afieldsPanel);
        final JPanel ofieldsPanel=new JPanel();
        JScrollPane opanelScrollPane = new JScrollPane(ofieldsPanel);
        
        JSplitPane asplitPane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,alistScrollPane,apanelScrollPane);
        JSplitPane osplitPane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,olistScrollPane,opanelScrollPane);
        
        Dimension minimumSize = new Dimension(100, 200);
        alistScrollPane.setMinimumSize(minimumSize);
        apanelScrollPane.setMinimumSize(minimumSize);
        olistScrollPane.setMinimumSize(minimumSize);
        opanelScrollPane.setMinimumSize(minimumSize);

        //Provide a preferred size for the split pane
        asplitPane.setPreferredSize(new Dimension(500, 200));
        osplitPane.setPreferredSize(new Dimension(500, 200));
        
        final ModificationBackup amodif=new ModificationBackup();
        final ModificationBackup omodif=new ModificationBackup();
        
        JButton bNew1=new JButton("New");
        bNew1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            	JPanel p=new JPanel();
            	p.setLayout(new GridLayout(1,2));
            	p.add(new JLabel("Name:"));
            	JTextField t=new JTextField();
            	p.add(t);
            	
                String [] options={"Ok","Cancel"};
                int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,p,
                	"New Domain Model action",JOptionPane.OK_CANCEL_OPTION,
                		JOptionPane.PLAIN_MESSAGE,null,options,options[0]);
                if (choice==0){
            	    String sssss=t.getText();
            	    if (actionMapping.containsKey(sssss)) 
            	    	JOptionPane.showMessageDialog(MainFrame.mainFrame,sssss+" already exists!",
            	    		"Error",JOptionPane.ERROR_MESSAGE);
            	    else { //ok
            	    	//actionMapping.put(sssss,new DomainAction(sssss));
            	    	register(sssss,new DomainAction(sssss));
            	    	
    	                Set keysn=actionMapping.keySet();
    	                anames=new String[keysn.size()];
            	    	actions=new DomainAction[keysn.size()];
    	                int in=0;
    	                String sn;
    	                for (Iterator itn=keysn.iterator();itn.hasNext();){
    	                    sn=(String)itn.next();
    	                    anames[in]=sn;
    	                    //actions[in++]=(DomainAction)actionMapping.get(sn);
    	                    actions[in++]=(DomainAction)getDAction(sn);

    	                }
            	    	alist.setListData(anames);
                	FileManager.MODIFIED=true;         
		    } 
                }
            }
        });
        
        JButton bDelete1=new JButton("Delete");
        bDelete1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            	String name=(String)alist.getSelectedValue();            	
                String [] options={"Ok","Cancel"};
                int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                	"Remove '"+name+"' ?","Delete Domain Model action",
                		JOptionPane.OK_CANCEL_OPTION,JOptionPane.PLAIN_MESSAGE,null,
                			options,options[0]);
                if (choice==0){
            	    actionMapping.remove(name);
            	    amodif.remove(name);
    	            Set keysn=actionMapping.keySet();
    	            anames=new String[keysn.size()];
            	    actions=new DomainAction[keysn.size()];
    	            int in=0;
    	            String sn;
    	            for (Iterator itn=keysn.iterator();itn.hasNext();){
    	                sn=(String)itn.next();
    	                anames[in]=sn;
    	                //actions[in++]=(DomainAction)actionMapping.get(sn);
    	                actions[in++]=(DomainAction)getDAction(sn);

    	            }
            	    alist.setListData(anames);
            	    afieldsPanel.removeAll();
	            FileManager.MODIFIED=true;         
                }
            }
        });

        JButton bNew2=new JButton("New");
        bNew2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            	JPanel p=new JPanel();
            	p.setLayout(new GridLayout(1,2));
            	p.add(new JLabel("Name:"));
            	JTextField t=new JTextField();
            	p.add(t);
            	
                String [] options={"Ok","Cancel"};
                int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,p,
                	"New Domain Model object",JOptionPane.OK_CANCEL_OPTION,
                		JOptionPane.PLAIN_MESSAGE,null,options,options[0]);
                if (choice==0){
            	    String sssss=t.getText();
            	    if (objectMapping.containsKey(sssss)) 
            	    	JOptionPane.showMessageDialog(MainFrame.mainFrame,sssss+" already exists!",
            	    		"Error",JOptionPane.ERROR_MESSAGE);
            	    else { //ok
            	    	//objectMapping.put(sssss,new DomainObject(sssss));
            	    	register(sssss,new DomainObject(sssss));

    	                Set keysn=objectMapping.keySet();
    	                anames=new String[keysn.size()];
            	    	objects=new DomainObject[keysn.size()];
    	                int in=0;
    	                String sn;
    	                for (Iterator itn=keysn.iterator();itn.hasNext();){
    	                    sn=(String)itn.next();
    	                    anames[in]=sn;
    	                    //objects[in++]=(DomainObject)objectMapping.get(sn);
    	                    objects[in++]=(DomainObject)getDObject(sn);

    	                }
            	    	olist.setListData(anames);
    			FileManager.MODIFIED=true;         
            	    } 
                }
            }
        });
        
        JButton bDelete2=new JButton("Delete");
        bDelete2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
            	String name=(String)olist.getSelectedValue();            	
                String [] options={"Ok","Cancel"};
                int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,
                	"Remove '"+name+"' ?","Delete Domain Model object",
                		JOptionPane.OK_CANCEL_OPTION,JOptionPane.PLAIN_MESSAGE,null,options,options[0]);
                if (choice==0){
            	    objectMapping.remove(name);
            	    omodif.remove(name);
    	            Set keysn=objectMapping.keySet();
    	            onames=new String[keysn.size()];
            	    objects=new DomainObject[keysn.size()];
    	            int in=0;
    	            String sn;
    	            for (Iterator itn=keysn.iterator();itn.hasNext();){
    	                sn=(String)itn.next();
    	                onames[in]=sn;
    	                //objects[in++]=(DomainObject)objectMapping.get(sn);
    	                objects[in++]=(DomainObject)getDObject(sn);
    	            }
            	    olist.setListData(onames);
            	    ofieldsPanel.removeAll();            	    
    		    FileManager.MODIFIED=true;         
                }
            }
        });
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(2,1));
        p1.add(bNew1);
        p1.add(bDelete1);
        
        JPanel p2=new JPanel();
        p2.setLayout(new GridLayout(2,1));
        p2.add(bNew2);
        p2.add(bDelete2);
        
        JPanel apanel=new JPanel();
        apanel.add(asplitPane,BorderLayout.CENTER);
        apanel.add(p1,BorderLayout.SOUTH);
        JPanel opanel=new JPanel();
        opanel.add(osplitPane,BorderLayout.CENTER);
        opanel.add(p2,BorderLayout.SOUTH);
        
        
        
        JTabbedPane tab=new JTabbedPane();
    	tab.addTab("Domain Actions",apanel);
    	tab.setSelectedIndex(0);
    	tab.addTab("Domain Objects",opanel);    	
    	//tab.setPreferredSize(new Dimension(290,350));

        
        

        
        alist.addListSelectionListener(new ListSelectionListener(){
            public void valueChanged(ListSelectionEvent e){
                JList theList = (JList)e.getSource();
                if (!theList.isSelectionEmpty()) {
            	    DomainAction da=actions[theList.getSelectedIndex()];
            	    if (da!=lastAction){
            	    	lastAction=da;
            	        String name=(String)theList.getSelectedValue();
                        
                        if (alastName!=null){
                            int l=afieldsPanel.getComponentCount();
                            for (int ii=0;ii<l;ii+=2){
                                amodif.addElement(alastName,((JLabel)afieldsPanel.getComponent(ii)).getText(),((JTextField)afieldsPanel.getComponent(ii+1)).getText());
                            }
            	            afieldsPanel.removeAll();
            	        }            
                        alastName=name;
                    
                        Field [] fields=da.getClass().getDeclaredFields();
            	        afieldsPanel.setLayout(new GridLayout(fields.length,2));
            	        Object ob;
            	        JComponent jc=null;
            	        Dimension maximumSize;
            	        JTextField tf;
            	        for (int j=0;j<fields.length;j++){
            	            jc=new JLabel(fields[j].getName());
                            maximumSize = new Dimension(100, 30);
                            jc.setMaximumSize(maximumSize);
                            afieldsPanel.add(jc);

            	            ob=null;
            	            try {
            	                String sss;
            	                if ((sss=amodif.modification(name,fields[j].getName()))==null) 
            	                	ob=fields[j].get(da);
            	                else ob=sss;
            	            }catch (IllegalAccessException excep){}
            	            tf=(ob==null)?(new JTextField("")):(new JTextField((String)ob));
            	            if (j==0) tf.setEditable(false);
                            maximumSize = new Dimension(100, 30);
                            tf.setMaximumSize(maximumSize);            	    
            	            afieldsPanel.add(tf);
            	        }
                    }
            	    afieldsPanel.revalidate();
                }
            }
        });
        
        olist.addListSelectionListener(new ListSelectionListener(){
            public void valueChanged(ListSelectionEvent e){
                JList theList = (JList)e.getSource();
                if (!theList.isSelectionEmpty()) {
            	    DomainObject dob=objects[theList.getSelectedIndex()];
            	    if (dob!=lastObject){
            	    	lastObject=dob;
            	        String name=(String)theList.getSelectedValue();
                        
                        if (olastName!=null){
                            int l=ofieldsPanel.getComponentCount();
                            for (int ii=0;ii<l;ii+=2){
                                omodif.addElement(olastName,((JLabel)ofieldsPanel.getComponent(ii)).getText(),((JTextField)ofieldsPanel.getComponent(ii+1)).getText());
                            }
            	            ofieldsPanel.removeAll();
            	        }            
                        olastName=name;
                    
                        Field [] fields=dob.getClass().getDeclaredFields();
            	        ofieldsPanel.setLayout(new GridLayout(fields.length,2));
            	        Object obb;
            	        JComponent jc=null;
            	        Dimension maximumSize;
            	        JTextField tf;
            	        for (int j=0;j<fields.length;j++){
            	            jc=new JLabel(fields[j].getName());
                            maximumSize = new Dimension(100, 30);
                            jc.setMaximumSize(maximumSize);
                            ofieldsPanel.add(jc);

            	            obb=null;
            	            try {
            	                String sss;
            	                if ((sss=omodif.modification(name,fields[j].getName()))==null) obb=fields[j].get(dob);
            	                else obb=sss;
            	            }catch (IllegalAccessException excep){}
            	            tf=(obb==null)?(new JTextField("")):(new JTextField((String)obb));
            	            if (j==0) tf.setEditable(false);
                            maximumSize = new Dimension(100, 30);
                            tf.setMaximumSize(maximumSize);            	    
            	            ofieldsPanel.add(tf);
            	        }
                    }
            	    ofieldsPanel.revalidate();
                }
            }
        });
        
        
        
        
        alist.setSelectedIndex(0);
        olist.setSelectedIndex(0);
        
        
        String [] options={"Ok","Cancel"};
        int choice=JOptionPane.showOptionDialog(MainFrame.mainFrame,tab,
        	"Domain Model (experimental)",JOptionPane.OK_CANCEL_OPTION,
        		JOptionPane.PLAIN_MESSAGE,null,options,options[0]);
        if (choice==0){


            if (alastName!=null){
                int l=afieldsPanel.getComponentCount();
                for (int ii=0;ii<l;ii+=2){
                    amodif.addElement(alastName,((JLabel)afieldsPanel.getComponent(ii)).getText(),
                    	((JTextField)afieldsPanel.getComponent(ii+1)).getText());
                }
            }            
            if (olastName!=null){
                int l=ofieldsPanel.getComponentCount();
                for (int ii=0;ii<l;ii+=2){
                    omodif.addElement(olastName,((JLabel)ofieldsPanel.getComponent(ii)).getText(),
                    	((JTextField)ofieldsPanel.getComponent(ii+1)).getText());
                }
            }            


            Iterator it2;
            String s1,s2;
            TreeMap ttemp;
            DomainAction a;
            Field field;
            for (Iterator it1=amodif.keySet().iterator();it1.hasNext();){
                s1=(String)it1.next();
                ttemp=(TreeMap)amodif.get(s1);
                for (it2=ttemp.keySet().iterator();it2.hasNext();){
                    s2=(String)it2.next();
                    try {
                        a=(DomainAction)actionMapping.get(s1);
                        field=a.getClass().getField(s2);
                        //field.set(a,ttemp.get(s2));
                        if (s2.equals("documentation"))
                        	field.set(a,ttemp.get(s2));
                        else field.set(a,((String)ttemp.get(s2)).toLowerCase());

                    } catch (Exception excep){System.err.println(excep);}
                    
                }
            } 
            DomainObject o;
            for (Iterator it1=omodif.keySet().iterator();it1.hasNext();){
                s1=(String)it1.next();
                ttemp=(TreeMap)omodif.get(s1);
                for (it2=ttemp.keySet().iterator();it2.hasNext();){
                    s2=(String)it2.next();
                    try {
                        o=(DomainObject)objectMapping.get(s1);
                        field=o.getClass().getField(s2);
                        field.set(o,ttemp.get(s2));
                        if (s2.equals("documentation"))
                        	field.set(o,ttemp.get(s2));
                        else field.set(o,((String)ttemp.get(s2)).toLowerCase());

                    } catch (Exception excep){System.err.println(excep);}
                    
                }
            } 
        }           
    }
    
    public boolean parseSemanticsAndCreate(String se){
    	String sem=se.toLowerCase();
    	
    	StringTokenizer st=new StringTokenizer(sem);
    	int nbTokens=st.countTokens();
    	if (nbTokens>=2){
    	    String verb=st.nextToken();
    	    String actee=st.nextToken();
    	    String proposition="";
    	    if (nbTokens>=3){
    	        StringBuffer buf=new StringBuffer();
    	        buf.append(st.nextToken());
    	        while (st.hasMoreTokens()){
    	            buf.append(' ');
    	            buf.append(st.nextToken());
    	        }
    	        proposition=buf.toString();
    	    }   	                    
    	    DomainAction da;
    	    
    	    
    	    if (isDmActionKey(oldActionName)){
    	    	System.out.println(" reuse new dm action");

    	    		da= getDAction(oldActionName); 
    	    		da.name=sem;
    	    		oldActionName= sem;
    	    }else {
    	    	da =new DomainAction(sem);
    	    	System.out.println(" create new dm action");
    	    }
    	    
    	    da.verb=verb.toLowerCase();
    	    da.actee=actee.toLowerCase();
    	    da.proposition=proposition.toLowerCase();
    	    
    	    actionBuff= da;
    	    
    	    Manager.dmManager.register(sem,da);
			DomainObject dmObj;
    		if (isDmObjKey(actee))
    			dmObj= getDObject( actee);
    		else {
    			dmObj=new DomainObject(actee);
    			Manager.dmManager.register(actee,dmObj);

    		}
    	    DomainObject dob; //=new DomainObject(actee);
    	    if (!proposition.equals("")){
    	        dob=new DomainObject(proposition);
    	        Manager.dmManager.register(proposition,dob);
    	    }
    	    return true;
    	}
    	else {if (sem.equals("")) return true; else return false;}
    }
    

    public DomainAction getDAction(String name){
    	//return (DomainAction)actionMapping.get(name);
    	return (DomainAction)actionMapping.get(name.toLowerCase());
    	
    }

    public DomainObject getDObject(String name){
    	//return (DomainObject)objectMapping.get(name);
    	return (DomainObject)objectMapping.get(name.toLowerCase());
    	
    }
    
    public void  editAction(String name ){
    	if (!parseSemanticsNotRegister(name)) {
    	        	JOptionPane.showMessageDialog(MainFrame.mainFrame,
    	            	"Semantics should consist of 2 or more words!\nOtherwise no Domain Model instance will be created\n for this task.","Warning",
    	             	JOptionPane.WARNING_MESSAGE); 
    	       		return;
    	}
/*
    	DomainAction da=new DomainAction("test");
    	if (isDmActionKey(name))
    		da= getDAction( name); 
   */                //     alastName=name;
        actionFields=actionBuff.getClass().getDeclaredFields();
        actionComp = new JComponent[actionFields.length];
        JPanel afieldsPanel= new JPanel();
        afieldsPanel.setLayout(new GridLayout(actionFields.length,3));
        Object ob;
        JComponent jc=null;
        Dimension maximumSize;
        JTextField tf;
        Field field;
        JButton actorB= new JButton("Edit Actor");
		JButton acteeB= new JButton("Edit Actee");

		for (int j=0;j<actionFields.length;j++){
			String filedName = actionFields[j].getName();
			jc=new JLabel(filedName);
            field =actionFields[j];
            maximumSize = new Dimension(100, 30);
            jc.setMaximumSize(maximumSize);
            afieldsPanel.add(jc);
            ob=null;
            try {
            	ob=actionFields[j].get(actionBuff);
            }catch (IllegalAccessException excep){}

            tf=(ob==null)?(new JTextField("")):(new JTextField((String)ob));
            //if (j==0) tf.setEditable(false);
            if (filedName.equals("verb") ||filedName.equals("actee")
            	||filedName.equals("proposition") ) tf.setEditable(false);
			maximumSize = new Dimension(100, 30);
            tf.setMaximumSize(maximumSize);            	    
            afieldsPanel.add(tf);
            actionComp[j]=tf;
            if ((field.getName()).equals("name")){
            	afieldsPanel.add(new JLabel(""));
				tf.addFocusListener(new DmActionParsing());
   	            
   	        } else if ((field.getName()).equals("actor")){
   	        	actorB.setMaximumSize(maximumSize); 
   	            actorB.addActionListener(new DmActorD());
   	            afieldsPanel.add(actorB);
                    
   	        } else if((field.getName()).equals("actee")){
   	        	acteeB.setMaximumSize(maximumSize); 
   	            acteeB.addActionListener(new DmActeeD());
   	            afieldsPanel.add(acteeB);
   	        } else afieldsPanel.add(new JLabel(""));

        }
        Dimension actPanelD= new Dimension(400,160);
        afieldsPanel.setPreferredSize(actPanelD);
        afieldsPanel.revalidate();
        
    	JOptionPane pane = new JOptionPane(afieldsPanel,
    		JOptionPane.PLAIN_MESSAGE,JOptionPane.OK_CANCEL_OPTION);
    	actionDialog = pane.createDialog(MainFrame.mainFrame, "Edit domain action");
    //	EditionDialog.dialog.hide();
		actionDialog.show();
		Object selectedValue = pane.getValue();
		if (selectedValue != null && selectedValue != JOptionPane.UNINITIALIZED_VALUE){
			Integer sv = (Integer)selectedValue;
			
			if( sv.intValue()  == JOptionPane.OK_OPTION) {
				parseUpdateActionFields();
				modifyAction(actionBuff);
				
			}else {
				
				
				
				
			}
		}
	//	EditionDialog.dialog.show();
        
    }
    
 public void  modifyAction(DomainAction da ){
 	//if (!(da instanceof DomainAction)) return;
 	
 	for (int i=0;i<actionFields.length;i++){
    	String aFname=actionFields[i].getName();
    	String type=actionFields[i].getType().getName();
    	if (aFname.equals("name")){
    		String semValue=((JTextField)actionComp[i]).getText();
	    	for (int j=0;j<EditionDialog.fields.length;j++){
	            String name=EditionDialog.fields[j].getName();
	
	    	    if (name.equals("semantics"))
	    	          ((JTextField)EditionDialog.jComp[j]).setText(semValue);
	    	}
    	}
    	             
	  	if (type.equals("java.lang.String")){
	   		try{
	   			if (!(actionFields[i].getName().equals("documentation")))
	   	        	actionFields[i].set(da,((JTextField)actionComp[i]).getText());
	   	        else
	   	        	actionFields[i].set(da,(((JTextField)actionComp[i]).getText()).toLowerCase());

	   	    } catch (Exception except){}
	    }else if (type.equals("int")){
	    	int nb=-1;
	        try {
	             nb=Integer.parseInt(((JTextField)actionComp[i]).getText());
	             if (nb<0) nb=-1;
	        } catch (NumberFormatException excep){}
	   	    try{
	   	          actionFields[i].setInt(da,nb);
	  	    } catch (Exception except){}
	    }else if (type.equals("boolean")) {
	   	    try{
	   	        actionFields[i].setBoolean(da,((AbstractButton)actionComp[i]).isSelected());
	   	     } catch (Exception except){}
	    }
 	}
 	
 }
 
    public boolean parseSemanticsNotRegister(String se){
    	String sem = se.toLowerCase();
    	
    	if (actionBuff == null) parseSemanticsAndCreate( sem);
    	
    	StringTokenizer st=new StringTokenizer(sem);
    	int nbTokens=st.countTokens();
    	if (nbTokens>=2){
    	    String verb=st.nextToken();
    	    String actee=st.nextToken();
    	    String proposition="";
    	    if (nbTokens>=3){
    	        StringBuffer buf=new StringBuffer();
    	        buf.append(st.nextToken());
    	        while (st.hasMoreTokens()){
    	            buf.append(' ');
    	            buf.append(st.nextToken());
    	        }
    	        proposition=buf.toString();
    	    }   	                    
    	    
    	    if (!(sem.equals(actionBuff.name) ))
    	    	actionBuff.name= sem;	
    	    actionBuff.verb=verb.toLowerCase();
    	    actionBuff.actee=actee.toLowerCase();
    	    actionBuff.proposition=proposition.toLowerCase();
    	    
			DomainObject dmObj;
    		if (isDmObjKey(actee))
    			dmObj= getDObject( actee);
    		else {
    			dmObj=new DomainObject(actee);
    			Manager.dmManager.register(actee,dmObj);

    		}
    	    DomainObject dob; //=new DomainObject(actee);
    	    //Manager.dmManager.register(actee,dob);
    	    if (!proposition.equals("")){
    	        dob=new DomainObject(proposition);
    	        Manager.dmManager.register(proposition,dob);
    	    }
    	    return true;
    	}
    	else {if (sem.equals("")) return true; else return false;}
    }
    
 
 /*

     public boolean parseSemantics(String sem){
     	actionBuff=new TreeMap();
    	StringTokenizer st=new StringTokenizer(sem);
    	int nbTokens=st.countTokens();
    	if (nbTokens>=2){
    	    //String actor=DomainDefault.DEFAULTUSER;  //"Default";
    	    String verb=st.nextToken();
    	    String actee=st.nextToken();
    	    String proposition="";
    	    if (nbTokens>=3){
    	        StringBuffer buf=new StringBuffer();
    	        buf.append(st.nextToken());
    	        while (st.hasMoreTokens()){
    	            buf.append(' ');
    	            buf.append(st.nextToken());
    	        }
    	        proposition=buf.toString();
    	    } 
    	    actionBuff.put("verb", verb);
    	    actionBuff.put("actee", actee);
    	    actionBuff.put("proposition", proposition);
    	    
    	    
    	    return true;
    	}else{if (sem.equals("")) return true; else return false;}
   	}
*/
    public void  editObject(String name ){

    	DomainObject dmObj;
    	if (isDmObjKey(name))
    		dmObj= getDObject( name);
    	else {
    		dmObj=new DomainObject(name);
    		Manager.dmManager.register(name,dmObj);

    	}

    	objectFields=dmObj.getClass().getDeclaredFields();
        objectComps = new JComponent[objectFields.length];
        JPanel ofieldsPanel= new JPanel();
        ofieldsPanel.setLayout(new GridLayout(objectFields.length,2));
        Object ob;
        JComponent jc=null;
        Dimension maximumSize;
        JTextField tf;
        Field field;
        JButton actorB= new JButton("Edit Actor");
		JButton acteeB= new JButton("Edit Actee");

		for (int j=0;j<objectFields.length;j++){
			String filedName = objectFields[j].getName();
			jc=new JLabel(filedName);
            field =objectFields[j];
            maximumSize = new Dimension(100, 30);
            jc.setMaximumSize(maximumSize);
            ofieldsPanel.add(jc);
            ob=null;
            try {
            	ob=objectFields[j].get(dmObj);
            }catch (IllegalAccessException excep){}

            tf=(ob==null)?(new JTextField("")):(new JTextField((String)ob));
            //if (j==0) tf.setEditable(false);
            if (filedName.equals("name")  ) tf.setEditable(false);
			maximumSize = new Dimension(100, 30);
            tf.setMaximumSize(maximumSize);            	    
            ofieldsPanel.add(tf);
            objectComps[j]=tf;

        }
         Dimension actPanelD= new Dimension(400,155);


        ofieldsPanel.setPreferredSize(actPanelD);
        ofieldsPanel.revalidate();
        
    	JOptionPane pane = new JOptionPane(ofieldsPanel,
    		JOptionPane.PLAIN_MESSAGE,JOptionPane.OK_CANCEL_OPTION);
    	objectDialog = pane.createDialog(MainFrame.mainFrame, "Edit domain object");
		objectDialog.show();
		Object selectedValue = pane.getValue();
		if (selectedValue != null && selectedValue != JOptionPane.UNINITIALIZED_VALUE){
			Integer sv = (Integer)selectedValue;
			
			if( sv.intValue()  == JOptionPane.OK_OPTION) {
				modifyObject(dmObj);
			}else {
			}
		}
        
    }
    public void  editObjectCombo(String name ){

    	DomainObject dmObj;
    	if (isDmObjKey(name))
    		dmObj= getDObject( name);
    	else {
    		dmObj=new DomainObject(name);
    		Manager.dmManager.register(name,dmObj);

    	}

    	objectFields=dmObj.getClass().getDeclaredFields();
        objectComps = new JComponent[objectFields.length];
        JPanel ofieldsPanel= new JPanel();
        ofieldsPanel.setLayout(new GridLayout(objectFields.length,2));
        Object ob;
        JComponent jc=null;
        Dimension maximumSize;
        JTextField tf;
        Field field;
		
		JComboBox cardinalityList = new JComboBox(CARDINALITY_CONTENTS);
        cardinalityList.addActionListener(new CardiActLis()) ;

		for (int j=0;j<objectFields.length;j++){
			String filedName = objectFields[j].getName();
			jc=new JLabel(filedName);
            field =objectFields[j];
            maximumSize = new Dimension(100, 30);
            jc.setMaximumSize(maximumSize);
            ofieldsPanel.add(jc);
            ob=null;
            try {
            	ob=objectFields[j].get(dmObj);
            }catch (IllegalAccessException excep){}
			if (filedName.equals("cardinality")  ){
				if (cardinalityMapping.containsKey((String)ob)){
					int in=((Integer)cardinalityMapping.get((String)ob)).intValue();
					cardinalityList.setSelectedIndex(in);
				}else cardinalityList.setSelectedIndex(0);
				
				cardinalityList.setMaximumSize(maximumSize);
				ofieldsPanel.add(cardinalityList);
            	objectComps[j]=cardinalityList;
			} else{
				
				tf=(ob==null)?(new JTextField("")):(new JTextField((String)ob));
				tf.setMaximumSize(maximumSize);
				ofieldsPanel.add(tf);
            	objectComps[j]=tf;
            	if (filedName.equals("name")  ) tf.setEditable(false);
			}
            
			//maximumSize = new Dimension(100, 30);
                        	    
            

        }
                    
        ofieldsPanel.revalidate();
        
    	JOptionPane pane = new JOptionPane(ofieldsPanel,
    		JOptionPane.PLAIN_MESSAGE,JOptionPane.OK_CANCEL_OPTION);
    	objectDialog = pane.createDialog(MainFrame.mainFrame, "Edit domain object");
		objectDialog.show();
		Object selectedValue = pane.getValue();
		if (selectedValue != null && selectedValue != JOptionPane.UNINITIALIZED_VALUE){
			Integer sv = (Integer)selectedValue;
			
			if( sv.intValue()  == JOptionPane.OK_OPTION) {
				modifyObject(dmObj);
			}else {
			}
		}
        
    }
    

    
 public void  modifyObject(DomainObject obj ){
 	//if (!(da instanceof DomainAction)) return;
 	
 	for (int i=0;i<objectFields.length;i++){
    	//String aFname=objectFields[i].getName();
    	String type=objectFields[i].getType().getName();
    	             
	  	if (type.equals("java.lang.String")){
	   		try{
	   	        //objectFields[i].set(obj,((JTextField)objectComps[i]).getText());
	   	        if (objectFields[i].getName().equals("documentation"))
	   	        	objectFields[i].set(obj,((JTextField)objectComps[i]).getText());
	   	        else if (objectFields[i].getName().equals("cardinality")){
	   	        	JComboBox cb=(JComboBox)objectComps[i];
        			String cardinality = (String)cb.getSelectedItem();

	   	        	objectFields[i].set(obj,cardinality);
	   	        }
	   	       	else 
	   	        	objectFields[i].set(obj,
	   	        		(((JTextField)objectComps[i]).getText()).toLowerCase());

	   	    } catch (Exception except){}
	    }else if (type.equals("int")){
	    	int nb=-1;
	        try {
	             nb=Integer.parseInt(((JTextField)objectComps[i]).getText());
	             if (nb<0) nb=-1;
	        } catch (NumberFormatException excep){}
	   	    try{
	   	          objectFields[i].setInt(obj,nb);
	  	    } catch (Exception except){}
	    }else if (type.equals("boolean")) {
	   	    try{
	   	        objectFields[i].setBoolean(obj,((AbstractButton)objectComps[i]).isSelected());
	   	     } catch (Exception except){}
	    }
 	}
 	
 }

 
 class DmActorD implements ActionListener {
 	public void actionPerformed(ActionEvent e){
 		
    	Field field;
    	for (int i=0;i<actionFields.length;i++){
    		try{
    		    field=actionFields[i];    		   
    		    if ((field.getName()).equals("actor")){
   	             	String actor=((JTextField)actionComp[i]).getText();   	             	
	    	        //editObject(actor); 
	    	        editObjectCombo(actor);
    		    return;
    		    }
    		    
    		}catch (Exception er){System.out.println("error");}
    	}
 	}
 }
        

 class DmActeeD implements ActionListener {
 	public void actionPerformed(ActionEvent e){
    	Field field;
    	for (int i=0;i<actionFields.length;i++){
    		try{
    		    field=actionFields[i];    		   
    		    if ((field.getName()).equals("actee")){
   	             	String actee=((JTextField)actionComp[i]).getText();   	             	
   	             //	String message = actee;
 				//	JOptionPane.showMessageDialog(MainFrame.mainFrame, actee,
	    	      //    	"Show dm object dialog", JOptionPane.WARNING_MESSAGE ); 
	    	        //editObject(actee); 
	    	        editObjectCombo(actee);
    		    return;
    		    }
    		    
    		}catch (Exception er){System.out.println("error");}
    	}
 	}
 }
    

 class DmActionParsing implements FocusListener {
 	public void focusGained(FocusEvent e){
			System.out.println("focusGained");
    
 	}
 	public void focusLost(FocusEvent e){
		System.out.println("focusLost");
 		parseUpdateActionFields();
 	}
 } 
 
 class CardiActLis implements ActionListener {
 	public void actionPerformed(ActionEvent e){
    	JComboBox cb = (JComboBox)e.getSource();
        String petName = (String)cb.getSelectedItem();
 	}
 }
 
 private void parseUpdateActionFields(){

		String sem="";
		for (int j=0;j<actionFields.length;j++){
			System.out.println("field length= "+ actionFields.length);
			String fieldName = actionFields[j].getName();
			System.out.println("focusLost"+ fieldName);

			if (fieldName.equals("name")){
				sem=(((JTextField)actionComp[j]).getText()).toLowerCase();
				if (oldActionName.equals(sem)) return;
				
				if (!parseSemanticsNotRegister(sem)) 
    	        	JOptionPane.showMessageDialog(MainFrame.mainFrame,
    	            	"Semantics should consist of 2 or more words!\nOtherwise no Domain Model instance will be created\n for this task.","Warning",
    	             	JOptionPane.WARNING_MESSAGE); 
			}
 		}
 		
    				
	    	for (int i=0;i<actionFields.length;i++){
				String fieldName = actionFields[i].getName();
				
				if (fieldName.equals("verb") ){
					String fieldValue = actionBuff.verb;  //(String)actionBuff.get("verb");
					((JTextField)actionComp[i]).setText(fieldValue);
				} else if (fieldName.equals("actee")){
					String fieldValue = actionBuff.actee; //(String)actionBuff.get("actee");
					((JTextField)actionComp[i]).setText(fieldValue);					
				} else if (fieldName.equals("proposition")){
					String fieldValue = actionBuff.proposition;  // (String)actionBuff.get("proposition");
					((JTextField)actionComp[i]).setText(fieldValue);	    				
	    	    } 
	    	}
	}
	
    public void  editActionFromHTMLview(String name ){
    	oldActionName =name;
    	if (isDmActionKey(name))
    		actionBuff= getDAction( name); 
    	else 	{
    		DomainAction da=new DomainAction(name);
    		actionBuff=da;
    		Manager.dmManager.register(name,da);

    	}
    	
        actionFields=actionBuff.getClass().getDeclaredFields();
        actionComp = new JComponent[actionFields.length];
        JPanel afieldsPanel= new JPanel();
        afieldsPanel.setLayout(new GridLayout(actionFields.length,3));
        Object ob;
        JComponent jc=null;
        Dimension maximumSize;
        JTextField tf;
        Field field;
        JButton actorB= new JButton("Edit Actor");
		JButton acteeB= new JButton("Edit Actee");

		for (int j=0;j<actionFields.length;j++){
			String filedName = actionFields[j].getName();
			jc=new JLabel(filedName);
            field =actionFields[j];
            maximumSize = new Dimension(100, 30);
            jc.setMaximumSize(maximumSize);
            afieldsPanel.add(jc);
            ob=null;
            try {
            	ob=actionFields[j].get(actionBuff);
            }catch (IllegalAccessException excep){}

            tf=(ob==null)?(new JTextField("")):(new JTextField((String)ob));
            //if (j==0) tf.setEditable(false);
            if (filedName.equals("verb") ||filedName.equals("actee")
            	||filedName.equals("proposition") ) tf.setEditable(false);
			maximumSize = new Dimension(100, 30);
            tf.setMaximumSize(maximumSize);            	    
            afieldsPanel.add(tf);
            actionComp[j]=tf;
            if ((field.getName()).equals("name")){
            	afieldsPanel.add(new JLabel(""));
				tf.addFocusListener(new DmActionParsing());
   	            
   	        } else if ((field.getName()).equals("actor")){
   	        	actorB.setMaximumSize(maximumSize); 
   	            actorB.addActionListener(new DmActorD());
   	            afieldsPanel.add(actorB);
                    
   	        } else if((field.getName()).equals("actee")){
   	        	acteeB.setMaximumSize(maximumSize); 
   	            acteeB.addActionListener(new DmActeeD());
   	            afieldsPanel.add(acteeB);
   	        } else afieldsPanel.add(new JLabel(""));

        }
        Dimension actPanelD= new Dimension(400,160);

        afieldsPanel.setPreferredSize(actPanelD);
        afieldsPanel.revalidate();
        
    	JOptionPane pane = new JOptionPane(afieldsPanel,
    		JOptionPane.PLAIN_MESSAGE,JOptionPane.OK_CANCEL_OPTION);
    	actionDialog = pane.createDialog(MainFrame.mainFrame, "Edit domain action");
    //	EditionDialog.dialog.hide();
		actionDialog.show();
		Object selectedValue = pane.getValue();
		if (selectedValue != null && selectedValue != JOptionPane.UNINITIALIZED_VALUE){
			Integer sv = (Integer)selectedValue;
			
			if( sv.intValue()  == JOptionPane.OK_OPTION) {
				parseUpdateActionFields();
				modifyActionFromHTMLView(actionBuff);
				
			}else {
				
				
				
				
			}
		}
	//	EditionDialog.dialog.show();
        
    }
    
 public void  modifyActionFromHTMLView(DomainAction da ){
 	//if (!(da instanceof DomainAction)) return;
 	
 	for (int i=0;i<actionFields.length;i++){
    	String aFname=actionFields[i].getName();
    	String type=actionFields[i].getType().getName();
    	             
	  	if (type.equals("java.lang.String")){
	   		try{
	   	        actionFields[i].set(da,((JTextField)actionComp[i]).getText());
	   	    } catch (Exception except){}
	    }else if (type.equals("int")){
	    	int nb=-1;
	        try {
	             nb=Integer.parseInt(((JTextField)actionComp[i]).getText());
	             if (nb<0) nb=-1;
	        } catch (NumberFormatException excep){}
	   	    try{
	   	          actionFields[i].setInt(da,nb);
	  	    } catch (Exception except){}
	    }else if (type.equals("boolean")) {
	   	    try{
	   	        actionFields[i].setBoolean(da,((AbstractButton)actionComp[i]).isSelected());
	   	     } catch (Exception except){}
	    }
 	}
 }


        
}

    class ModificationBackup extends TreeMap{
        public void addElement(String s1,String s2,String value){
        	String lCaseS1=s1.toLowerCase();
        	String lCaseS2=s2.toLowerCase();
        	String lCaseValue=value.toLowerCase();
            if (containsKey(lCaseS1)){
            	TreeMap map=(TreeMap)get(lCaseS1);
            	map.put(lCaseS2,value);
            }
            else {
            	TreeMap map=new TreeMap();
            	map.put(lCaseS2,value);
            	put(lCaseS1,map);
            }
        }
        public String modification(String s1,String s2){
        	String lCaseS1=s1.toLowerCase();
        	String lCaseS2=s2.toLowerCase();
			if (containsKey(lCaseS1)){
                TreeMap map=(TreeMap)get(lCaseS1);
                return (String)map.get(lCaseS2);
            } else return null;
        }



}
/*
    class ModificationBackup extends TreeMap{
        public void addElement(String s1,String s2,String value){
            if (containsKey(s1)){
            	TreeMap map=(TreeMap)get(s1);
            	map.put(s2,value);
            }
            else {
            	TreeMap map=new TreeMap();
            	map.put(s2,value);
            	put(s1,map);
            }
        }
        public String modification(String s1,String s2){
            if (containsKey(s1)){
                TreeMap map=(TreeMap)get(s1);
                return (String)map.get(s2);
            } else return null;
        }



}
*/