/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.gui.stepsettings;

import java.awt.event.ActionEvent;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;

import org.musoft.limo.application.Resource;

import edu.udo.cs.miningmart.exception.M4Exception;
import edu.udo.cs.miningmart.gui.application.MiningMartApplication;
import edu.udo.cs.miningmart.m4.Concept;
import edu.udo.cs.miningmart.m4.M4Interface;
import edu.udo.cs.miningmart.m4.MultiColumnFeature;
import edu.udo.cs.miningmart.m4.OpParam;
import edu.udo.cs.miningmart.m4.utils.Print;

/**
 *An editor and renderer for multi-selection of <code>MultiColumnFeature</code>s.
 * @author Daniel Hakenjos
 * @version $Id: ListMCFeatureEditor.java,v 1.3 2006/04/11 14:10:13 euler Exp $
 */
public class ListMCFeatureEditor extends ListSelectEditor {
	
	private StepParameterTable table;
	
	private Vector features;

        /**
         *Construct a new <code>ListMCFeatureEditor</code>.
         */
	public ListMCFeatureEditor(MiningMartApplication app,StepParameterTable table, OpParam opParam){
		super(app,table.getTheStep(),opParam);
		this.table=table;

	}
	
	public void init(){
		super.init();
		try{
			this.selected_data=new String[0];

			Collection coll=getFeatureCollection();
			if (coll!=null){
				this.selected_data=new String[coll.size()];
				Iterator iter=coll.iterator();
				int index=0;
				while (iter.hasNext()){
//					if (opParam.isInput()){
						MultiColumnFeature mcfeat=(MultiColumnFeature) iter.next();
						String name=new String("");
						if (mcfeat.getConcept()!=null){
							name=mcfeat.getConcept().getName();
						}
						selected_data[index]=(mcfeat).getName()+" ["+name+"]";
/*					}else{
						selected_data[index]=(String) iter.next();
					}
*/					index++;
				}
			}
			setDataItems(selected_data);
		}catch(M4Exception error){
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
	}
	
	

	/**
	 * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		try{
			Collection conceptparams=step.getPossibleConceptsForParam(opParam);
			this.data=new String[conceptparams.size()];

			Iterator iter=conceptparams.iterator();
			int d=0;
			while (iter.hasNext()){
				data[d]=(String) iter.next();
				d++;
			}

			Collection concepts=new LinkedList();			
			for (int i=0;i<data.length;i++){
				concepts.addAll(table.getConceptEditorValues(data[i]));
			}


			Collection battribs=new LinkedList();
			iter=concepts.iterator();
			Concept concept;
			while (iter.hasNext()){
				concept=M4Interface.getCurrentCase().getConcept((String) iter.next());
				if (concept!=null){
					Collection c=concept.getAllMultiColumnFeatures();
					Iterator iter2=c.iterator();
					MultiColumnFeature feat;					
					while (iter2.hasNext()){
						feat=(MultiColumnFeature) iter2.next();
						if (step.isVisible(feat)){
							battribs.add(feat);
						}
					}
				}
			}

			this.data=new String[battribs.size()];
			
			iter=battribs.iterator();
			int c=0;
			MultiColumnFeature mcfeat;
			String name;
			while (iter.hasNext()){
				mcfeat=(MultiColumnFeature) iter.next();
				name=new String("");
				if (mcfeat.getConcept()!=null){
					name=mcfeat.getConcept().getName();
				}
				data[c]=mcfeat.getName()+" ["+name+"]";
				c++;
			}
	
			ListSelectDialog dialog=new ListSelectDialog(app,Resource.getString("STEPSETTINGS_TITLE_MCFEATURE"),Resource.getString("STEPSETTINGS_TITLE_SELECT_MCFEATURE"),data,selected_data,true,opParam.getMinArg(),opParam.getMaxArg());
			if (dialog.getExitAction()==ListSelectDialog.OK){
				selected_data=dialog.getSelectedDataItems();
				this.setDataItems(selected_data);

				LinkedList list=new LinkedList();
				for(int s=0;s<selected_data.length;s++){
					iter=battribs.iterator();
					MultiColumnFeature selectedMCF=null;
					boolean found=false;
					while ((iter.hasNext())&&(!found)){
						selectedMCF=(MultiColumnFeature) iter.next();
						name=new String("");
						if (selectedMCF.getConcept()!=null){
							name=selectedMCF.getConcept().getName();
						}
						if ((selectedMCF.getName()+" ["+name+"]").equals(selected_data[s])){
							found=true;
						}
					}
					if (found){
						list.add(selectedMCF);
					}
				}
				setParameterCollection(list);
				this.fireStateChanged();

			}
		}catch(M4Exception error){
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
	}

	private void initFeatures(){
		features=new Vector();
		numberofloops=step.getLoopCount();
		if (numberofloops==0){
			numberofloops=1;
		}

		try{
			Collection coll;
			for(int i=0;i<numberofloops;i++){
				if (opParam.isCoordinated()){
					//coordinierte Parameter so auslesen
					coll=step.getParameter(opParam,0);					
					if (coll==null)	coll=new LinkedList();
					features.add(coll);
				}else if ((opParam.isLoopable())&&(numberofloops==1)){
					//opParam ist loopable, mechanismus wird im step nicht genutzt
					coll=step.getParameter(opParam,0);					
					if (coll==null)	coll=new LinkedList();
					features.add(coll);
					
				}else if ((opParam.isLoopable())&&(numberofloops>1)){
					//opParam ist loopable, mechanismus wird im step genutzt
					//also auslesen von 1...numberofloops
					coll=step.getParameter(opParam,i+1);					
					if (coll==null)	coll=new LinkedList();
					features.add(coll);
					
				}else{
					coll=step.getParameter(opParam,0);					
					if (coll==null)	coll=new LinkedList();
					features.add(coll);
				}
			}
		}catch(M4Exception error){
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
		}
	}

	/* (non-Javadoc)
	 * @see edu.udo.cs.miningmart.gui.stepsettings.ParameterEditor#setParameterCollection(java.util.Collection, int)
	 */
	public void setParameterCollection(Collection collection, int loopnumber) {
		super.setParameterCollection(collection, loopnumber);
		boolean loopable=true;
		try{
			loopable=opParam.isLoopable();
		}catch(M4Exception error){
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			loopable=true;
		}

		if (features==null){
			initFeatures();
		}

		if (loopable){
			features.set(loopnumber-1, collection);
		}else{
			for(int i=0;i<paramcollections.size();i++){
				features.set(i, collection);
			}
		}
	}

	/**
	 * Gets the <code>Collection</code> of the Parameter for the specified loopnumber.
	 */
	private Collection getFeatureCollection(int loopnumber){
		boolean loopable=true;
		try{
			loopable=opParam.isLoopable();
		}catch(M4Exception error){
			M4Interface.print.doPrint(Print.ERROR,error.getMessage(),error);
			loopable=true;
		}
		if (features==null){
			initFeatures();
		}
		if (loopable){		
			return (Collection) features.get(loopnumber-1);
		}else{
			return (Collection) features.get(0);
		}
	}
	
	/**
	 * Gets the <code>Collection</code> for the current loopnumber.
	 */
	private Collection getFeatureCollection(){
		return getFeatureCollection(loopnumber);
	}
	
	/* (non-Javadoc)
	 * @see edu.udo.cs.miningmart.gui.stepsettings.ParameterEditor#makeOutput(boolean, boolean, boolean, boolean)
	 */
	public void makeOutput(boolean inputchanged,boolean outputchanged,boolean loopcountlower,	boolean loopcounthigher)	throws M4Exception {
		super.makeOutput(inputchanged,outputchanged,loopcountlower,loopcounthigher);
		initFeatures();
	}
	
	/* (non-Javadoc)
	 * @see edu.udo.cs.miningmart.gui.stepsettings.ParameterEditor#existsOutput()
	 */
	public boolean existsOutput() {
		if (opParam.isInput())
			return false;
	
		Collection coll;
		Collection actual;
		for(int loop=1;loop<=numberofloops;loop++){
			coll=(Collection) this.oldparamcollections.get(loop-1);
			actual=(Collection) this.paramcollections.get(loop-1);
			if (coll==null){
				return false;
			}
			if (coll.isEmpty()){
				return false;
			}
			if (actual==null){
				actual=new LinkedList();
			}
			if (coll.size()!=actual.size()){
				return false;
			}else{
				//pr\x{00FC}fe, ob die Namen passen
				Iterator iter=coll.iterator();
				while (iter.hasNext()){
					if (!actual.contains(iter.next())){
						return false;
					}
				}
			}
		}
			
		//gibt nur true zur?ck, wenn in allen loops die gleiche nicht leere Anzahl von Eintr\x{00E4}gen vorhanden ist und die Eintraege auch 
		//noch im Namen uebereinstimmen
		return true;
	}

	/* (non-Javadoc)
	 * @see edu.udo.cs.miningmart.gui.stepsettings.ParameterEditor#setNumberOfLoops(int)
	 */
	public void setNumberOfLoops(int numberofloops) {
		if (numberofloops==0){
			numberofloops=1;
		}
	
		if (features==null){
			initFeatures();
		}
		if (features.size()<numberofloops){
			while (features.size()!=numberofloops){
				features.add(new LinkedList());
			}
		}else if (features.size()>numberofloops){
			while (features.size()!=numberofloops){
				features.remove(paramcollections.size()-1);
			}
		}
	
		super.setNumberOfLoops(numberofloops);
	}

}
/*
$Log: ListMCFeatureEditor.java,v $
Revision 1.3  2006/04/11 14:10:13  euler
Updated license text.

Revision 1.2  2006/04/06 16:31:12  euler
Prepended license remark.

Revision 1.1  2006/01/03 09:54:15  hakenjos
Initial version!

*/
