//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.layout.elements;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.layout.IElementLayout;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;

import com.ibm.icu.util.StringTokenizer;


/**
 * abstrct class for process element layout that is process specific
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public abstract class AbstractProcessElementLayout extends
		AbstractElementLayout {

	protected Process owningProcess = null;

	protected String elementProcessPath = null;
	protected String relProcessPath = null;
	protected String[] paths = null;
	protected String displayName = null;
	
	/**
	 * construct a layout for process element
	 * 
	 * @param layoutManager
	 * @param element
	 * @param owningProc
	 * @param path
	 */
	public void init(ElementLayoutManager layoutManager, MethodElement element,
			Process owningProc, String path) {

		init(layoutManager, element);

		this.owningProcess = owningProc;
		this.elementProcessPath = path;

		if (this.owningProcess == null) {
			this.owningProcess = TngUtil
					.getOwningProcess((BreakdownElement) super.element);
		}

		if (LibraryUtil.isProcess(element)) {
			owningProcess = (Process) element;
			elementProcessPath = AbstractProcessElementLayout.makePath(null,
					element);
			relProcessPath = elementProcessPath;
		}
		
		if ( elementProcessPath == null && this.element instanceof BreakdownElement)
		{
			elementProcessPath = AbstractProcessElementLayout.getPath((BreakdownElement)this.element);
		}
		
		// get the path array
		paths = getPathArray(elementProcessPath);
		
	}


	/**
	 * the process path of this item relative to the calling item
	 * @param path
	 */
	public void setRelativeProcessPath(String path)
	{
		this.relProcessPath = path;
	}
	
	/**
	 * get the relative process path
	 * @return String
	 */
	public String getRelativeProcessPath()
	{
		return this.relProcessPath;
	}
	
//	public String getUrl() {
//		String url = super.getUrl();
//
//		return url + getQueryString();
//	}

	/**
	 * get query string for the process element
	 * @return String
	 */
	public String getQueryString() {
//		if (owningProcess == element) {
//			return "";
//		}
		// return "?" + ResourceHelper.URL_PARAMETER_PROCESS + "=" +
		// owningProcess.getGuid() + "&" + ResourceHelper.URL_PARAMETER_PATH +
		// "=" + elementProcessPath;

		return ElementLayoutManager.getQueryString(owningProcess.getGuid(),
				elementProcessPath);
	}

	/**
	 * @see org.eclipse.epf.library.layout.IElementLayout#getDisplayName()
	 */
	public String getDisplayName() {
		if ( this.displayName == null ) {
			Process proc = getOwningProcess();
			
			// need to handle the supressed breakdown elements
			// use the Supress utility
			Suppression sup = getSuppression(proc);
	
			// display name needs to be fixed, extended activity may need to get display name from the base
			// DVT:  PNs of extended processes no picked up for publish (TCT 638)
			ComposedAdapterFactory adapterFactory = layoutManager.getCBSAdapterFactory();
			Object wrapper = sup.getObjectByPath(this.paths, adapterFactory);
			if ( wrapper == null ) {
				wrapper = super.element;
			}
	
			IBSItemProvider adapter = (IBSItemProvider) adapterFactory.adapt(
					wrapper, ITreeItemContentProvider.class);
	
			this.displayName = ProcessUtil.getAttribute(element,
					IBSItemProvider.COL_PRESENTATION_NAME, adapter);
		}
		
		return displayName;
	}
	
	protected Suppression getSuppression(Process proc)
	{
		return layoutManager.getSuppression(proc);
	}
	
	protected XmlElement getXmlElement() {
		XmlElement elementXml = super.getXmlElement();
		elementXml.setAttribute("queryString", getQueryString()) //$NON-NLS-1$
			//.setAttribute("owningProcessGuid", owningProcess.getGuid()) // //$NON-NLS-1$
			//.setAttribute("elementProcessPath", elementProcessPath) //$NON-NLS-1$
			.setAttribute("relProcessPath", relProcessPath); //$NON-NLS-1$

		return elementXml;
	}
	
	protected Process getOwningProcess() {
		return owningProcess;
	}

	protected IElementLayout getLayout(ProcessElementItem item) {
		IElementLayout layout = layoutManager.createLayout(item.element, owningProcess, item.path);
		
		if ( layout instanceof AbstractProcessElementLayout )
		{		
			// set the relative path to this layout since this is the caller
			String relPath = AbstractProcessElementLayout.getRelativePath(item.path, this.elementProcessPath);
			((AbstractProcessElementLayout)layout).setRelativeProcessPath(relPath);
		}
		return layout;
	}

	protected String getSuperActivityPath() {
		if ( element instanceof BreakdownElement ) {
			Activity act = ((BreakdownElement)element).getSuperActivities();
			String id = act.getGuid();
			int i = elementProcessPath.indexOf(id);
			if ( i >=0 ) {
				return elementProcessPath.substring(0, i + id.length());
			}
		}
		
		return null;
	}
	
	/**
	 * static utility methods for make a path for the process elenment
	 */
	public static String makePath(String parentPath, MethodElement element) {
		if (parentPath == null || parentPath.length() == 0) {
			return element.getGuid();
		}

		return parentPath + "," + element.getGuid(); //$NON-NLS-1$
	}

	/**
	 * static method to get the path of a break down element
	 * @param element
	 * @return String
	 */
	public static String getPath(BreakdownElement element) {
		
		String path = element.getGuid();
		BreakdownElement act = element;
		Process proc = TngUtil.getOwningProcess(element);

		// Check superactivity is process and should owning process (this is useful in deepcopy
		while ( act != proc )
		{
			Activity superActs = act.getSuperActivities();
			if ( superActs != null )
			{
				act = superActs;
				path = act.getGuid() + "," + path; //$NON-NLS-1$
			}
			else
			{
				break;
			}
		}
		
		return path;		
	}
	
	/**
	 * get the path for a given breakdown element item provider
	 * @param wrapper BreakdownElementWrapperItemProvider
	 * @return String the path
	 */
	public static String getPath(BreakdownElementWrapperItemProvider wrapper)
	{
		Object e = LibraryUtil.unwrap(wrapper);
		if ( !(e instanceof MethodElement) ) {
			return null;
		}
		Object topItem = wrapper.getTopItem();
		StringBuffer path = new StringBuffer();
		path.append(((MethodElement)e).getGuid());
		
		Object parent = wrapper;
		while (parent != null && parent != topItem) {
			if ( parent instanceof BreakdownElement ) {
				parent = ((BreakdownElement)parent).getSuperActivities();
				e = parent;
			} else if ( parent instanceof BreakdownElementWrapperItemProvider ){
				parent = ((BreakdownElementWrapperItemProvider)parent).getParent(parent);
				e = LibraryUtil.unwrap(parent);
			} else {
				break;
			}
			
			if ( e instanceof MethodElement) {
				path.insert(0, ((MethodElement)e).getGuid() + ","); //$NON-NLS-1$
			}
		}
		
		return path.toString();
	}
	
	/**
	 * utility method to get the relative path to the parent
	 * @param path String
	 * @param parentPath String
	 * @return String
	 */
	public static String getRelativePath(String path, String parentPath) {
		
		if ( path == null )
		{
			return path;
		}
		
		if ( path.startsWith(parentPath) )
		{
			return path.substring(parentPath.length());
		}
		
		return path;
	}

	/**
	 * get the path arrray
	 * @param path String
	 * @return String[]
	 */
	public static String[] getPathArray(String path)
	{
		if ( path == null )
		{
			return new String[]{};			
		}
		
		List items = new ArrayList();
		StringTokenizer st = new StringTokenizer(path, ","); //$NON-NLS-1$
		while ( st.hasMoreTokens() )
		{
			String s = st.nextToken().trim();
			if ( s.length() > 0 )
			{
				items.add(s);
			}
		}
		
		String[] arr = new String[items.size()];
		items.toArray(arr);
		
		return arr;
	}
	
	/**
	 * get the owning process from path, the first part of the path is the guid of the process
	 * @param path
	 * @return String
	 */
	public static String getOwningProcessGuidFromPath(String path)
	{
		if ( path == null )
		{
			return null;
		}
		
		int index = path.indexOf(","); //$NON-NLS-1$
		String guid;
		if ( index < 0 )
		{
			guid = path;
		}
		else
		{
			guid = path.substring(0, index);
		}
		
		return guid;
	}

	/**
	 * get the parent path
	 * @param path
	 * @return String
	 */
	public static String getParentPath(String path) {
		if ( path == null ) {
			return null;
		}
		
		int index = path.lastIndexOf(","); //$NON-NLS-1$
		if ( index > 0 ) {
			return path.substring(0, index);
		}
		
		return null;
	}
	
}
