//------------------------------------------------------------------------------
// 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.publishing.layout;

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

import org.eclipse.epf.library.layout.util.XmlElement;

/**
 * @author Jinhua Xi
 * @since 1.0
 */
public class Bookmark {

	static final long serialVersionUID = -3652582791326323863L;

	// points to the description file in the file system
	private String _fileName = ""; //$NON-NLS-1$

	// used as "closed" or "default" icon
	private String _closedIconName = ""; //$NON-NLS-1$

	// used as "open" icon
	private String _openIconName = ""; //$NON-NLS-1$

	// presentation name of the entry
	private String _presentationName = ""; //$NON-NLS-1$

	// whether mouse is over the bookmark
	// this is for backwards compatibility
	// private boolean _isMouseOver = false;

	// whether the file exists in the file system
	private boolean _isExist = true;

	// whether the file is from content library
	private boolean _isFromContentLibrary = true;

	// unique id.
	// A bookmark may not have a uniqueID in which case the
	// bookmark has no relation to any layout elements.
	private String _uniqueId = null;

	// whether the bookmark is visible
	private boolean _isVisible = true;

	// whether the bookmark is enabled
	// this is to support a special case where bookmarks
	// are to remain hidden and cannot be unhidden as
	// well as transparency
	private boolean _isEnabled = true;

	// whether the bookmark is transparent
	private boolean _isTransparent = false;

	// whether the bookmark is a default one
	// default means that it is published and is read-only
	private boolean _isDefault = false;

	// whether the bookmark is the current one
	// current means the first one to be focused on
	private boolean _isCurrent = false;

	private String queryString = "";
	
	private List children = new ArrayList();

	/**
	 * Default constructor. Takes in the presentation name of the process layout
	 * entry.
	 */
	public Bookmark(String name) {
		_uniqueId = null;
		_presentationName = name;
		if (_presentationName == null) {
			_presentationName = ""; //$NON-NLS-1$
		}
	}

	/**
	 * Name and uniqueId for a layout node.
	 */
	public Bookmark(String presentationName, String uniqueId) {
		this(presentationName);
		_uniqueId = uniqueId;

	}

	/**
	 * Override to return presentation name as the user object.
	 */
	public Object getUserObject() {
		return (_presentationName);
	}

	public void setUserObject(Object userObject) {
		_presentationName = (String) userObject;
		if (_presentationName == null) {
			_presentationName = ""; //$NON-NLS-1$
		}
	}

	public void setPresentationName(String name) {
		_presentationName = name;
		if (_presentationName == null) {
			_presentationName = ""; //$NON-NLS-1$
		}
	}

	public String getPresentationName() {
		return (_presentationName);
	}

	public void setFileName(String name) {
		_fileName = name;
		if (_fileName == null) {
			_fileName = ""; //$NON-NLS-1$
		}
	}

	public String getFileName() {
		return (_fileName);
	}

	public void setClosedIconName(String name) {
		_closedIconName = name;
	}

	public String getClosedIconName() {
		return (_closedIconName);
	}

	public String getOpenIconName() {
		return (_openIconName);
	}

	public void setOpenIconName(String name) {
		_openIconName = name;
	}

	public void setExist(boolean isExist) {
		_isExist = isExist;
	}

	public boolean isExist() {
		return (_isExist);
	}

	public void setFromContentLibrary(boolean flag) {
		_isFromContentLibrary = flag;
	}

	public boolean isFromContentLibrary() {
		return (_isFromContentLibrary);
	}

	public String getUniqueId() {
		return (_uniqueId);
	}

	public void setUniqueId(String uniqueId) {
		_uniqueId = uniqueId;
	}

	public void setVisible(boolean isVisible) {
		_isVisible = isVisible;
		// special case where all children need to change as well
		for (int i = 0; i < getChildCount(); i++) {
			Bookmark child = (Bookmark) ((Bookmark) getChildAt(i));
			child.setVisible(isVisible);
		}
	}

	public boolean isVisible() {
		return (_isVisible);
	}

	public void setEnabled(boolean isEnabled) {
		_isEnabled = isEnabled;
		// special case where all children need to change as well
		for (int i = 0; i < getChildCount(); i++) {
			Bookmark child = (Bookmark) ((Bookmark) getChildAt(i));
			child.setEnabled(isEnabled);
		}
	}

	public boolean isEnabled() {
		return (_isEnabled);
	}

	public void setTransparency(boolean isTransparent) {
		// set at this bookmark only, not children
		_isTransparent = isTransparent;
	}

	public boolean isTransparent() {
		return (_isTransparent);
	}

	public void setDefault(boolean isDefault) {
		_isDefault = isDefault;
	}

	public boolean isDefault() {
		return (_isDefault);
	}

	public void setCurrent(boolean isCurrent) {
		_isCurrent = isCurrent;
	}

	public boolean isCurrent() {
		return (_isCurrent);
	}

	/**
	 * Override to handle visiblity.
	 */
	public int getChildCount() {
		return children.size();
	}

	/**
	 * Retrieves real child count regardless of visibility.
	 */
	public int getActualChildCount() {
		return (getChildCount());
	}

	public Object getChildAt(int i) {
		return children.get(i);
	}

	public Object getActualChildAt(int i) {
		return children.get(i);
	}

	public void addChild(Bookmark child) {
		children.add(child);
	}

	public String getQueryString()
	{
		return queryString;
	}
	
	public void setQueryString(String queryStr)
	{
		this.queryString = queryStr;
	}
	
	public XmlElement getXmlElement() {
		XmlElement elementXml = new XmlElement("Element") //$NON-NLS-1$
				.setAttribute("id", getUniqueId()) //$NON-NLS-1$
				.setAttribute("name", getPresentationName().trim()) //$NON-NLS-1$
				.setAttribute("url", getFileName() + getQueryString()) //$NON-NLS-1$
				.setAttribute("closedIconName", getClosedIconName()) //$NON-NLS-1$
				.setAttribute("openIconName", getOpenIconName()) //$NON-NLS-1$
				.setAttribute("exist", isExist() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute(
						"fromContentLibrary", isFromContentLibrary() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute("visible", isVisible() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute("enabled", isEnabled() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute("transparent", isTransparent() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute("default", isDefault() ? "true" : "false") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				.setAttribute("current", isCurrent() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		for (int i = 0; i < getChildCount(); i++) {
			Bookmark child = (Bookmark) getActualChildAt(i);
			elementXml.addChild(child.getXmlElement());
		}

		return elementXml;
	}

}