/*
 * Copyright (c) 2006-2008 Maskat Project.
 *
 * 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:
 *     Maskat Project - initial API and implementation
 */
package org.maskat.ui.views.properties.tabbed.treenodewrapper;

import java.util.Iterator;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.TreeViewer;
import org.maskat.core.event.Event;
import org.maskat.core.event.Result;
import org.maskat.core.event.Target;
import org.maskat.ui.Messages;
import org.maskat.ui.views.properties.tabbed.beanwrapper.ResultTreeNode;
import org.maskat.ui.views.properties.tabbed.command.AddTreeNodeCommand;
import org.maskat.ui.views.properties.tabbed.masterdetails.EventPropertiesMasterDetailsBlock;

public class MessageToBeReceivedTreeNode extends AbstractTreeNode {
	private static final String MESSAGE_TOBE_RECEIVE =
		Messages.getString("messageToBeReceivedTreeNode.messageTobeReceived"); //$NON-NLS-1$		

	private static final String ADD_MESSAGE_CONTENT =
		Messages.getString("messageToBeReceivedTreeNode.addMessageContent"); //$NON-NLS-1$
	
	
	public MessageToBeReceivedTreeNode(Event event) {
		super(event);
	}

	protected void loadChildren() {
		if(shouldLoadChildren()) {
			ResultTreeNode child = new ResultTreeNode(((Event)maskatElement).getResult());
			addChild(child);
		}
	}

	private boolean shouldLoadChildren() {
		return (maskatElement != null)
				&& ((Event)maskatElement).getTypedChildren(Result.class) != null
				&& ((Event)maskatElement).getResult() != null
				&& ((Event)maskatElement).getResult().isEnable();
	}
	
	/**destroy the result bean of the child after remove the child*/
	public void removeChild(ITreeNode child) {
		super.removeChild(child);
		if (!hasLocalDataBinding()) {
			maskatElement.removeChild(child.getModel());
		} else {
			removeRemoteDataBinding();
		}
	}
	
	private boolean hasLocalDataBinding() {
		if (((Event)maskatElement).getTypedChildren(Result.class) == null) {
			return false;
		}
		Result result = ((Event)maskatElement).getResult();
		if (result != null) {
			Iterator iterator = result.getTypedChildren(Target.class);
			while (iterator != null && iterator.hasNext()) {
				Target target = (Target) iterator.next();
				if (target.getType().equals("local")) {
					return true;
				}
			}
		}
		return false;
	}
	
	private void removeRemoteDataBinding() {
		if (((Event)maskatElement).getTypedChildren(Result.class) == null) {
			return ;
		}
		Result result = ((Event)maskatElement).getResult();
		if (result != null) {
			Iterator iterator = result.getTypedChildren(Target.class);
			while (iterator != null && iterator.hasNext()) {
				Target target = (Target) iterator.next();
				if (!target.getType().equals("local")) {
					result.removeChild(target);
					iterator = result.getTypedChildren(Target.class);
				}
			}
		}
	}
	
	/**add the model relation when add child*/
	public void addChild(ITreeNode child) {
		super.addChild(child);

		Iterator itResult = maskatElement.getTypedChildren(Result.class);
		if (itResult == null || !itResult.hasNext()) {
			maskatElement.addChild(child.getModel());
		} else {
			Result result = (Result)itResult.next();
			Result temp = (Result)child.getModel();
			Iterator it = temp.getTypedChildren(Target.class);
			while(it != null && it.hasNext()) {
				result.addChild(it.next());
			}
		}
		Result result = ((Event)maskatElement).getResult();
		for (int i=0; i<child.getChildren().length; i++) {
			result.addChild(((ITreeNode)child.getChildren()[i]).getModel());
		}
		((Event)maskatElement).getResult().setEnable(true);
	}
	
	public boolean isDeletable() {
		return false;
	}

	public String getDisplayText() {
		return MESSAGE_TOBE_RECEIVE;
	}
	
	public IMenuManager fillContextMenu(final TreeViewer treeViewer, IMenuManager manager) {
		final ITreeNode node = this;
		if (getChildren().length == 0) {
			manager.add(new Action(ADD_MESSAGE_CONTENT){
				public void run() {
					Result result = ((Event)maskatElement).getResult();
					result.setEnable(true);
					ITreeNode childNode = new ResultTreeNode(result);
					EventPropertiesMasterDetailsBlock.executeCommand(new AddTreeNodeCommand(treeViewer,node,childNode));
				}
			});
		}
		return manager;
	}
}
