/*******************************************************************************
 * Copyright (c) 2015
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *******************************************************************************/
package jsettlers.graphics.messages;

import java.util.LinkedList;
import java.util.List;

import jsettlers.common.menu.messages.IMessage;
import jsettlers.common.statistics.IGameTimeProvider;

/**
 * This is a messenger, that lets you display messages on the users screen.
 * 
 * @author michael
 */
public class Messenger {

	private final LinkedList<IMessage> messages = new LinkedList<IMessage>();
	private final IGameTimeProvider gameTimeProvider;
	private int latestTickTime;

	public Messenger(IGameTimeProvider gameTimeProvider) {
		this.gameTimeProvider = gameTimeProvider;
		this.latestTickTime = (int)System.currentTimeMillis();
	}

	/**
	 * Gets a list of messages that should be displayed to the user at the moment. It may be long, because only the first messages are displayed.
	 * <p>
	 * The messages have to be sorted by age, the one with the lowest age first.
	 * 
	 * @return The messages to display.
	 */
	public List<IMessage> getMessages() {
		return messages;
	}

	public boolean addMessage(IMessage message) {
		if (isNews(message)) {
			messages.addFirst(message);
			if (messages.size() > IMessage.MAX_MESSAGES)
				messages.removeLast();
			return true;
		}
		return false;
	}

	/**
	 * 
	 */
	public void doTick() {
		int millis = (int)System.currentTimeMillis(); 
		if (!gameTimeProvider.isGamePausing()) {
			// update message ages
			int interval = millis - latestTickTime;
			for (IMessage m : messages) {
				if (m.ageBy(interval) > IMessage.MESSAGE_TTL)
					// remove all remaining messages, assuming they in order
					while (!messages.pollLast().equals(m))
						;
			}
		}
		latestTickTime = millis;
	}

	/**
	 * Determines whether a given message is worth its display, considering nature and 
	 * content of the messages already shown. 
	 * @param msg {@link IMessage} to be inspected.
	 * @return true, if message should be displayed.
	 */
	boolean isNews(IMessage msg) {
		for (IMessage m : messages) {
			if (msg.duplicates(m)) {
				return false;
			}
		}
		return true;
	}
}

@@ -2224,234 +2224,807 @@
 %7D%0A%0A%09
-public boolean addMessage(IMessage message) %7B%0A%09%09if (isNews(message)) %7B%0A%09%09%09messages.addFirst(message);%0A%09%09%09if (messages.size() %3E IMessage.MAX_MESSAGES)%0A%09%09%09%09messages.removeLast();%0A%09%09%09return true;%0A%09%09%7D%0A%09%09return false;%0A%09%7D%0A%0A%09/**%0A%09 * 
+/**%0A%09 * Adds a given %7B@link IMessage%7D to this messenger's FIFO list, but%0A%09 * only if given message doesn't seem to be a duplicate of any of the%0A%09 * messages that are already contained. Whether its a duplicate or not%0A%09 * is determined by %7B@link IMessage#duplicates(IMessage)%7D.%0A%09 * @param message%0A%09 * @return%0A%09 */%0A%09public boolean addMessage(IMessage message) %7B%0A%09%09if (isNews(message)) %7B%0A%09%09%09messages.addFirst(message);%0A%09%09%09if (messages.size() %3E IMessage.MAX_MESSAGES)%0A%09%09%09%09messages.removeLast();%0A%09%09%09return true;%0A%09%09%7D%0A%09%09return false;%0A%09%7D%0A%0A%09/**%0A%09 * Perform perpetual update step, i.e. determine amount of time that has%0A%09 * passed since last call, let all currently active messages age by that%0A%09 * interval, then remove all messages whose age exceed the allowed%0A%09 * time-to-live (%7B@link IMessage#MESSAGE_TTL%7D).
 %0A%09 *

Add some docstring.