package de.afbb.bibo.aggregation;

import java.net.ConnectException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.Display;

import de.afbb.bibo.servletclient.ServiceLocator;
import de.afbb.bibo.share.IAggregationService;
import de.afbb.bibo.share.IBorrowerService;
import de.afbb.bibo.share.IMediumService;
import de.afbb.bibo.share.callback.EventListener;
import de.afbb.bibo.share.callback.IAggregatorTarget;
import de.afbb.bibo.share.model.Borrower;
import de.afbb.bibo.share.model.Medium;
import de.afbb.bibo.share.model.NavigationTreeNodeType;

public class NavigationTreeService implements EventListener {

	private static final String SUM = "∑";//$NON-NLS-1$
	private static final String UP = "↑";//$NON-NLS-1$
	private static final String MEDIA_INFORMATION = " [" + SUM + ":%d, " + UP + "%d]";//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

	private final IBorrowerService borrowerService = ServiceLocator.getInstance().getBorrowerService();
	private final IMediumService mediumService = ServiceLocator.getInstance().getMediumService();
	private final IAggregationService aggregationService = ServiceLocator.getInstance().getAggregationService();

	private NavigationTreeViewNode borrowersRoot;
	private NavigationTreeViewNode mediaRoot;
	private final TreeViewer viewer;

	public NavigationTreeService(final TreeViewer viewer) throws ConnectException {
		this.viewer = viewer;
		ServiceLocator.getInstance().getLoginService().register(this);
		ServiceLocator.getInstance().getCopyService().register(this);
		aggregationService.register(this);
		borrowerService.register(this);
	}

	public void reloadBorrowers() throws ConnectException {
		borrowersRoot = new NavigationTreeViewNode("Ausleiher", null, NavigationTreeNodeType.PERSONS);
		loadBorrowers(borrowersRoot);
		setInput();
	}

	public void reloadCopies() throws ConnectException {
		mediaRoot = new NavigationTreeViewNode("Medien", null, NavigationTreeNodeType.MEDIA);
		loadCopies(mediaRoot);
		setInput();
	}

	public NavigationTreeViewNode getRoot() {
		final NavigationTreeViewNode root = new NavigationTreeViewNode("", null, NavigationTreeNodeType.ROOT);
		root.addChild(borrowersRoot);
		root.addChild(mediaRoot);
		return root;
	}

	private void loadCopies(final NavigationTreeViewNode root) throws ConnectException {
		mediaRoot.setInformation(null);
		final Collection<Medium> media = mediumService.list();
		final Iterator<Medium> mediaIterator = media.iterator();
		while (mediaIterator.hasNext()) {
			final Medium medium = mediaIterator.next();
			if (medium != null) {
				final NavigationTreeViewNode mediumNode = new NavigationTreeViewNode(medium.getTitle(), medium,
						NavigationTreeNodeType.MEDIUM);
				final Job job = new Job("Lade Informationen") {

					@Override
					protected IStatus run(final IProgressMonitor monitor) {
						aggregationService.aggregateMediumInformation(medium.getMediumId(), mediumNode);
						return Status.OK_STATUS;
					}

				};
				job.schedule();
				root.addChild(mediumNode);
			}
		}

	}

	private void loadBorrowers(final NavigationTreeViewNode root) throws ConnectException {
		borrowersRoot.setInformation(null);
		final HashMap<String, NavigationTreeViewNode> groups = new HashMap<String, NavigationTreeViewNode>();

		final Iterator<Borrower> borrowerIterator = borrowerService.listAll().iterator();
		while (borrowerIterator.hasNext()) {
			final Borrower borrower = borrowerIterator.next();
			NavigationTreeViewNode personsNode;
			final NavigationTreeViewNode pupilNode;

			if (groups.containsKey(borrower.getInfo())) {
				personsNode = groups.get(borrower.getInfo());
			} else {
				personsNode = new NavigationTreeViewNode(borrower.getInfo(), null, NavigationTreeNodeType.PERSONS);
				personsNode.setInformation(null);
				groups.put(borrower.getInfo(), personsNode);
			}

			pupilNode = new NavigationTreeViewNode(borrower.getForename() + " " + borrower.getSurname(), borrower,
					NavigationTreeNodeType.PERSON);
			final Job job = new Job("Lade Informationen") {

				@Override
				protected IStatus run(final IProgressMonitor monitor) {
					aggregationService.aggregateBorrowerInformation(borrower.getId(), pupilNode);
					return Status.OK_STATUS;
				}

			};
			job.schedule();

			personsNode.addChild(pupilNode);
		}

		final Iterator<NavigationTreeViewNode> groupsIterator = groups.values().iterator();
		while (groupsIterator.hasNext()) {
			final NavigationTreeViewNode group = groupsIterator.next();

			root.addChild(group);
		}
	}

	@Override
	public void invalidate(final NavigationTreeNodeType type) {
		try {
			if (NavigationTreeNodeType.ROOT.equals(type)) {
				reloadBorrowers();
				reloadCopies();
			} else if (NavigationTreeNodeType.PERSONS.equals(type)) {
				reloadBorrowers();
			}
			if (NavigationTreeNodeType.MEDIA.equals(type)) {
				reloadCopies();
			}
		} catch (final ConnectException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void setInput() {
		Display.getDefault().asyncExec(new Runnable() {

			@Override
			public void run() {
				if (viewer != null && viewer.getTree() != null && !viewer.getTree().isDisposed()) {
					viewer.setInput(getRoot());
				}
				viewer.refresh();
			}
		});
	}

	@Override
	public void update(final IAggregatorTarget target, final String[] information) {
		target.setInformation(information);
		setInput();
	}

}

@@ -923,243 +923,8 @@
 %0D%0A%0D%0A
-%09private static final String SUM = %22%E2%88%91%22;//$NON-NLS-1$%0D%0A%09private static final String UP = %22%E2%86%91%22;//$NON-NLS-1$%0D%0A%09private static final String MEDIA_INFORMATION = %22 %5B%22 + SUM + %22:%25d, %22 + UP + %22%25d%5D%22;//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$%0D%0A%0D%0A
 %09pri
@@ -1013,32 +1013,32 @@
 owerService();%0D%0A
+
 %09private final I
@@ -2036,22 +2036,21 @@
 %0D%0A%09%09load
-Copies
+Media
 (mediaRo
@@ -2328,22 +2328,21 @@
 oid load
-Copies
+Media
 (final N
@@ -2400,43 +2400,8 @@
  %7B%0D%0A
-%09%09mediaRoot.setInformation(null);%0D%0A
 %09%09fi
@@ -3202,47 +3202,8 @@
  %7B%0D%0A
-%09%09borrowersRoot.setInformation(null);%0D%0A
 %09%09fi
@@ -3681,24 +3681,24 @@
 %09%09%7D else %7B%0D%0A
+
 %09%09%09%09personsN
@@ -3794,47 +3794,8 @@
 );%0D%0A
-%09%09%09%09personsNode.setInformation(null);%0D%0A
 %09%09%09%09

renamed methods. removed not needed method call