/*
 * $Id: TreeViewManager.java,v 1.20 2006/10/02 00:25:53 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: TreeViewManager.java,v $
 * Revision 1.20  2006/10/02 00:25:53  marbobo
 * + Explorer Fehlerbeseitigt (Hoffe endgültig)
 *
 * Revision 1.19  2005/09/05 22:46:45  marbobo
 * + Anpassungen bzgl. Trash-Funktionalität
 *
 * Revision 1.18  2004/03/02 17:42:18  bigmac
 * Log-Message auskommentiert
 *
 * Revision 1.17  2003/12/24 10:11:57  bigmac
 * Projektweite Import-Optimierung
 *
 * Revision 1.16  2003/11/14 02:27:21  koppy
 * Features + Refactoring
 *
 * Revision 1.15  2003/11/12 14:05:38  koppy
 * Löschen eines Knotens modifiziert
 *
 * Revision 1.14  2003/11/12 01:11:11  koppy
 * Navigatorverhalten optimiert
 *
 * Revision 1.13  2003/11/11 02:39:08  koppy
 * Redesign/ Refactoring
 *
 * Revision 1.12  2003/11/07 12:51:05  koppy
 * TreeView Update bei Umbennung einer Kategorie
 *
 * Revision 1.11  2003/11/05 00:27:15  koppy
 * bugfix + Verbesserungen
 *
 * Revision 1.10  2003/10/16 08:28:10  bigmac
 * NPE abgefangen
 *
 * Revision 1.9  2003/10/08 21:22:21  koppy
 * bugfix
 *
 * Revision 1.8  2003/09/16 21:25:48  koppy
 * update des treeview bei copy&move Operationen
 *
 * Revision 1.7  2003/09/16 00:23:09  koppy
 * + diverse refresh-Methoden
 *
 * Revision 1.6  2003/08/03 15:34:18  bigmac
 * *** empty log message ***
 *
 * Revision 1.5  2003/08/02 16:14:15  bigmac
 * *** empty log message ***
 *
 * Revision 1.4  2003/07/31 13:59:30  bigmac
 * Compilerwarnungen beseitigt
 *
 * Revision 1.3  2003/05/13 12:52:37  koppy
 * ...
 *
 * Revision 1.2  2003/05/05 15:08:01  koppy
 * ...
 *
 * Revision 1.1  2003/05/01 22:44:26  koppy
 * <No Comment Entered>
 *
 */
package vkc.util.treeview;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import vkc.db.entities.VKCCategory;
import vkc.exception.DBException;
import vkc.misc.VKCLogManager;
import vkc.view.WebShare;

/**
 * This class manages <code>vkc.util.treeview.TreeView</code>
 *
 * @version 1.0
 * @author koppy
 */
public final class TreeViewManager {
	/** Singelton pattern */
	private static TreeViewManager instance = null;	
	/** Reference to the global treeview */
	private TreeView globalTreeView = null;
	
	private boolean updateRequested = false;
	
	private TreeViewManager() {
	}

	public final static TreeViewManager getInstance() {
		if (instance == null) {
			instance = new TreeViewManager();
		}

		return instance;
	}
	

	/**
	 * Builds the global tree
	 */
	public final synchronized void buildGlobalTree() throws DBException {
		this.globalTreeView = new TreeView();						
		WebShare.database.buildTree(globalTreeView);		
		this.updateRequested = false;
	}

	/**
	 * Refreshes the treeview with the given category
	 * 
	 * @param newCategory
	 */
	public void add(VKCCategory newCategory) {
		if (globalTreeView == null) {
			return;
		}
		
		synchronized(globalTreeView) {
			TreeViewItem p = this.globalTreeView.getTreeViewItemById(newCategory.getParentCategoryId().toString());
			
			if (p == null) {
				VKCLogManager.infoLog(this, "TreeViewManager: TreeViewItem '" + newCategory.getParentCategoryId() + "' not found.");
				
				return;
	
			} 	
			
			TreeViewItem newItem = new TreeViewItem(newCategory.getCategoryId().toString(),	null, newCategory.getName(), null);

			//VKCLogManager.infoLog( this, "TreeViewManager: adding TreeViewItem '" + newItem + "' to TreeViewItem " + p );

			p.addChild(newItem);	
			this.globalTreeView.addTreeViewItem(newItem);
			this.globalTreeView.setLastModified(System.currentTimeMillis());
		}		
	}
	
	/**
	 * Updates the Name of the TreeviewItem with the given category
	 * 
	 * @param category	 
	 */
	public void update(VKCCategory category) {
		if (globalTreeView == null) {
			return;
		}
		
		synchronized(globalTreeView) {
			TreeViewItem p = this.globalTreeView.getTreeViewItemById(category.getCategoryId().toString());
			
			if (p == null) {
				VKCLogManager.infoLog(this, "TreeViewManager: TreeViewItem '" + category.getCategoryId() + "' not found.");
				
				return;
			}		
			
			// Updates the label of the TreeViewItem
			p.setText(category.getName());		
			this.globalTreeView.setLastModified(System.currentTimeMillis());
		}
	}
	
	/**
	 * Refreshes the treeview by deleting the given category
	 * 
	 * @param itemId the ID of the category to be deleted
	 */
	public void remove(String itemId) {
		if (globalTreeView == null) {
			return;
		}
		
		synchronized(globalTreeView) {
			TreeViewItem c = this.globalTreeView.getTreeViewItemById(itemId);
			
			if (c == null) {
				return;				
			} 

			VKCLogManager.infoLog(this, "TreeViewManager: deleting child '" + c + "' from " + c.getParent());
			c.remove();						
			
			// Traverse all child nodes and remove them from global treeview list		
			List tmpList = new ArrayList();
			tmpList.add(c);
			
			while (!tmpList.isEmpty()) {
				TreeViewItem item = (TreeViewItem)tmpList.remove(0);				
				this.globalTreeView.removeTreeViewItem(item.getId());
				
				for (Iterator it = item.getChildren().iterator(); it.hasNext();) {
					tmpList.add(it.next());	
				}
			}
			
			this.globalTreeView.setLastModified(System.currentTimeMillis());				
		}
	}	
		
	/**
	 *  Refreshes the tree by moving the given categories
	 *		 
	 * @param categoryIds the categoryIds of categories to be moved (same parent)
	 * @param targetItemId the ID of the targetCategory
	 */
	public void move(Set categoryIds, String targetItemId) {
		if (globalTreeView == null) {
			return;
		}
		
		synchronized(globalTreeView) {
			if (categoryIds == null || categoryIds.isEmpty()) {
				return;
			}
	
			TreeViewItem p = this.globalTreeView.getTreeViewItemById(categoryIds.iterator().next().toString()).getParent();
						
			if (p == null) {
				return; // Should not happen
			}
			
			TreeViewItem newParent = this.globalTreeView.getTreeViewItemById(targetItemId);
					
			for (Iterator it = categoryIds.iterator(); it.hasNext();) {
				Integer catId = (Integer)it.next();
				TreeViewItem cChild = this.globalTreeView.getTreeViewItemById(catId.toString());
												
				p.deleteChildById(catId.toString());			
				newParent.addChild(cChild);	
			}
			
			this.globalTreeView.setLastModified(System.currentTimeMillis());
		}
	}	

	/**
	 *  Refreshes the tree by moving the given categories
	 *		 
	 * @param categoryId the categoryIds of categories to be moved (same parent)
	 * @param targetItemId the ID of the targetCategory
	 */
	public void move(Integer categoryId, String targetItemId) {
		if (globalTreeView == null) {
			return;
		}
		
		synchronized(globalTreeView) {
			if (categoryId == null || categoryId.intValue() <= 0) {
				return;
			}
	
			TreeViewItem p = this.globalTreeView.getTreeViewItemById(categoryId.toString()).getParent();
						
			if (p == null) {
				return; // Should not happen
			}
			
			TreeViewItem newParent = this.globalTreeView.getTreeViewItemById(targetItemId);
					
			TreeViewItem child = this.globalTreeView.getTreeViewItemById(categoryId.toString());
												
			p.deleteChildById(categoryId.toString());			
			newParent.addChild(child);	
			
			this.globalTreeView.setLastModified(System.currentTimeMillis());
		}
	}	

	/**
	 * Returns the global Treeview
	 */
	public TreeView getGlobalTreeView() {
		return this.globalTreeView;
	}

	public boolean updateRequested() {
		return updateRequested;
	}
	
	public void requestUpdate() {
		updateRequested = true;
	}	
}