/*
 * 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.editors.layout.editparts;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;

import org.maskat.core.MaskatElementVisitor;
import org.maskat.core.layout.TreeNode;
import org.maskat.core.layout.TreeView;
import org.maskat.ui.editors.layout.editpolicies.DataBindingEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.FeedBackComponentEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.LabelDirectEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.MaskatComponentEditPolicy;
import org.maskat.ui.editors.layout.editpolicies.TreeViewEditPolicy;
import org.maskat.ui.editors.layout.figures.TreeViewFigure;

public class TreeViewEditPart extends ComponentEditPart
	implements HorizontalResizable, VerticalResizable {

	public IFigure createFigure() {
		Label label = new TreeViewFigure();
		label.setBorder(new CompoundBorder(new LineBorder(), new MarginBorder(0)));

		label.setOpaque(false);
		XYLayout layout = new XYLayout();
		label.setLayoutManager(layout);
		return label;
	}

	protected List getModelChildren() {
		final List result = new ArrayList();
		TreeView def = (TreeView) getModel();
		TreeNode treeNodeDef = (TreeNode) def.getChildByTypeIdx(TreeNode.class,0);

		// 一番目の子ノードのツリーノードしか子モデルとして扱う
		if (treeNodeDef != null) {
			result.add(treeNodeDef);
			treeNodeDef.accept(new MaskatElementVisitor() {

				public void visit(Object def) {
					result.add(def);
				}
			});
		}

		// ツリーに所属すべてのツリーノードを返す
		return result;
	}

	protected void createEditPolicies() {
		int style = FeedBackComponentEditPolicy.getStyle(this);
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new MaskatComponentEditPolicy());
		installEditPolicy(EditPolicy.LAYOUT_ROLE, new TreeViewEditPolicy(style));
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
		installEditPolicy("Snap Feedback", new SnapFeedbackPolicy());
		installEditPolicy(DataBindingEditPolicy.ROLE, new DataBindingEditPolicy());
	}

	public void propertyChange(PropertyChangeEvent evt) {
		this.refresh();
		super.propertyChange(evt);
	}

	public void refresh() {
		TreeView def = (TreeView) getModel();
		def.iterateTree();
		super.refresh();
	}

	public void forceRefresh() {
		refresh();
		// すべての子ノードをリフレッシュ
		for (Iterator it = this.getChildren().iterator(); it.hasNext();) {
			((EditPart) it.next()).refresh();
		}
	}
}

