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

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;

import javax.swing.JCheckBox;

/**
 * @author Daniel Hakenjos
 * @version $Id: OperatorCheck.java,v 1.3 2006/04/11 14:10:16 euler Exp $
 */
public class OperatorCheck{
	
	private class CheckListener implements ItemListener{
		
		public CheckListener(){
		}
		
		public void itemStateChanged(ItemEvent e){

			if (cascading){
				setSelected(checkbox.isSelected());
			}

		}
	
	}
	
	private boolean isOperator,cascading;
	private String name;
	private Vector op_checks;
	private int depth;
	
	private OperatorCheck parent;
	
	private JCheckBox checkbox;

	/**
	 * Constructor for OperatorCheck.
	 */
	public OperatorCheck(String name, boolean isOperator, int depth, OperatorCheck parent) {
		this.isOperator=isOperator;
		this.cascading=true;
		this.name=name;
		if (!isOperator){
			this.op_checks=new Vector();
		}else{
			this.op_checks=null;
		}
		
		this.depth=depth;
		this.parent=parent;
		initComponents();
	}

	private void initComponents(){
		
		checkbox=new JCheckBox(name);
		checkbox.setSelected(false);
		checkbox.addItemListener(new CheckListener());

	}

	/**
	 * Is this <code>OperatorCheck for an operator?
	 * @return true, if it is for an operator<br>
	 * 		   false, if it is for a group of operators.
	 */
	public boolean isOperator(){
		return isOperator;
	}
	
	/**
	 * Gets the size.
	 */
	public int getOpChecksSize(){
		if (!this.isOperator){
			return this.op_checks.size();
		}
		return -1;
		
	}
	
	public OperatorCheck getOperatorCheck(int index){
		if ((index>=0)&&(index<op_checks.size())){
			return (OperatorCheck) op_checks.get(index);
		}
		return null;
	}
	
	/**
	 * Adds an <code>OperatorCheck</code> as child.
	 */
	public boolean addOperatorCheck(OperatorCheck check){
		if (!isOperator){
			this.op_checks.add(check);
		}
		return false;

	}
	
	/**
	 * Gets the name.
	 */
	public String toString(){
		return name;
	}
	
	/**
	 * Gets the name.
	 */
	public String getName(){
		return name;
	}
	
	/**
	 * A simple selection of this <code>OperatorCheck</code>.
	 */
	public void setSelectedSimple(boolean bool){
		setCascading(false);
		this.checkbox.setSelected(bool);
		setCascading(true);
	}
	
	/**
	 * Sets the selection without cascading.
	 */
	public void setSelected(boolean bool){
		this.checkbox.setSelected(bool);
		if ((bool==true)&&(parent!=null)){
			//alle Eltern muessen auch aktiviert werden aber nur die Eltern
			OperatorCheck p=this.parent;
			while (p!=null){
				p.setSelectedSimple(true);
				
				p=p.parent;
			}
		}
		
		if ((bool==false)&&(parent!=null)){
			//?berpr?fen, ob alle Geschwisterkinder auch deaktiviert sind
			// dann n?mlich auch die Eltern deaktivieren
			boolean activated=false;
			OperatorCheck ch;
			for (int i=0;((i<parent.op_checks.size())&&(!activated));i++){
				ch=(OperatorCheck) parent.op_checks.get(i);
				if (ch.isSelected()){
					activated=true;
				}
			}
			if (!activated){
				parent.setSelected(false);
			}
		}
		
		if (!isOperator){
			//Alle Kinder muessen aktiviert bzw. deaktiviert werden
			Vector allchecks=(Vector) op_checks.clone();
			
			OperatorCheck ch;
			while (allchecks.size()>0){
				ch=(OperatorCheck) allchecks.remove(0);
				ch.setSelectedSimple(bool);

				if (!ch.isOperator){
					for (int i=0;i<ch.op_checks.size();i++){
						allchecks.add(ch.op_checks.get(i));	
					}					
				}
			}
		}
	}
	
	/**
	 * Sets the selection with cascading.
	 */
	public void setSelectedCascading(boolean bool){
		this.checkbox.setSelected(bool);
		
		if (isOperator)
		return;

		if ((checkbox.isSelected())&&(parent!=null)){
			//Alle Eltern-Checkboxen muessen auch ausgew?hlt werden
			parent.setSelectedCascadingTop(true);
		}
		
		
			
		if ((!isOperator)&&(checkbox.isSelected())){
			//eine Gruppe wurde aktiviert -> also auch alle Kinder-Checkboxen aktivieren
			OperatorCheck ch;
			for (int i=0;i<op_checks.size();i++){
				ch=(OperatorCheck) op_checks.get(i);
				ch.setSelectedCascading(true);
			}
		}

		if ((!isOperator)&&(!checkbox.isSelected())){
			//eine Gruppe wurde deaktiviert -> also auch alle Kinder-Checkboxen deaktivieren
			OperatorCheck ch;
			for (int i=0;i<op_checks.size();i++){
				ch=(OperatorCheck) op_checks.get(i);
				ch.setSelectedCascading(false);
			}
		}
		
		if ((!checkbox.isSelected())&&(parent!=null)){
			//Gruppe oder Operator wurde deaktiviert -> also schauen ob alle Geschwister 
			//auch deaktiviert sind, dann Eltern-Checkbox auch deaktivieren
			
			boolean deactivated=true;
			OperatorCheck ch;
			for (int i=0;((i<parent.op_checks.size())&&(deactivated));i++){
				ch=(OperatorCheck) parent.op_checks.get(i);
				if (ch.isSelected()){
					deactivated=false;
				}
			}
			
			if (deactivated){
				parent.setSelectedCascading(false);
			}
		}
	}
	
	public void setSelectedCascadingTop(boolean bool){
		this.checkbox.setSelected(bool);
		this.parent.setSelectedCascadingTop(bool);
	}
	
	public void setSelectedCascadingDown(boolean bool){
	}

	/**
	 * Is this <code>Operatorcheck</code> selected.
	 */
	public boolean isSelected(){
		return this.checkbox.isSelected();
	}
	
	/**
	 * Checks wether something is selected.
	 * @return true, if at least 1 child is selected.
	 */
	public boolean isPartlySelected(){
		if (isOperator()){
			return isSelected();
		}

		boolean partly_selected=true;		
		OperatorCheck ch;
		for (int i=0;i<op_checks.size();i++){
			ch=(OperatorCheck) op_checks.get(i);
			if (ch.isPartlySelected())
				return true;
		}
		return false;		
		
	}
	
	/**
	 * Checks the selection of all childs.
	 * @return true, if all childs are selected.
	 */
	public boolean isAllSelected(){
		if (isOperator()){
			return isSelected();
		}

		OperatorCheck ch;
		for (int i=0;i<op_checks.size();i++){
			ch=(OperatorCheck) op_checks.get(i);
			if (!ch.isAllSelected())
				return false;
		}
		return true;		
	}
	
	/**
	 * Sets the cascading-flag.
	 */
	public void setCascading(boolean bool){
		this.cascading=bool;
	}	
	
	/**
	 * Gets the cascading-flag.
	 */
	public boolean getCascading(){
		return cascading;
	}
	
	/**
	 * Gets the <code>OperatorCheck</code>s-childs.
	 */
	public Vector getSubOperatorChecks(){
		return this.op_checks;
	}

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

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

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

*/
