/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-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
 * @param page
 */
	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.
 * @boolean 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 enum = pages.elements(); enum.hasMoreElements();) {
			PageBag pageBag = (PageBag) enum.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.
 */
	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.
 */	
	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;
			}
		}
		pageBook.showEmptyPage();
	}
	private void checkLimit() {
		if (pages.size() <= getPageLimit()) return;
		// overflow
		int currentTicket = PageBag.getCurrentTicket();
		int cutoffTicket = currentTicket - getPageLimit();
		for (Enumeration enum=pages.keys(); enum.hasMoreElements();) {
			Object key = enum.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();
	}
}