/*
 * Copyright 2006 Maskat Project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.maskat.ide.gef.editparts;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartListener;
import org.eclipse.gef.GraphicalEditPart;
import org.maskat.framework.CUtil;
import org.maskat.framework.screendef.ComboDef;
import org.maskat.framework.screendef.ComboItemDef;
import org.maskat.framework.screendef.ComponentDef;
import org.maskat.framework.screendef.PopupDef;
import org.maskat.ide.gef.figure.ComboFigure;

public class ComboboxEditPart extends ComponentEditPart {
	public void activate() {
		this.addEditPartListener(new EditPartListener.Stub() {
			public void selectedStateChanged(EditPart part) {
				if (part.getSelected() == SELECTED_PRIMARY) {
					setShowChildren(true);
				} else {
					setShowChildren(false);
				}
				refresh();
				super.selectedStateChanged(part);
			}
		});
		super.activate();
	}

	public boolean isShowChildren() {
		return ((ComboFigure) this.getFigure()).isChildrenShown();
	}

	public void setShowChildren(boolean showChildren) {
		((ComboFigure) this.getFigure()).setChildrenShown(showChildren);
		this.refresh();
		if (!showChildren)
			((ComboFigure) this.getFigure()).setIcon(COMBOBOXDROPDOWN);
		else
			((ComboFigure) this.getFigure()).setIcon(null);
	}

	protected IFigure createFigure() {
		ComboFigure label = new ComboFigure("     ", COMBOBOXDROPDOWN);
		label.setFont(DEFAULT_FONT);
		label.setBorder(new CompoundBorder(new LineBorder(), new MarginBorder(0)));
		label.setTextAlignment(PositionConstants.TOP);
		label.setTextPlacement(PositionConstants.WEST);
		label.setOpaque(false);

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

	protected List getModelChildren() {
		ComboDef cd = (ComboDef) getModel();
		List result = cd.getUnmodifiableChildren();
		if (result == null)
			return Collections.EMPTY_LIST;
		return result;
	}

	public final static int MIN_HEIGHT_ITEM = 15;

	protected void refreshVisuals() {
		ComboDef combo = (ComboDef) getModel();
		int displayHeight = ComponentDef.DEFAULT_HEIGHT;
		if (isShowChildren()) {
			int heightItem = CUtil.safeToInt(combo.getHeightItem());
			heightItem = Math.max(heightItem, MIN_HEIGHT_ITEM);//
			Iterator it = combo.getTypedChildren(ComboItemDef.class);
			int childCount = 0;
			for (; it != null && it.hasNext(); it.next()) {
				childCount++;
			}
			displayHeight += heightItem * childCount;
			this.getFigure().setOpaque(true);
		} else {
			this.getFigure().setOpaque(false);
		}
		Rectangle constraint = new Rectangle(combo.getLeft(), combo.getTop(), combo
				.getWidth(), displayHeight);

		// TODO Unnatural. This "+=20" operatin should be done by PopupDef.
		if (getParent().getModel() instanceof PopupDef) {
			constraint.y += 20;
		}

		((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(),
				constraint);
		// 子EditPartのリフレッシュ
		for (Iterator it = this.getChildren().iterator(); it.hasNext();) {
			((EditPart) it.next()).refresh();
		}
	}
}