/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * 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 woolpack.dom;

import java.util.Map;
import java.util.Map.Entry;

import woolpack.utils.CheckUtils;

/**
 * 入力値により{@link DomContext#setId(String)}を再設定する{@link DomExpression}。 ひとつの
 * HTML フォームに複数のボタンが存在する場合に使用されることを想定している。 適用しているパターン：フィルタ。
 * 
 * @author nakamura
 * 
 */
public class BranchButton implements DomExpression {
	private final String key;

	private final Map<String, Map<String, String>> map;

	/**
	 * コンストラクタ。
	 * 
	 * @param map
	 *            変換元 id をキーとし、パラメータ名またはパラメータ値をキーとして
	 *            変換先 id を値とした{@link Map}を値とした{@link Map}。
	 * @throws NullPointerException
	 *             引数のいずれかが null の場合。
	 * @throws StringIndexOutOfBoundsException
	 *             key が空の場合。
	 */
	public BranchButton(final String key,
			final Map<String, Map<String, String>> map) {
		CheckUtils.checkNotEmpty(key);
		CheckUtils.checkNotNull(map);

		this.key = key;
		this.map = map;
	}

	public void interpret(final DomContext context) {
		final Map<String, String> m = map.get(context.getId());
		if (m != null) {
			String newId = null;
			{
				final Object value = context.getInput().get(key);
				if (value != null) {
					newId = m.get(value);
				}
			}
			if (newId == null) {
				for (final Entry<String, String> entry : m.entrySet()) {
					final Object value = context.getInput().get(entry.getKey());
					if (value != null && !value.equals("")) {
						newId = entry.getValue();
						break;
					}
				}
			}
			if (newId != null) {
				context.setId(newId);
			}
		}
	}
}
