/*
 * 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.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;

import org.jhotdraw.util.Iconkit;
import org.musoft.limo.application.Resource;

import edu.udo.cs.miningmart.exception.M4Exception;
import edu.udo.cs.miningmart.m4.M4Interface;
import edu.udo.cs.miningmart.m4.Operator;
import edu.udo.cs.miningmart.m4.OperatorGroup;
import edu.udo.cs.miningmart.m4.utils.Print;

/**
 * A <code>PreferencesPanel</code> for the operators.
 * @author Daniel Hakenjos
 * @version $Id: OperatorPreferencesPanel.java,v 1.3 2006/04/11 14:10:16 euler Exp $
 */
public class OperatorPreferencesPanel extends PreferencesPanel {

	private MiningMartApplication app;

	//Objecte vom Typ OperatorCheck
	private Vector op_checks;
	private int size;

	private JPanel gridpanel;
	private JScrollPane scrollpane;
	private JTree jtree;

	/**
	 * Constructor for OperatorPreferencesPanel.
	 */
	public OperatorPreferencesPanel(MiningMartApplication app) {
		super();
		this.app = app;
		this.size = 0;
		op_checks = new Vector();
		initComponents();
	}

	private void initComponents() {
		createOpChecksVector();

		gridpanel = new JPanel();
		gridpanel.setLayout(new GridLayout(size, 1));

		DefaultMutableTreeNode top =
			new DefaultMutableTreeNode(
				new OperatorCheck(Resource.getString("OPERATORS"), false, 0, null),
				true);
		createTreeNodes(top);
		jtree = new JTree(top);
		jtree.setRootVisible(true);
		jtree.setVisibleRowCount(1);		
		MyMouseListener mm=new MyMouseListener();
		
		MyTreeCellRenderer treecellrenderer = new MyTreeCellRenderer();
		jtree.addMouseListener(mm);
		jtree.setCellRenderer(treecellrenderer);

		scrollpane = new JScrollPane(jtree);

		this.setLayout(new BorderLayout());
		this.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		this.add(scrollpane, BorderLayout.CENTER);

	}

	private void createTreeNodes(DefaultMutableTreeNode top) {
		Object[] objects=new Object[this.op_checks.size()];		
		OperatorCheck check;
		for (int i = 0; i < this.op_checks.size(); i++) {
			check = (OperatorCheck) op_checks.get(i);
			createTreeNode(top,check);
		}
	}

	private void createTreeNode(
		DefaultMutableTreeNode top,
		OperatorCheck check) {
		DefaultMutableTreeNode treenode =
			new DefaultMutableTreeNode(check, !check.isOperator());
		top.add(treenode);

		for (int i = 0; i < check.getOpChecksSize(); i++) {
			createTreeNode(treenode, check.getOperatorCheck(i));
		}
	}

	private void createOpChecksVector() {
		M4Interface m4i = M4Interface.getInstance();
		boolean success = true;
		if (m4i != null) {
			OperatorGroup opg = m4i.getOperatorGroup();
			Iterator it = opg.getTopLevelOperatorGroups().iterator();
			while (it.hasNext()) {
				Long opgId = (Long) it.next();
				try {
					this.op_checks.add(
						recurseThroughInsertOps(opgId, opg, 0, null));
					size++;
				} catch (M4Exception e) {
					M4Interface.print.doPrint(Print.ERROR,e.getMessage(),e);
					success = false;
				}
			}
		}
	}

	private OperatorCheck recurseThroughInsertOps(
		Long opGroupId,
		OperatorGroup opg,
		int depth,
		OperatorCheck parent)
		throws M4Exception {
		// the opGroupId belongs to an operator group (inner node), so just create
		// an according folder:
		//String name = opg.getGroupName(opGroupId);
		//IconCommandMenu cclist = this.getInsertItemFolder(name);

		// Iterate through the contained elements:
		Collection col = opg.getChildGroups(opGroupId);
		Iterator it = col.iterator();
		String name = opg.getGroupName(opGroupId);
		OperatorCheck check = new OperatorCheck(name, false, depth, parent);
		check.setSelected(isPreferenced(check));

		while (it.hasNext()) {
			Long idNext = (Long) it.next();

			// Test whether idNext represents an inner node or an operator:
			Collection down = (Collection) opg.getChildGroups(idNext);
			if (down != null) {
				// "down" represents an inner node, recurse!
				OperatorCheck ch2 =
					this.recurseThroughInsertOps(idNext, opg, depth + 1, check);
				ch2.setSelected(isPreferenced(ch2));
				check.addOperatorCheck(ch2);
				size++;
			} else {
				// "down" represents an operator, just add it to the folder!
				Operator op = (edu.udo.cs.miningmart.m4.Operator) opg.getOperator(idNext);
				if (op != null) {
					String opName = op.getName();
					OperatorCheck ch =
						new OperatorCheck(opName, true, depth + 1, check);
					ch.setSelected(isPreferenced(ch));
					check.addOperatorCheck(ch);
					size++;
				}
			}
		}

		return check;
	}

	private boolean isPreferenced(OperatorCheck check) {
		Vector ops = app.getOperatorsInToolPanel();
		if (ops.contains(check.getName().toLowerCase())) {
			return true;
		}
		return false;
	}

	private Vector getOpsChecked() {
		Vector ops = new Vector();
		Vector allchecks = (Vector) this.op_checks.clone();
		OperatorCheck ch;
		while (allchecks.size() > 0) {
			ch = (OperatorCheck) allchecks.remove(0);
			if (ch.isSelected()) {
				ops.add(ch.getName().toLowerCase());
			}
			if (!ch.isOperator()) {
				Vector children = ch.getSubOperatorChecks();
				for (int i = 0; i < children.size(); i++) {
					allchecks.add(children.get(i));
				}
			}
		}
		return ops;
	}

	public void actionSave() {
		//Hier muessen die Eingaben in die Datei geschrieben werden.
		app.setOperatorInToolPanel(getOpsChecked());
		app.saveParams();
		app.refreshOperatorToolPanel();
	}

	public void actionOK() {
		//Aenderungen einfach uebernehmen ohne speichern
		//Ein Speichern erfolgt dann erst beim Beenden des Programms  
		app.setOperatorInToolPanel(getOpsChecked());
		app.refreshOperatorToolPanel();
	}

	public void actionCancel() {
		//Nothing todo here
	}

	private class MyMouseListener extends MouseAdapter{
		public void mouseClicked(MouseEvent e){
			int selRow = jtree.getRowForLocation(e.getX(), e.getY());
         	TreePath selPath = jtree.getPathForLocation(e.getX(), e.getY());

			DefaultMutableTreeNode node=null;
			if (selPath!=null)
				node=(DefaultMutableTreeNode) selPath.getLastPathComponent();

			OperatorCheck check=null;
			if (node!=null)
				check= (OperatorCheck) node.getUserObject();

			if (check!=null){
				if (check.isAllSelected()){
					check.setSelected(false);
				}else{
					check.setSelected(true);
				}
			}
			jtree.repaint();
		}
	}

	private class MyTreeCellRenderer extends DefaultTreeCellRenderer {

		private Icon op_selected, op_notselected;
		private Icon group_notselected,
			group_partly_selected,
			group_allselected;
		private Icon ops;

		public MyTreeCellRenderer() {
			Iconkit kit = Iconkit.instance();

			op_selected =
				new ImageIcon(
					kit.loadImageResource(Resource.getString("OP_SELECTED")));
			op_notselected =
				new ImageIcon(
					kit.loadImageResource(
						Resource.getString("OP_NOT_SELECTED")));
			group_notselected =
				new ImageIcon(
					kit.loadImageResource(
						Resource.getString("GROUP_NOT_SELECTED")));
			group_partly_selected =
				new ImageIcon(
					kit.loadImageResource(
						Resource.getString("GROUP_PARTLY_SELECTED")));
			group_allselected =
				new ImageIcon(
					kit.loadImageResource(
						Resource.getString("GROUP_ALL_SELECTED")));
			ops =
				new ImageIcon(
					kit.loadImageResource(
						Resource.getString("CaseIcon")));

		}

		public Component getTreeCellRendererComponent(
			JTree tree,
			Object value,
			boolean sel,
			boolean expanded,
			boolean leaf,
			int row,
			boolean hasFocus) {

			DefaultMutableTreeNode treenode = (DefaultMutableTreeNode) value;
			OperatorCheck check = (OperatorCheck) treenode.getUserObject();

			super.getTreeCellRendererComponent(
				tree,
				value,
				sel,
				expanded,
				leaf,
				row,
				hasFocus);
				
			if (treenode.isRoot()){
				setIcon(ops);
				return this;
			}
			if (leaf) {
				if (check.isSelected()) {
					setIcon(op_selected);
				} else {
					setIcon(op_notselected);
				}
			} else {
				if (check.isAllSelected()) {
					setIcon(group_allselected);
				} else if (check.isPartlySelected()) {
					setIcon(group_partly_selected);
				} else {
					setIcon(group_notselected);
				}
			}
			
			return this;
		}

	}
}
/*
$Log: OperatorPreferencesPanel.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:26  hakenjos
Initial version!

*/
