/**
 * File:    ViewItemWrapper.java
 * Created: 26.09.2006
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wolf Fischer, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.misc.views;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EObject;


/**
 * This class contains the information if an object should be displayed in the modeller or
 * not.
 * 
 * @version $Id: ViewItemWrapper.java,v 1.7 2009-11-26 12:41:45 chsaad Exp $
 * @author Wolf Fischer, Programming distributed Systems Lab, University of Augsburg,
 *         Germany, www.ds-lab.org
 * @since 0.6.0
 */
public class ViewItemWrapper
		implements Serializable, Comparable<ViewItemWrapper>
{

	private static final long serialVersionUID = 6834568603177376781L;
	private String text;
	private boolean value;
	private List<ViewItemWrapper> children = new ArrayList<ViewItemWrapper>();
	public ViewItemWrapper parent = null;


	/**
	 * Standard constructor. Takes an eobject and generates a name out of it, that is used
	 * for identification.
	 * 
	 * @param obj
	 *            The EObject
	 * @param value
	 *            if true, indicates, that this element can be shown.
	 * @param ignorerootelement
	 *            This is for generation of the name in combination with jwt-view: If
	 *            loading the ecore meta model file and manually browsing through the meta
	 *            model, there is another root-level: "Model". Normally, it is just
	 *            "process", "organisation" or something else. The "Model" has to be
	 *            ignored.
	 */
	public ViewItemWrapper(EObject obj, boolean value, boolean ignorerootelement)
	{
		text = makeName(obj, ignorerootelement);
		this.value = value;
		parent = null;
	}


	/**
	 * Adds a child to this viewitemwrapper (for example an attribute)
	 * 
	 * @param newchild
	 */
	public void addChild(ViewItemWrapper newchild)
	{
		children.add(newchild);
	}


	/*
	 * /** Sets this viewitems parent @param parent / private void
	 * setParent(ViewItemWrapper parent) { this.parent = parent; }
	 * 
	 * /** Returns this childs parent @return / private ViewItemWrapper getParent() {
	 * return parent; }
	 */

	/**
	 * Creates a unique name of a modelelement via walking up a tree path and
	 * concatenating the elements names.
	 * 
	 * @param obj
	 *            The object for which a name should be created
	 * @param ignorerootelement
	 *            Should the root element exist in the name? this is important for the
	 *            ResourceManager, because there the root node is "model" and not packages
	 *            like "core", "processes" etc.
	 * @return Name in the form of "organisations.Role"
	 */
	public static String makeName(EObject obj, boolean ignorerootelement)
	{
		String result = ""; //$NON-NLS-1$
		while (obj.eContainer() != null)
		{
			result = getName(obj) + result;
			if (obj.eContainer() != null)
				result = "." + result; //$NON-NLS-1$
			obj = obj.eContainer();
		}
		if (!ignorerootelement)
		{
			result = getName(obj) + result;
		}
		else
		{
			result = result.substring(1);
		}
		return result;
	}


	/**
	 * Returns the name of an EObject
	 * 
	 * @param obj
	 * @return
	 */
	private static String getName(EObject obj)
	{
		if (obj instanceof ENamedElement)
		{
			return ((ENamedElement) obj).getName();
		}
		else
		{
			return makeName(obj.eClass(), false);
		}
	}


	/**
	 * Overriden toString Method.
	 */
	@Override
	public String toString()
	{
		return text;
	}


	/**
	 * Returns a value that indicates if this element can be displayed. This is done by
	 * walking back through the tree and checking, if all of its parents can be shown or
	 * not
	 * 
	 * @return True, if it can be displayed. Else false
	 */
	public boolean getDisplay()
	{
		boolean parentval = (parent != null) ? parent.getDisplay() : true;
		return (value && parentval);
	}


	/**
	 * Just return its display value without walking up the tree
	 * 
	 * @return
	 */
	public boolean getValue()
	{
		return value;
	}


	/**
	 * Sets, if this viewitem can be displayed or not
	 * 
	 * @param val
	 */
	public void setDisplay(boolean val)
	{
		value = val;
	}


	/**
	 * Compares this viewitem to another viewitem on a string basis
	 */
	public int compareTo(ViewItemWrapper o)
	{
		return toString().compareTo(o.toString());
	}

}
