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

import java.util.ArrayList;
import java.util.HashMap;
//import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.maskat.core.MaskatElementVisitor;
import org.maskat.core.event.Event;
import org.maskat.core.event.EventDef;
import org.maskat.core.event.EventTypeConstants;

public class Layout extends AbstractContainer {

	private LayoutDef layoutDef;

	public LayoutDef getLayoutDef() {
		return layoutDef;
	}

	public void setLayoutDef(LayoutDef layoutDef) {
		this.layoutDef = layoutDef;
	}

	public void setElement(Component component) {
		if(component.getName() == null) {
			return;
		}
	}

	public Layout getLayout() {
		return this;
	}

	/**
	 * Read the radio group data, set the group properties of the corresponding
	 * radio.
	 */
	public void unpackRadioGroup() {
		Iterator it = this.getTypedChildren(RadioGroup.class);
		if (it == null) {
			return;
		}

		final Map nameToGroupMap = new HashMap();
		while (it.hasNext()) {
			RadioGroup rg = (RadioGroup) it.next();
			String groupName = rg.getName();

			Iterator memberIt = rg.getTypedChildren(RadioMember.class);
			while (memberIt != null && memberIt.hasNext()) {
				// Get the groupMember defs
				RadioMember member = (RadioMember) memberIt.next();
				if (member.getRef() != null) {
					nameToGroupMap.put(member.getRef(), groupName);
				}
			}
		}
		// Find all the radiodef in this layout, then set groupName
		// to the group property.
		if (nameToGroupMap.size() > 0) {
			this.accept(new MaskatElementVisitor() {
				public void visit(Object def) {
					if (def instanceof Radio) {
						Radio radioDef = (Radio) def;
						radioDef.setGroup((String) nameToGroupMap.get(radioDef.getName()));
					}
				}
			});
		}
		// this.removeAllByType(RadioGroupDef.class);
	}

	/**
	 * Delete all the "empty" radio group node
	 */
	public void packRadioGroup() {
		final Map radioGroupMap = new HashMap();
		for (Iterator it = this.getTypedChildren(RadioGroup.class); 
				it != null && it.hasNext();) {
			RadioGroup rgDef = (RadioGroup) it.next();
			rgDef.removeAllByType(RadioMember.class);
			radioGroupMap.put(rgDef.getName(), rgDef);
			// layoutDefにすでにあるradioGroupをmapに入れる
		}

		this.accept(new MaskatElementVisitor() {
			public void visit(Object def) {
				if (def instanceof Radio) {
					// Create or modify a radioGroup according to the group of
					// the radio
					Radio radioDef = (Radio) def;
					String group = radioDef.getGroup();
					if (group == null || "".equals(group)) {
						return;
					}
					RadioGroup radioGroup = (RadioGroup) radioGroupMap.get(group);
					if (radioGroup == null) {
						radioGroup = new RadioGroup();
						radioGroup.setName(group);
						radioGroupMap.put(group, radioGroup);
					}
					radioGroup.addMember(radioDef.getName());
				}
			}
		});

		// Delete all the "empty" radio group node
		List radioGroupToDel = new ArrayList();
		for (Iterator it = this.getTypedChildren(RadioGroup.class); 
				it != null && it.hasNext();) {
			RadioGroup rgDef = (RadioGroup) it.next();
			Iterator rgChildIt = rgDef.getChildren();
			if (rgChildIt == null || !rgChildIt.hasNext()) {
				radioGroupToDel.add(rgDef);
			}
		}

		for (int i = 0; i < radioGroupToDel.size(); i++) {
			this.removeChild(radioGroupToDel.get(i));
		}
	}

	public RadioGroup findRadioGroupDef(String group) {
		for (Iterator it = this.getTypedChildren(RadioGroup.class);
		 		it != null && it.hasNext();) {
			RadioGroup rgd = (RadioGroup) it.next();
			if (rgd.getName() != null && rgd.getName().equals(group)) {
				return rgd;
			}
		}
		return null;
	}

	public RadioGroup createRadioGroupDef(String group) {
		RadioGroup newOne = new RadioGroup();
		newOne.setName(group);
		this.addChildToIdx(newOne, 0);
		return newOne;
	}

	public void removeRadioMemberFromGroup(String groupName, String memberName) {
		if (groupName == null || memberName == null) {
			return;
		}
		RadioGroup rgd = findRadioGroupDef(groupName);
		if (rgd == null) {
			return;
		}
		RadioMember rmd = null;
		for (Iterator it = rgd.getTypedChildren(RadioMember.class);
		 		it != null && it.hasNext();) {
			rmd = (RadioMember) it.next();
			if (memberName.equals(rmd.getRef())) {
				break;
			}
		}
		if (rmd != null) {
			rgd.removeChild(rmd);
		}
	}

	public String[] getEventTypes() {
		return new String[] {EventTypeConstants.ON_LOAD};
	}

	public Event getEvent(String eventType) {
		if (hasEvent(eventType)) {
			EventDef eventDef = getLayout().getLayoutDef().getEventDef();
			Event event = eventDef.findEvent(eventType);
			if (event == null) {
				event = new Event(eventType);
				eventDef.addChild(event);
			}
			return event;
		}
		return null;
	}
}
