package eu.dnetlib.client.managers;

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.logging.Logger;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import eu.dnetlib.client.GinWidgetGinjector;
import eu.dnetlib.client.notification.NotificationServiceAsync;
import eu.dnetlib.client.shared.StartUpComponents;
import eu.dnetlib.client.updaters.LayoutUpdater;

/**
 * @author Eri
 * 
 */

@Singleton
public class ActiveComponentsManagerImpl implements ActiveComponentsManager {

	private static Logger log = Logger.getLogger("ActiveComponentsManager.java");

	private NotificationServiceAsync CometService = null;

	private HashMap<String, String> activeComponents;
	@Inject
	private LayoutUpdater layoutUpdater;
	@Inject
	private StartUpComponents startUpComponents;

	@Inject
	public ActiveComponentsManagerImpl() {
		activeComponents = new HashMap<String, String>();
		CometService = GinWidgetGinjector.INSTANCE.getNotificationServiceAsync();
		startUpComponents = GinWidgetGinjector.INSTANCE.getStartUpComponents();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * eu.dnetlib.client.managers.ActiveComponentsManager#unMarkItem(java.lang
	 * .String, java.lang.String)
	 */
	public void unMarkItem(final String itemdId, final String userId) {
		// TODO add this so that if listener has lost connection, at least we
		// can keep track of the local active items
		if (startUpComponents.getMyLockedComponentList().contains(itemdId)) {
			startUpComponents.getMyLockedComponentList().remove(itemdId);
		}
		activeComponents.remove(itemdId);
		layoutUpdater.setLocked(itemdId, false, userId);

		CometService.unmarkComponent(itemdId, userId, new AsyncCallback<Void>() {
			public void onSuccess(Void result) {
				log.info("\n\n\n\n\n  component with id: " +itemdId+ " unmarked ");

			}

			public void onFailure(Throwable caught) {
				log.warning("\n\n  component with id: " + itemdId + " failed to be unmarked ");
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * eu.dnetlib.client.managers.ActiveComponentsManager#MarkItem(java.lang
	 * .String, java.lang.String)
	 */
	public void MarkItem(final String itemdId, final String userId) {

		activeComponents.put(itemdId, userId);
		if (!startUpComponents.getMyLockedComponentList().contains(itemdId)) {
			startUpComponents.getMyLockedComponentList().add(itemdId);
			log.info("Add to myyyyyyyyyy locked");
		}
		layoutUpdater.setLocked(itemdId, true, userId);

		// CometService =
		// GinWidgetGinjector.INSTANCE.getNotificationServiceAsync();
		CometService.markComponent(itemdId, userId, new AsyncCallback<Void>() {
			public void onSuccess(Void result) {
				log.info("\n\n\n\n\n  component with id: "+itemdId + " marked ");

			}

			public void onFailure(Throwable caught) {
				log.warning("\n\n  component with id: " + itemdId + " failed to be marked ");
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * eu.dnetlib.client.managers.ActiveComponentsManager#updateActiveComponents
	 * (java.util.HashMap)
	 */

	public void updateActiveComponents(HashMap<String, String> updatedActiveComponents) {
		for (Entry<String, String> e : this.activeComponents.entrySet()) {

			layoutUpdater.setLocked(e.getKey(), false, e.getValue());
		}

		this.activeComponents.clear();

		if (updatedActiveComponents != null && !updatedActiveComponents.isEmpty()) {

			this.activeComponents.putAll(updatedActiveComponents);
			for (Entry<String, String> e : this.activeComponents.entrySet()) {

				layoutUpdater.setLocked(e.getKey(), true, e.getValue());

			}

		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * eu.dnetlib.client.managers.ActiveComponentsManager#isLocked(java.lang
	 * .String, java.lang.String)
	 */
	public boolean isLocked(String componentId, String currentUserId) {
		String owner = this.getActiveComponents().get(componentId);
		// // if (owner != null && !owner.equals(currentUserId)) {
		// log.info("IS LOCKED????????????// starts user:"+startUpComponents.getUser().getId()+" comp:"+startUpComponents.getMyLockedComponentList()+" compID:"+componentId+" currentUser:"+currentUserId);
		// // if (owner != null &&
		// !(owner.equals(currentUserId)&&!startUpComponents.getMyLockedComponentList().contains(componentId)))
		// {
		// if (owner != null &&
		// !(owner.equals(currentUserId)&&!startUpComponents.getMyLockedComponentList().contains(componentId)))
		// {
		//
		//
		// return true;
		// } else {
		// return false;
		// }
		if (owner == null) {
			log.info("It's free");
			return false;

		} else {
			if (owner.equals(currentUserId) && startUpComponents.getMyLockedComponentList().contains(componentId)) {
				log.info("It's mine");
				return false;
			} else {
				log.info("It's same user :"+owner.equals(currentUserId) +" mine list :"+startUpComponents.getMyLockedComponentList().contains(componentId));
				return true;
			}
		}
	}

	// TODO return whether a component is in use by the current user

	public boolean isInUse(String componentId, String currentUserId) {
		String owner = this.getActiveComponents().get(componentId);
		// if (owner != null && owner.equals(currentUserId)) {

		if (owner != null && (owner.equals(currentUserId) && startUpComponents.getMyLockedComponentList().contains(componentId))) {
			return true;
		} else {
			return false;
		}

	}

	public HashMap<String, String> getActiveComponents() {
		return activeComponents;
	}

	public void setActiveComponents(HashMap<String, String> activeComponents) {
		this.activeComponents = activeComponents;
	}

	public void unlockAllComponents() {
		HashMap<String, String> emptyComponents = new HashMap<String, String>();
		startUpComponents.getMyLockedComponentList().clear();
		this.updateActiveComponents(emptyComponents);
	}

}
