package org.metaabm.gen.test;

/**
 * Network Agent Java Implementation.
 * 
 * Generated by metaabm system: May 13, 2009 11:53:52 AM PDT in project: org.metaabm.gen.repast.test  (testing) */

import static org.junit.Assert.*;

public class NetworkAgent {

	/**
	 * 
	 */

	private int vision = 0;
	/**
	 * 
	 */

	private boolean movingTowardGoal = true;
	/**
	 * Constructs a new Network Agent.
	 */

	public NetworkAgent() {
		createUniqueID();
	}

	//todo, make this a useful value for evaluating compatibility of different versions of generated classes
	private static final long serialVersionUID = 89989998L;

	private String uniqueID;

	public String getUID() {
		return uniqueID;
	}

	public void createUniqueID() {
		uniqueID = org.apache.commons.lang.RandomStringUtils
				.randomAlphanumeric(5);
	}

	/**
	 * Clones the agent, ensuring that a unique id is assigned.
	 */
	public Object clone() {
		try {
			NetworkAgent clone = (NetworkAgent) super.clone();
			clone.createUniqueID();
			return clone;
		} catch (Exception e) {
			throw new RuntimeException("Unexpected cloning exception: " + e);
		}
	}

	@org.junit.Test
	public void dummy() {
		assertTrue(true);
	}

	/**
	 * Most recent version.
	 */

	private BasicMovementModel basicMovementModelList = null;

	/**
	 * Gets the Basic Movement Model property for .
	 * @return Most recent version.
	 */

	public BasicMovementModel getBasicMovementModel() {
		return basicMovementModelList;
	}

	/**
	 * Sets the Basic Movement Model property for .
	 * Most recent version.
	 * @param _basicMovementModel the new Basic Movement Model value
	 */

	public void setBasicMovementModel(BasicMovementModel _basicMovementModel) {
		basicMovementModelList = _basicMovementModel;
	}

	public double randomInRange(double minValue, double maxValue) {
		return repast.simphony.random.RandomHelper.nextDoubleFromTo(minValue,
				maxValue);
	}

	public double randomToLimit(double maxValue) {
		return repast.simphony.random.RandomHelper.nextDoubleFromTo(0.0,
				maxValue);
	}

	public int randomToLimit(int maxValue) {
		return repast.simphony.random.RandomHelper.nextIntFromTo(0, maxValue);
	}
	/**
	 * .
	 */

	@org.junit.Test
	@repast.simphony.engine.schedule.ScheduledMethod(start = 1, interval = 1, priority = -6)
	public void simpleNetworkMoveTowardAgent() {

		final repast.simphony.context.Context context = repast.simphony.util.ContextUtils
				.getContext(this);

		final repast.simphony.space.graph.Network testNetwork = (repast.simphony.space.graph.Network) context
				.getProjection("Test Network");

		final repast.simphony.space.grid.Grid grid = (repast.simphony.space.grid.Grid) context
				.getProjection("Grid");

		/*PROTECTED REGION ID(NetworkAgent_simpleNetworkMoveTowardAgent_Pre) ENABLED START*/
		//Pre-Conditions Here
		/*PROTECTED REGION END*/

		{

			repast.simphony.query.Query<Object> spaceNeighborQuery = null;

			spaceNeighborQuery = new repast.simphony.query.space.graph.NetPathWithin(
					testNetwork, this, 1);

			repast.simphony.query.Query<Object> spaceNeighborQueryAgentClass = new repast.simphony.query.Query<Object>() {
				public java.lang.Iterable<Object> query() {

					return new repast.simphony.util.collections.FilteredIterator<Object>(
							context.iterator(),
							new org.apache.commons.collections15.Predicate() {
								public boolean evaluate(Object object) {

									return (object instanceof NetworkAgent);

								}
							});

				}
				public java.lang.Iterable<Object> query(
						java.lang.Iterable<Object> other) {
					return new repast.simphony.util.collections.FilteredIterator<Object>(
							query().iterator(),
							repast.simphony.query.QueryUtils
									.createContains(other));
				}
			};

			spaceNeighborQuery = new repast.simphony.query.AndQuery<Object>(
					spaceNeighborQuery, spaceNeighborQueryAgentClass);

			java.util.Iterator spaceNeighborIter = spaceNeighborQuery.query()
					.iterator();
			if (spaceNeighborIter.hasNext()) {
				java.util.List spaceNeighborList = org.apache.commons.collections15.IteratorUtils
						.toList(spaceNeighborIter);
				final NetworkAgent person2 = (NetworkAgent) spaceNeighborList
						.get(repast.simphony.random.RandomHelper.nextIntFromTo(
								0, spaceNeighborList.size() - 1));

				{

					repast.simphony.query.Query<Object> towardQuery = null;

					repast.simphony.query.Query<Object> towardQueryAgentClass = new repast.simphony.query.Query<Object>() {
						public java.lang.Iterable<Object> query() {

							return new repast.simphony.util.collections.FilteredIterator<Object>(
									context.iterator(),
									new org.apache.commons.collections15.Predicate() {
										public boolean evaluate(Object object) {

											return (object instanceof BasicCell);

										}
									});

						}
						public java.lang.Iterable<Object> query(
								java.lang.Iterable<Object> other) {
							return new repast.simphony.util.collections.FilteredIterator<Object>(
									query().iterator(),
									repast.simphony.query.QueryUtils
											.createContains(other));
						}
					};

					towardQuery = new repast.simphony.query.AndQuery<Object>(
							towardQuery, towardQueryAgentClass);

					java.util.Iterator towardIter = towardQuery.query()
							.iterator();
					if (towardIter.hasNext()) {
						java.util.List towardList = org.apache.commons.collections15.IteratorUtils
								.toList(towardIter);
						final BasicCell neighborGridLocation = (BasicCell) towardList
								.get(repast.simphony.random.RandomHelper
										.nextIntFromTo(0, towardList.size() - 1));

						int[] movetoPerson2Loc = grid.getLocation(
								neighborGridLocation).toIntArray(null);
						grid.moveTo(this, movetoPerson2Loc);

					}
				}

			}
		}

		/*PROTECTED REGION ID(NetworkAgent_simpleNetworkMoveTowardAgent_Post) ENABLED START*/
		//Post-Conditions Here
		/*PROTECTED REGION END*/

	}

	/**
	 * .
	 */

	@org.junit.Test
	@repast.simphony.engine.schedule.ScheduledMethod(start = 1, interval = 1, priority = -7)
	public void disconnect() {

		final repast.simphony.context.Context context = repast.simphony.util.ContextUtils
				.getContext(this);

		final repast.simphony.space.graph.Network testNetwork = (repast.simphony.space.graph.Network) context
				.getProjection("Test Network");

		/*PROTECTED REGION ID(NetworkAgent_disconnect_Pre) ENABLED START*/
		//Pre-Conditions Here
		/*PROTECTED REGION END*/

		{

			repast.simphony.query.Query<Object> spaceNeighborCopyQuery = null;

			spaceNeighborCopyQuery = new repast.simphony.query.space.graph.NetPathWithin(
					testNetwork, this, 1);

			repast.simphony.query.Query<Object> spaceNeighborCopyQueryAgentClass = new repast.simphony.query.Query<Object>() {
				public java.lang.Iterable<Object> query() {

					return new repast.simphony.util.collections.FilteredIterator<Object>(
							context.iterator(),
							new org.apache.commons.collections15.Predicate() {
								public boolean evaluate(Object object) {

									return (object instanceof NetworkAgent);

								}
							});

				}
				public java.lang.Iterable<Object> query(
						java.lang.Iterable<Object> other) {
					return new repast.simphony.util.collections.FilteredIterator<Object>(
							query().iterator(),
							repast.simphony.query.QueryUtils
									.createContains(other));
				}
			};

			spaceNeighborCopyQuery = new repast.simphony.query.AndQuery<Object>(
					spaceNeighborCopyQuery, spaceNeighborCopyQueryAgentClass);

			java.util.Iterator spaceNeighborCopyIter = spaceNeighborCopyQuery
					.query().iterator();
			if (spaceNeighborCopyIter.hasNext()) {
				java.util.List spaceNeighborCopyList = org.apache.commons.collections15.IteratorUtils
						.toList(spaceNeighborCopyIter);
				final NetworkAgent actPersonNetwork = (NetworkAgent) spaceNeighborCopyList
						.get(repast.simphony.random.RandomHelper.nextIntFromTo(
								0, spaceNeighborCopyList.size() - 1));

			}
		}

		/*PROTECTED REGION ID(NetworkAgent_disconnect_Post) ENABLED START*/
		//Post-Conditions Here
		/*PROTECTED REGION END*/

	}

	/**
	 * .
	 */

	@org.junit.Test
	@repast.simphony.engine.schedule.ScheduledMethod(start = 1, interval = 1, priority = -8)
	public void replace() {

		final repast.simphony.context.Context context = repast.simphony.util.ContextUtils
				.getContext(this);

		final repast.simphony.space.graph.Network testNetwork = (repast.simphony.space.graph.Network) context
				.getProjection("Test Network");

		/*PROTECTED REGION ID(NetworkAgent_replace_Pre) ENABLED START*/
		//Pre-Conditions Here
		/*PROTECTED REGION END*/

		{

			repast.simphony.query.Query<Object> spaceNeighborCopyCopyQuery = null;

			spaceNeighborCopyCopyQuery = new repast.simphony.query.space.graph.NetPathWithin(
					testNetwork, this, 1);

			repast.simphony.query.Query<Object> spaceNeighborCopyCopyQueryAgentClass = new repast.simphony.query.Query<Object>() {
				public java.lang.Iterable<Object> query() {

					return new repast.simphony.util.collections.FilteredIterator<Object>(
							context.iterator(),
							new org.apache.commons.collections15.Predicate() {
								public boolean evaluate(Object object) {

									return (object instanceof NetworkAgent);

								}
							});

				}
				public java.lang.Iterable<Object> query(
						java.lang.Iterable<Object> other) {
					return new repast.simphony.util.collections.FilteredIterator<Object>(
							query().iterator(),
							repast.simphony.query.QueryUtils
									.createContains(other));
				}
			};

			spaceNeighborCopyCopyQuery = new repast.simphony.query.AndQuery<Object>(
					spaceNeighborCopyCopyQuery,
					spaceNeighborCopyCopyQueryAgentClass);

			java.util.Iterator spaceNeighborCopyCopyIter = spaceNeighborCopyCopyQuery
					.query().iterator();
			if (spaceNeighborCopyCopyIter.hasNext()) {
				java.util.List spaceNeighborCopyCopyList = org.apache.commons.collections15.IteratorUtils
						.toList(spaceNeighborCopyCopyIter);
				final NetworkAgent actPersonNetworkCopy = (NetworkAgent) spaceNeighborCopyCopyList
						.get(repast.simphony.random.RandomHelper.nextIntFromTo(
								0, spaceNeighborCopyCopyList.size() - 1));

			}
		}

		/*PROTECTED REGION ID(NetworkAgent_replace_Post) ENABLED START*/
		//Post-Conditions Here
		/*PROTECTED REGION END*/

	}

	/**
	 * Gets the Vision property for Network Agent.
	 * @return 
	 */

	@repast.simphony.parameter.Parameter(displayName = "Vision", usageName = "vision", defaultValue = "0")
	public int getVision() {
		return vision;
	}

	/**
	 * Sets the Vision property for Network Agent.
	 * 
	 * @param _vision the new Vision value
	 */

	public void setVision(int _vision) {
		vision = _vision;
	}

	/**
	 * Gets the Moving Toward Goal property for Network Agent.
	 * @return 
	 */

	@repast.simphony.parameter.Parameter(displayName = "Moving Toward Goal", usageName = "movingTowardGoal", defaultValue = "true")
	public boolean isMovingTowardGoal() {
		return movingTowardGoal;
	}

	/**
	 * Sets the Moving Toward Goal property for Network Agent.
	 * 
	 * @param _movingTowardGoal the new Moving Toward Goal value
	 */

	public void setMovingTowardGoal(boolean _movingTowardGoal) {
		movingTowardGoal = _movingTowardGoal;
	}

}
