/*******************************************************************************
 * Copyright (c) 2000, 2004 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 API and implementation
 *******************************************************************************/
package org.eclipse.ui.forms;
import java.util.*;

import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.ScrolledPageBook;
/**
 * This managed form part handles the 'details' portion of the 
 * 'master/details' block. It has a page book that manages pages
 * of details registered for the current selection.
 * <p>By default, details part accepts any number of pages.
 * If dynamic page provider is registered, this number may
 * be excessive. To avoid running out of steam (by creating 
 * a large number of pages with widgets on each), maximum
 * number of pages can be set to some reasonable value (e.g. 10).
 * When this number is reached, old pages (those created first)
 * will be removed and disposed as new ones are added. If
 * the disposed pages are needed again after that, they
 * will be created again.
 * 
 * @since 3.0
 */
public final class DetailsPart implements IFormPart, IPartSelectionListener {
	private IManagedForm managedForm;
	private ScrolledPageBook pageBook;
	private IFormPart masterPart;
	private IStructuredSelection currentSelection;
	private Hashtable pages;
	private IDetailsPageProvider pageProvider;
	private int pageLimit=Integer.MAX_VALUE;
	
	private static class PageBag {
		private static int counter;
		private int ticket;
		private IDetailsPage page;
		private boolean fixed;
		
		public PageBag(IDetailsPage page, boolean fixed) {
			this.page= page;
			this.fixed = fixed;
			this.ticket = ++counter;
		}
		public int getTicket() {
			return ticket;
		}
		public IDetailsPage getPage() {
			return page;
		}
		public void dispose() {
			page.dispose();
			page=null;
		}
		public boolean isDisposed() {
			return page==null;
		}
		public boolean isFixed() {
			return fixed;
		}
		public static int getCurrentTicket() {
			return counter;
		}
	}
/**
 * Creates a details part by wrapping the provided page book.
 * @param mform the parent form
 * @param pageBook the page book to wrap
 */	
	public DetailsPart(IManagedForm mform, ScrolledPageBook pageBook) {
		this.pageBook = pageBook;
		pages = new Hashtable();
		initialize(mform);
	}
/**
 * Creates a new details part in the provided form by creating 
 * the page book.
 * @param mform the parent form
 * @param parent the composite to create the page book in
 * @param style the style for the page book
 */
	public DetailsPart(IManagedForm mform, Composite parent, int style) {
		this(mform, mform.getToolkit().createPageBook(parent, style|SWT.V_SCROLL|SWT.H_SCROLL));
	}
/**
 * Registers the details page to be used for all the objects of
 * the provided object class.
 * @param objectClass an object of type 'java.lang.Class' to be used 
 * as a key for the provided page
 * @param page the page to show for objects of the provided object class
 */
	public void registerPage(Object objectClass, IDetailsPage page) {
		registerPage(objectClass, page, true);
	}
	
	private void registerPage(Object objectClass, IDetailsPage page, boolean fixed) {
		pages.put(objectClass, new PageBag(page, fixed));
		page.initialize(managedForm);
	}
/**
 * Sets the dynamic page provider. The dynamic provider can return
 * different pages for objects of the same class based on their state.
 * @param provider the provider to use
 */
	public void setPageProvider(IDetailsPageProvider provider) {
		this.pageProvider = provider;
	}
/**
 * Commits the part by committing the current page.
 * @param onSave <code>true</code> if commit is requested as a result
 * of the 'save' action, <code>false</code> otherwise.
 */
	public void commit(boolean onSave) {
		IDetailsPage page = getCurrentPage();
		if (page != null)
			page.commit(onSave);
	}
/**
 * Returns the current page visible in the part.
 * @return the current page
 */
	public IDetailsPage getCurrentPage() {
		Control control = pageBook.getCurrentPage();
		if (control != null) {
			Object data = control.getData();
			if (data instanceof IDetailsPage)
				return (IDetailsPage) data;
		}
		return null;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IFormPart#dispose()
	 */
	public void dispose() {
		for (Enumeration enm = pages.elements(); enm.hasMoreElements();) {
			PageBag pageBag = (PageBag) enm.nextElement();
			pageBag.dispose();
		}
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
	 */
	public void initialize(IManagedForm form) {
		this.managedForm = form;
	}
/**
 * Tests if the currently visible page is dirty.
 * @return <code>true</code> if the page is dirty, <code>false</code> otherwise.
 */
	public boolean isDirty() {
		IDetailsPage page = getCurrentPage();
		if (page != null)
			return page.isDirty();
		return false;
	}
/**
 * Tests if the currently visible page is stale and needs refreshing.
 * @return <code>true</code> if the page is stale, <code>false</code> otherwise.
 */	
	public boolean isStale() {
		IDetailsPage page = getCurrentPage();
		if (page != null)
			return page.isStale();
		return false;
	}

/**
 * Refreshes the current page.
 */
	public void refresh() {
		IDetailsPage page = getCurrentPage();
		if (page != null)
			page.refresh();
	}
/**
 * Sets the focus to the currently visible page.
 */
	public void setFocus() {
		IDetailsPage page = getCurrentPage();
		if (page != null)
			page.setFocus();
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IFormPart#setFormInput(java.lang.Object)
	 */
	public boolean setFormInput(Object input) {
		return false;
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.IPartSelectionListener#selectionChanged(org.eclipse.ui.forms.IFormPart,
	 *      org.eclipse.jface.viewers.ISelection)
	 */
	public void selectionChanged(IFormPart part, ISelection selection) {
		this.masterPart = part;
		if (currentSelection != null) {
		}
		if (selection instanceof IStructuredSelection)
			currentSelection = (IStructuredSelection) selection;
		else
			currentSelection = null;
		update();
	}
	private void update() {
		Object key = null;
		if (currentSelection != null) {
			for (Iterator iter = currentSelection.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (key == null)
					key = getKey(obj);
				else if (getKey(obj).equals(key) == false) {
					key = null;
					break;
				}
			}
		}
		showPage(key);
	}
	private Object getKey(Object object) {
		if (pageProvider!=null) {
			Object key = pageProvider.getPageKey(object);
			if (key!=null)
				return key;
		}
		return object.getClass();
	}
	private void showPage(final Object key) {
		checkLimit();
		final IDetailsPage oldPage = getCurrentPage();
		if (key != null) {
			PageBag pageBag = (PageBag)pages.get(key);
			IDetailsPage page = pageBag!=null?pageBag.getPage():null;
			if (page==null) {
				// try to get the page dynamically from the provider
				if (pageProvider!=null) {
					page = pageProvider.getPage(key);
					if (page!=null) {
						registerPage(key, page, false);
					}
				}
			}
			if (page != null) {
				final IDetailsPage fpage = page;
				BusyIndicator.showWhile(pageBook.getDisplay(), new Runnable() {
					public void run() {
						if (!pageBook.hasPage(key)) {
							Composite parent = pageBook.createPage(key);
							fpage.createContents(parent);
							parent.setData(fpage);
						}
						//commit the current page
						if (oldPage!=null && oldPage.isDirty())
							oldPage.commit(false);
						//refresh the new page
						if (fpage.isStale())
							fpage.refresh();
						fpage.selectionChanged(masterPart, currentSelection);
						pageBook.showPage(key);
					}
				});
				return;
			}
		}
		// If we are switching from an old page to nothing,
		// don't loose data 
		if (oldPage!=null && oldPage.isDirty())
			oldPage.commit(false);
		pageBook.showEmptyPage();
	}
	private void checkLimit() {
		if (pages.size() <= getPageLimit()) return;
		// overflow
		int currentTicket = PageBag.getCurrentTicket();
		int cutoffTicket = currentTicket - getPageLimit();
		for (Enumeration enm=pages.keys(); enm.hasMoreElements();) {
			Object key = enm.nextElement();
			PageBag pageBag = (PageBag)pages.get(key);
			if (pageBag.getTicket()<=cutoffTicket) {
				// candidate - see if it is active and not fixed
				if (!pageBag.isFixed() && !pageBag.getPage().equals(getCurrentPage())) {
					// drop it
					pageBag.dispose();
					pages.remove(key);
					pageBook.removePage(key, false);				
				}
			}
		}
	}
	/**
	 * Returns the maximum number of pages that should be
	 * maintained in this part. When an attempt is made to
	 * add more pages, old pages are removed and disposed
	 * based on the order of creation (the oldest pages
	 * are removed). The exception is made for the 
	 * page that should otherwise be disposed but is
	 * currently active.
	 * @return maximum number of pages for this part
	 */
	public int getPageLimit() {
		return pageLimit;
	}
	/**
	 * Sets the page limit for this part. 
	 * @see #getPageLimit()
	 * @param pageLimit the maximum number of pages that
	 * should be maintained in this part.
	 */
	public void setPageLimit(int pageLimit) {
		this.pageLimit = pageLimit;
		checkLimit();
	}
}
