/*
   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 domainModel.gui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.io.*;
import domainModel.*;
import taskModellingTool.*;


public class EntityPane extends JPanel {
	
  	private DmManager _dMM=Manager.getXDM().getDmManager();	// default _dMM 
 	private static DmRelation _dMRelat = DmRelation.getInstance();
	private EntityInstance _eIns;
	private static int NUMBER_OF_ROWS = 8;	//used by the Jlists
	private static int CELL_WIDTH = 200;	//used by the Jlists
	
	//define labels to be used in the dialod box 
	private static final String _name = "Name";
	private static final String _concept = "Concept";
	private static final String _dirty = "Dirty";
	private static final String _cardinality = "Cardinality";
	private static final String _prem = "Premodifier";
	private static final String _postm = "Postmodifier";
	private static final String _plural = "Plural";
	private static final String _note = "Comment";
	
	private JPanel _userPanel, _systemPanel, _thingPanel,
		_relnsPanel,_insPanel;
	private JList _userL, _systemL, _thingL;
	
	// put all entity concepts(including User and System types in _concepts
   	private JComboBox _conCm, _cardCm, _enInsCm;
	private JTabbedPane _tabPane;
	
  	private HashMap _indxIDRel; 	//  nested HashMap for pairs of index and ID 
  											//for relation instance
  	private HashMap _idIndxRel; 	//  nested HashMap for pairs of index and 
  											//ID for relation instance
  	private HashMap _RelCombos=new HashMap();
									 	//   HashMap for pairs of relation-name
  											// and comboBox
   	//define editable components
	private JTextField _nameT,_premT,_postmT;

   	//private JCheckBox _dirtyC;
   	private JTextArea _noteA;
   
   	//define popup menu	)
   	private JPopupMenu _popMenu = new JPopupMenu();
   	//private JPopupMenu _popList = new JPopupMenu();
  	private JMenuItem _userIn = new JMenuItem("Add New User Instance");
  	private JMenuItem _systemIn = new JMenuItem("Add New System Instance");
  	private JMenuItem _thingIn = new JMenuItem("Add New Thing Instance");
  
  	private JMenuItem _editIn = new JMenuItem("Edit");
  	private JMenuItem _deleteIn = new JMenuItem("Delete");
  	private JMenuItem _reset = new JMenuItem("Reset");
   	private JMenuItem _filter = new JMenuItem("Filter");
  
	public EntityPane(){
		super();
        //_popMenu.add(_popNew);    

        addMenuItemListener();	
		add(getRootPanel());
	}
	
	private void addMenuItemListener(){
	   _thingIn.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
	        	_dMM.newEIns();
				updateTab();
	      	}
	    });
    
	   _systemIn.addActionListener(new java.awt.event.ActionListener() {
		    public void actionPerformed(ActionEvent e) {
		        _dMM.newSIns();
				updateTab();
		    }
	    });
    
	   _userIn.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
	        	_dMM.newUIns();
	        	updateTab();

	      	}
	    });
    
	   _editIn.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
	      		editIns();
	      	}
	    });
    
	   _deleteIn.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
				deleteIns();	      
	      	}
	    });
    
	   _reset.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
				resetTabs();
	      	}
	    });
	    
	   _filter.addActionListener(new java.awt.event.ActionListener() {
	      	public void actionPerformed(ActionEvent e) {
				System.out.println( "\n selected filter menuItem");
	      	}
	    });
    
	}
	
	//
	private void deleteIns(){
		_dMM.removeEInstance(_eIns); 
		
		//update list
		updateTab();
	}
	
	private void updateTab(){
		if (_tabPane.getSelectedComponent().equals(_thingPanel)){
			setJlistContent(_thingL,  
				_dMM.getEiSome(ConceptType.getDefaultEntityType()));
		}else if (_tabPane.getSelectedComponent().equals(_systemPanel)){
			setJlistContent(_systemL,  
				_dMM.getEiSome(ConceptType.getDefaultSystemType()));
		}else{
			setJlistContent(_userL,  
				_dMM.getEiSome(ConceptType.getDefaultUserType()));			
		}
	}
	
	private void editIns(){
		if (_eIns != null){
			EInstanceEdit id = new EInstanceEdit(MainFrame.getMainFrame(),
				"Edit Entity Instance",_eIns);
		}
	}
	
	private void resetTabs(){
		setJlistContent(_thingL,  
			_dMM.getEiSome(ConceptType.getDefaultEntityType()));
		setJlistContent(_systemL,  
			_dMM.getEiSome(ConceptType.getDefaultSystemType()));
		setJlistContent(_userL,  
			_dMM.getEiSome(ConceptType.getDefaultUserType()));
	}
	
	private JPanel getRootPanel(){
		JPanel rootPanel= new JPanel();
		//Dimension PanelD= new Dimension(200,100);
		
       	rootPanel.setLayout(new BorderLayout());
		rootPanel.add(new JLabel("Entity Instance"),
			BorderLayout.NORTH);
     	rootPanel.add(getTabPanel(),BorderLayout.CENTER);
    	rootPanel.add(getInsPanel(),BorderLayout.SOUTH);
      	rootPanel.setPreferredSize(rootPanel.getPreferredSize());
		return rootPanel;	
	}
	
	private JTabbedPane getTabPanel(){
		_tabPane= new JTabbedPane();
		// Add the different tabs 
		_tabPane.addTab(DmConcept.getDefaultEntityConcept().getName(),
			null, getEntityTab());
		_tabPane.addTab(EntityInstance.getDefaultSystemInstance().getName(),
			null, 	getSystemTab());
		_tabPane.addTab(EntityInstance.getDefaultUserInstance().getName(),
			null, getUserTab());
	//	_tabPane.setSize(_tabPane.getMaximumSize());
		
		//add listener
		_tabPane.addChangeListener(tabListener);
		
     	return _tabPane;	
      
	}
	
	ChangeListener tabListener = new ChangeListener(){
		public void stateChanged(ChangeEvent e) {
			JPanel jp = (JPanel)_tabPane.getSelectedComponent();
			
			// save change, if any
			storeChange();
			
			if (jp.equals(_userPanel)){
				selectUser();
			}else if (jp.equals(_systemPanel)){
				selectSystem();
			}else{
				selectThing();
			}
		}
	};
	
	private JPanel getUserTab(){
		_userPanel= new JPanel();
		_userL = new JList();
		setJlistContent(_userL,  
			_dMM.getEiSome(ConceptType.getDefaultUserType()));
			
		//_userPanel.add(_userL);
		
		JScrollPane scrollP= new JScrollPane(_userL);
     	scrollP.setHorizontalScrollBarPolicy(
          JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);	//	_NEVER);
     	scrollP.setVerticalScrollBarPolicy(
          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
			
		_userPanel.add(scrollP);
		_userL.setVisibleRowCount(NUMBER_OF_ROWS);
		_userL.setFixedCellWidth(CELL_WIDTH);

		_userL.addListSelectionListener(userListener);
		
		_userL.addMouseListener(popupListener);		
		_userPanel.addMouseListener(popupListener);
		return _userPanel;	
	}
	
	ListSelectionListener userListener = new ListSelectionListener(){
		public void valueChanged(ListSelectionEvent e) {
			storeChange();
			selectUser();
		}
	};
	
	MouseListener popupListener = new MouseAdapter(){
    	public void mousePressed(MouseEvent e) {
			maybeShowPopup(e);
		}	

		public void mouseReleased(MouseEvent e) {
		  	maybeShowPopup(e);
		}
		
		public void maybeShowPopup(MouseEvent e) {
			
			if (e.isPopupTrigger()) {
		      	//System.out.println( "\n right mouse button pressed");
				constructMenu();
		        _popMenu.show(e.getComponent(),
		        e.getX(), e.getY());
		    }
		}

	};
	
	private void constructMenu(){
		if (_tabPane.getSelectedComponent().equals(_thingPanel)){
			_popMenu.removeAll();    
			_popMenu.add(_thingIn);
			addCommonMenuItem();
		}else if (_tabPane.getSelectedComponent().equals(_systemPanel)){
			_popMenu.removeAll();    
			_popMenu.add(_systemIn);    
			addCommonMenuItem();
		}else{
			_popMenu.removeAll();    
			_popMenu.add(_userIn);    
			addCommonMenuItem();
		}
		return;	
	}
	private void addCommonMenuItem(){
		if (_eIns == null){
	        _popMenu.add(new JPopupMenu.Separator());    
			_popMenu.add(_reset);  
		
		}else{
	        _popMenu.add(new JPopupMenu.Separator());    
			_popMenu.add(_editIn);
			_popMenu.add(_deleteIn);    
			_popMenu.add(_reset);  
	        _popMenu.add(new JPopupMenu.Separator());    
			_popMenu.add(_filter);
		}
		return;
	}
	private void selectUser(){
		String eiName = (String)_userL.getSelectedValue();
		updateIns(eiName,ConceptType.getDefaultUserType());
	}
	
	private void selectSystem(){
		String eiName = (String)_systemL.getSelectedValue();
		updateIns(eiName,ConceptType.getDefaultSystemType());
	}
	
	
	private void selectThing(){
		String eiName = (String)_thingL.getSelectedValue();
		updateIns(eiName,ConceptType.getDefaultEntityType());
	}
	
	public void updateIns(String eiName, String type){
		if (eiName == null){
			setFieldsContent(null, type);
			setRelationContent(null);
			_eIns = null;
		} else {
			EntityInstance ei = _dMM.getEi(eiName, type);
			_eIns = ei;
			setFieldsContent(ei, type);
			setRelationContent(ei);
		}
		//refresh();
	}
/*
	private void refresh(){
		// _nameT,_premT,_premT;_noteA  _conCm, _cardCm
		_nameT.paintImmediately(_nameT.getBounds());
		_premT.paintImmediately(_premT.getBounds());
		_postmT.paintImmediately(_postmT.getBounds());
		_noteA.paintImmediately(_noteA.getBounds());
		_conCm.paintImmediately(_conCm.getBounds());
		_cardCm.paintImmediately(_cardCm.getBounds());
		
	}
*/	
	private JPanel getSystemTab(){
		_systemPanel= new JPanel();
		_systemL = new JList();
		setJlistContent(_systemL,  
			_dMM.getEiSome(ConceptType.getDefaultSystemType()));
			
		JScrollPane scrollP= new JScrollPane(_systemL);
     	scrollP.setHorizontalScrollBarPolicy(
          JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);	//	_NEVER);
     	scrollP.setVerticalScrollBarPolicy(
          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
                   
		_systemPanel.add(scrollP);
		_systemL.setVisibleRowCount(NUMBER_OF_ROWS);
		_systemL.setFixedCellWidth(CELL_WIDTH);
		_systemL.addListSelectionListener(systemListener);
		
		_systemL.addMouseListener(popupListener);		
		_systemPanel.addMouseListener(popupListener);
		return _systemPanel;	
	}

	
	ListSelectionListener systemListener = new ListSelectionListener(){
		public void valueChanged(ListSelectionEvent e) {
			storeChange();
			selectSystem();
		}
	};
	
	private JPanel getEntityTab(){
		_thingPanel= new JPanel();
		_thingL = new JList();
		setJlistContent(_thingL,  
			_dMM.getEiSome(ConceptType.getDefaultEntityType()));
					
		JScrollPane scrollP= new JScrollPane(_thingL);
     	scrollP.setHorizontalScrollBarPolicy(
          JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);	//	_NEVER);
     	scrollP.setVerticalScrollBarPolicy(
          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
          
		_thingPanel.add(scrollP);
		//	_thingL.setSize(_thingL.getMaximumSize());
		_thingL.setVisibleRowCount(NUMBER_OF_ROWS);
		_thingL.setFixedCellWidth(CELL_WIDTH);

		_thingL.addListSelectionListener(thingListener);
		
		_thingL.addMouseListener(popupListener);		
		_thingPanel.addMouseListener(popupListener);

		return _thingPanel;	
	}
	
	ListSelectionListener thingListener = new ListSelectionListener(){
		public void valueChanged(ListSelectionEvent e) {
			storeChange();
			selectThing();
		}
	};
	
	/** remove all content for list if there is any,
	* then populate list with user
	*/
	public void setJlistContent(JList list, Collection user ){
		list.removeAll(); 
		Iterator it = user.iterator();
		EntityInstance ei;
		DefaultListModel model = new DefaultListModel();

		while (it.hasNext()){
			ei = (EntityInstance)it.next();
			model.addElement(ei.getName());
		}
		list.setModel(model);
		return;	
	}

	private JPanel getInsPanel(){
		_insPanel= new JPanel();
       	_insPanel.setLayout(new BorderLayout());
     	//insPanel.setLayout(new GridLayout(3,1));
       	_insPanel.add(getFieldsPanel(),BorderLayout.NORTH);
      	_insPanel.add(getRelationPanel(),BorderLayout.CENTER);
     	_insPanel.add(getNotePanel(),BorderLayout.SOUTH);
		return _insPanel;	
	}

	private JPanel getFieldsPanel(){
		JPanel fieldsPanel= new JPanel();
		
      	fieldsPanel.setLayout(new GridLayout(6,2));
      	//add 1 empty row
      	fieldsPanel.add(new JLabel());
      	fieldsPanel.add(new JLabel(" "));

      	fieldsPanel.add(new JLabel(_name));
     	_nameT = new JTextField();
      	fieldsPanel.add(_nameT);
      
      	//initialize concept Combon box
      	fieldsPanel.add(new JLabel(_concept));
      	_conCm = new JComboBox();
	  	fieldsPanel.add(_conCm);

	  	fieldsPanel.add(new JLabel(_cardinality));
      	_cardCm = new JComboBox();
      	fieldsPanel.add(_cardCm);
		
      	fieldsPanel.add(new JLabel(_prem));
     	_premT = new JTextField(); 	//_eIns.getPreModifier());
      	fieldsPanel.add(_premT);
		
      	fieldsPanel.add(new JLabel(_postm));
     	_postmT = new JTextField(); 	//_eIns.getPostModifier());
      	fieldsPanel.add(_postmT);
		
     	return fieldsPanel;	
		
	}
	
	public void setFieldsContent(EntityInstance ei, String type){
		if (ei == null)
			clearFieldsContent();
		else{
			//clearFieldsContent();
			
			_nameT.setText(ei.getName());
			
			DefaultComboBoxModel mod1= new DefaultComboBoxModel();
			Iterator it = _dMM.getConceptSome(type).iterator();
	      	while ( it.hasNext()) {
	      		mod1.addElement(((DmConcept)it.next()).getName());
	      	}
      		_conCm.setModel(mod1);

			_conCm.setSelectedItem(ei.getConceptOf().getName());
			
			DefaultComboBoxModel mod= new DefaultComboBoxModel(
					EntityInstance.getCardinalityAll());
      		_cardCm.setModel(mod);
   			_cardCm.setSelectedItem(ei.getCardinality());
   			
   			String pre = ei.getPreModifier();
   			if (pre == null || pre.equals(""))
				_premT.setText(" ");
			else 
				_premT.setText(pre);
				
   			String post = ei.getPostModifier();
   			if (post == null || post.equals(""))
				_postmT.setText(" ");
			else 
				_postmT.setText(post);
				
   			String note = ei.getNote();
   			if (note == null || note.equals(""))
				_noteA.setText(" ");
			else 
				_noteA.setText(note);
		
		}
	}
	
	
	private void clearFieldsContent(){
		_nameT.setText(" ");
		DefaultComboBoxModel mod= new DefaultComboBoxModel();
		_conCm.setModel(mod);
		_cardCm.setModel(mod);
		_premT.setText(" ");
		_postmT.setText(" ");
		_noteA.setText(" ");
	}
	
	private JPanel getNotePanel(){
		JPanel notePanel= new JPanel();
		
		//Dimension notePanelD= new Dimension(200,100);
      //	notePanel.setPreferredSize(notePanelD);
      
      	notePanel.setLayout(new BorderLayout());
							//new GridLayout(2,1));
		
    	notePanel.add(new JLabel(_note),BorderLayout.NORTH);
     	_noteA = new JTextArea();
     	_noteA.setRows(4);	//4 rows of text
     	
     	//add default keymap to the textarea, so that Ctrl-c and v can
     	// be used for copy and past
     	
     	JTextField tf= new JTextField();
     	_noteA.setKeymap(tf.getKeymap());
     	
     	JScrollPane scrollP= new JScrollPane(_noteA);
     	scrollP.setHorizontalScrollBarPolicy(
          JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
     	scrollP.setVerticalScrollBarPolicy(
          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
          
      	notePanel.add(scrollP, BorderLayout.CENTER);
     	
      	//notePanel.add(_noteA, BorderLayout.CENTER);
      	
     	return notePanel;	
      
	}
	
	
	private JPanel getRelationPanel(){
		_relnsPanel= new JPanel();
   		_indxIDRel = new HashMap();
   		_idIndxRel = new HashMap(); 
		
		
      	String allEnRle[] = _dMRelat.getAllEntityRelations();
      	int numberRel =allEnRle.length; 
      	_relnsPanel.setLayout(new GridLayout(numberRel,2));
      	String relName;
	//	TreeMap reEnInstances = _eIns.getEntityRelations();    
		for (int j = 0; j < numberRel; j++) {
			relName = allEnRle[j];
      		_indxIDRel.put(relName,new HashMap() );
      		_idIndxRel.put(relName,new HashMap() );;
			_relnsPanel.add(new JLabel(relName));
			_relnsPanel.add(getEInsCm(relName));
		}
    	
    	return _relnsPanel;
      
	}
	
	public void setRelationContent(EntityInstance ei){
		_indxIDRel = new HashMap();
   		_idIndxRel = new HashMap(); 
      	String allEnRle[] = _dMRelat.getAllEntityRelations();
      	int numberRel =allEnRle.length;
	    String relName;
	    
		if (ei == null){
			for (int j = 0; j < numberRel; j++) {
				relName = allEnRle[j];
				clearEiRelInsContent(relName);
	    	}
		}
		else{

			TreeMap reEnInstances = ei.getEntityRelations();    
			for (int j = 0; j < numberRel; j++) {
				relName = allEnRle[j];
	      		_indxIDRel.put(relName,new HashMap() );
	      		_idIndxRel.put(relName,new HashMap() );;
				setEiRelInsContent(relName,
					(EntityInstance)reEnInstances.get(relName));
				
	    	}
		}
	}
	
	private JPanel getRelPanel(){
		JPanel _relnsPanel= new JPanel();
    	return _relnsPanel;
      
	}
	
	private JComboBox getEInsCm(String relName ){
    	JComboBox tempCm = new JComboBox();
	    _RelCombos.put(relName,tempCm);
		return tempCm;
	}
	
	
	public void setEiRelInsContent(String relName,EntityInstance en){
		JComboBox tempCm= (JComboBox)_RelCombos.get(relName);
		if ( tempCm == null)
			return;
			
	//    Iterator it = _dMM.getEInstanceAll().iterator();
	    EntityInstance temp ;
	   	HashMap tempInxId = (HashMap)_indxIDRel.get(relName );
	   	HashMap tempIdInx = (HashMap)_idIndxRel.get(relName );
	   	
		DefaultComboBoxModel mod= new DefaultComboBoxModel();
		
		int i= 1; 	// if no relation instance select "None"
		mod.addElement("");
	    Iterator it = _dMM.getEInstanceAll().iterator();
      	while ( it.hasNext()) {
      		temp = (EntityInstance)it.next();
      		mod.addElement(temp.getName());
	      	tempInxId.put(Integer.toString(i),temp.getID() );
	      	tempIdInx.put(temp.getID(),Integer.toString(i++) );
      	}
      	tempCm.setModel(mod);
      	
		i= 0; 	// if no relation instance select "None"
      	if (en != null)
      		i= Integer.parseInt((String)tempIdInx.get(en.getID()));
      		
      	tempCm.setSelectedIndex(i);

	    	      
		return;  	
	}
	
	public void clearEiRelInsContent(String relName){
		JComboBox tempCm= (JComboBox)_RelCombos.get(relName);
		if ( tempCm == null)
			return;
		DefaultComboBoxModel mod= new DefaultComboBoxModel();
  		tempCm.setModel(mod);	      	
	    	      
		return;  	
	}
	
	private void storeChange(){
		// update Enttity instance attributes
		if (_eIns == null) return;
		
     	_eIns.setName(_nameT.getText());
     	String ConceptName= (String)_conCm.getSelectedItem();
     	_eIns.setConceptOf(_dMM.getEConceptAny(ConceptName));
     //	_eIns.setDirty(_dirtyC.isSelected());
     	String cardi= (String)_cardCm.getSelectedItem();
     	_eIns.setCardinality(cardi);
     	_eIns.setPreModifier(_premT.getText());
     	_eIns.setPostModifier(_postmT.getText());

     	_eIns.setNote(_noteA.getText());
        updateRel();
      //2001-2-14
      // mark related task dirty
      DmManager.getInstance().markTaskDirty(_eIns);
	}
	
	
	private void updateRel(){
      String allActRle[] = _dMRelat.getAllEntityRelations();
      int numberRel =allActRle.length; 
      String relName;
	//	TreeMap reActInstances = _eIns.getEntityRelations();    
		for (int j = 0; j < numberRel; j++) {
			relName = allActRle[j];
			//get selected instance index
			JComboBox tempCm =(JComboBox)_RelCombos.get(relName);
			if (tempCm == null)
				continue;
			
			int indexSelect = tempCm.getSelectedIndex();
			
			if (indexSelect == 0){
				_eIns.setEntityRelation(relName,null);
				continue;

			}
			//get selected instance ID
			HashMap tempHM= (HashMap) _indxIDRel.get(relName);
			String tempID  = (String)	tempHM.get(Integer.toString(indexSelect));
			System.out.println( "\n realtion : "+ relName+ " index =" +indexSelect
						+ " ID =" + tempID);

			EntityInstance tempEn = _dMM.getEInstance(tempID);
			
			//update the content of the relation related instsance
			if (tempEn != null){
				_eIns.setEntityRelation(relName,tempEn);
			}
    	}
    }	
}