package de.dass_it.vanhelsing.gui;

//import org.apache.log4j.Logger;
import java.lang.reflect.Method;

import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import de.dass_it.vanhelsing.gui.items.*;
import de.dass_it.www.vanhelsing.*;
import de.dass_it.www.vanhelsing.VanHelsingCallbackHandler.*;
import de.dass_it.www.vanhelsing.VanHelsingStub.*;

/*
 * Helper class to encapsulate all procedures 
 * to work with the tree structure.
 */
public class TreeNavigation extends BeanUtil {
	private DefaultTreeModel tree;
	//private Logger logger = Logger.getLogger(this.getClass());
	public DefaultTreeModel createTree(DefaultMutableTreeNode root, 
			String[] nodes, String title){
		
		DefaultMutableTreeNode node;
		DefaultMutableTreeNode myNode;
		tree = new DefaultTreeModel(root);
		UserObjectItemType item = new UserObjectItemType(root);
		UserObjectItem uoi = new TreeItem("Configuration");
		uoi.setResType("Tree");
		item.setUserObjectItem(uoi);
		root.setUserObject(item);
		
		for(int i = 0; i< nodes.length; i++){
			//root.add(addNode(root, "Tree", nodes[i]));
			myNode = null;
			myNode = addNode(root, nodes[i], nodes[i]);
			if (myNode != null){
				root.add(myNode);
			}
		}
		return tree;
	}
	
	public DefaultMutableTreeNode addNode(DefaultMutableTreeNode parent, String type, String title){
		DefaultMutableTreeNode node = new DefaultMutableTreeNode();
		Class subClass;
		Class myClass;
		Method[] methods;
		Object o;
		UserObjectItemType userObject = new UserObjectItemType(node);
		String type2 = "de.dass_it.vanhelsing.gui.items." + type + "Item";
		
		try {
			subClass = Class.forName(type2);
			o = subClass.newInstance();
			UserObjectItem item = (UserObjectItem) o;
			item.setResType(type);
			myClass = item.getClass().asSubclass(subClass);		
			methods = myClass.getMethods();
			for (Method m : methods){
				//System.err.println(m.getName());
				if(m.getName().contains("setValue")){
					m.invoke(item, title);
				}
			}
			//ItemObjekt erzeugen und an das UserObjekt referenzieren
			userObject.setUserObjectItem((UserObjectItem)o);
			//Eine Referenz auf das UserObjekt wird an das Nodeobjekt übergeben
			node.setUserObject(userObject);
			return node;
		} catch (ClassNotFoundException e1){
			System.err.println("Itemclass "+ type2 +" must be in the classpath");
		} catch (InstantiationException e2){
			System.err.println("Class "+type2+" must be a concrete class, not an interface or an abstract class");
		} catch (IllegalAccessException e3){
			System.err.println("Class " + type2 + " lacks a no-argument constructor");
		} catch (Exception e){
			System.err.println(e.toString());
		}
		
		return null;
	}
  	public DefaultMutableTreeNode addNode(DefaultMutableTreeNode parent, String type, ResourceInfo ri){
		DefaultMutableTreeNode node = new DefaultMutableTreeNode();
		Class subClass;
		Class myClass;
		Method[] riMethods;
		Method[] methods;
		Object o;
		UserObjectItemType userObject = new UserObjectItemType(node);
		String type2 = "de.dass_it.vanhelsing.gui.items." + type + "Item";
		
		try {
			subClass = Class.forName(type2);
			o = subClass.newInstance();
			UserObjectItem item = (UserObjectItem) o;
			item.setResType(type);
			myClass = item.getClass().asSubclass(subClass);		
			methods = myClass.getMethods();
			;
			/*for (Method m : methods){
				if(m.getName().contains("set" + p)){
					m.invoke(item, title);
				}
			}*/
			for (Method n : ri.getClass().getDeclaredMethods()){
				if (n.getName().startsWith("get") 
						&& !(n.getName().contains("OMElement") || n.getName().contains("PullParser"))){
						
					//System.err.println("Name: " + n.getName() +" Feld: "+ n.getName().substring(3));
					for (Method m : methods){
						if (m.getName().equals("set"+n.getName().substring(3))){
							m.invoke(item, n.invoke(ri, (Object[])null));
							break;
						}
					}
					
				
				}
				
			}
			//Value-Wert für die TreeView übertragen
			((ItemType)o).setValue(((ItemType)o).getResName());
			//ItemObjekt erzeugen und an das UserObjekt referenzieren
			userObject.setUserObjectItem((UserObjectItem)o);
			//Eine Referenz auf das UserObjekt wird an das Nodeobjekt übergeben
			node.setUserObject(userObject);
			return node;
		} catch (ClassNotFoundException e1){
			System.err.println("Itemclass "+ type2 +" must be in the classpath");
		} catch (InstantiationException e2){
			System.err.println("Class "+type2+" must be a concrete class, not an interface or an abstract class");
		} catch (IllegalAccessException e3){
			System.err.println("Class " + type2 + " lacks a no-argument constructor");
		} catch (Exception e){
			System.err.println(e.toString());
		}
		
		return null;
	}
	
}
