/*
 * Copyright 2014, Hridesh Rajan, Robert Dyer, 
 *                 and Iowa State University of Science and Technology
 *
 * 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 boa.compiler.visitors;

import java.util.ArrayList;
import java.util.List;

import boa.compiler.ast.expressions.VisitorExpression;
import boa.compiler.ast.statements.VisitStatement;

/**
 * Classifies each {@link VisitStatement} into groups.  Contains groups
 * for before/after visitors and default visitors (if any).
 * 
 * @author rdyer
 */
public class VisitClassifier extends AbstractVisitorNoArg {
	protected VisitStatement defaultBeforeVisit;
	protected VisitStatement defaultAfterVisit;
	protected List<VisitStatement> befores = new ArrayList<VisitStatement>();
	protected List<VisitStatement> afters = new ArrayList<VisitStatement>();

	public boolean hasDefaultBefore() {
		return defaultBeforeVisit != null;
	}

	public VisitStatement getDefaultBefore() {
		return defaultBeforeVisit;
	}

	public boolean hasDefaultAfter() {
		return defaultAfterVisit != null;
	}

	public VisitStatement getDefaultAfter() {
		return defaultAfterVisit;
	}

	public List<VisitStatement> getAfters() {
		return afters;
	}

	public List<VisitStatement> getBefores() {
		return befores;
	}

	/** @{inheritDoc} */
	@Override
	protected void initialize() {
		defaultBeforeVisit = null;
		defaultAfterVisit = null;
		befores.clear();
		afters.clear();
	}

	/** @{inheritDoc} */
	@Override
	public void visit(final VisitorExpression n) {
		// dont nest
	}

	/** @{inheritDoc} */
	@Override
	public void visit(VisitStatement n) {
		if (n.isBefore()) {
			if (n.hasWildcard())
				defaultBeforeVisit = n;
			befores.add(n);
		} else {
			if (n.hasWildcard())
				defaultAfterVisit = n;
				afters.add(n);
		}
	}
}

@@ -754,20 +754,68 @@
 va.util.
-List
+HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Aimpor
@@ -864,16 +864,52 @@
 ession;%0A
+import boa.compiler.ast.Identifier;%0A
 import b
@@ -1412,16 +1412,191 @@
 ment%3E();
+%0A%09protected Map%3CString,VisitStatement%3E beforeMap = new HashMap%3CString,VisitStatement%3E();%0A%09protected Map%3CString,VisitStatement%3E afterMap = new HashMap%3CString,VisitStatement%3E();
 %0A%0A%09publi
@@ -2021,24 +2021,174 @@
 efores;%0A%09%7D%0A%0A
+%09public Map%3CString,VisitStatement%3E getAfterMap() %7B%0A%09%09return afterMap;%0A%09%7D%0A%0A%09public Map%3CString,VisitStatement%3E getBeforeMap() %7B%0A%09%09return beforeMap;%0A%09%7D%0A%0A
 %09/** @%7Binher
@@ -2546,32 +2546,34 @@
 n.hasWildcard())
+ %7B
 %0A%09%09%09%09defaultBefo
@@ -2585,16 +2585,230 @@
 it = n;%0A
+%09%09%09%09beforeMap.put(%22_%22, n);%0A%09%09%09%7D%0A%09%09%09if (n.hasComponent())%0A%09%09%09%09beforeMap.put(((Identifier)n.getComponent().getType()).getToken(), n);%0A%09%09%09for (final Identifier id : n.getIdList())%0A%09%09%09%09beforeMap.put(id.getToken(), n);%0A
 %09%09%09befor
@@ -2852,16 +2852,18 @@
 dcard())
+ %7B
 %0A%09%09%09%09def
@@ -2882,17 +2882,227 @@
 it = n;%0A
-
 %09
+%09%09%09afterMap.put(%22_%22, n);%0A%09%09%09%7D%0A%09%09%09if (n.hasComponent())%0A%09%09%09%09afterMap.put(((Identifier)n.getComponent().getType()).getToken(), n);%0A%09%09%09for (final Identifier id : n.getIdList())%0A%09%09%09%09afterMap.put(id.getToken(), n);%0A
 %09%09%09after

modify visit classifier to keep a map of befores/afters