package hirondelle.web4j.ui.translate;

import java.util.logging.*;
import hirondelle.web4j.BuildImpl;
import hirondelle.web4j.request.LocaleSource;
import hirondelle.web4j.util.Util;
import hirondelle.web4j.model.AppResponseMessage;
import hirondelle.web4j.model.MessageList;
import hirondelle.web4j.ui.tag.TagHelper;

import java.util.*;

/**
 Custom tag for rendering a {@link hirondelle.web4j.model.MessageList}.
 
  <P>Example use case :
 <PRE>
 &lt;c:if test="${not empty web4j_key_for_messages}"&gt; 
  Message(s) :
  &lt;w:messages name="web4j_key_for_messages"&gt;
   &lt;span class="message"&gt;placeholder&lt;/span&gt;&lt;br&gt;
  &lt;/w:messages&gt;
  &lt;c:remove var="web4j_key_for_messages" scope="session"/&gt;
 &lt;/c:if&gt;
 </PRE>
 
 <P>The body of this tag is a simple template for emitting each element of the named  
 {@link MessageList}. The special <tt>placeholder</tt> text is the location where 
 each item returned by {@link MessageList#getMessages()} is displayed.
*/
public final class Messages  extends TagHelper  {
  
  /**
   Key for a {@link MessageList} (in any scope).
   
   <P>Required attribute. The {@link hirondelle.web4j.action.ActionImpl} class creates two such items, identified 
   with {@link hirondelle.web4j.action.ActionImpl#ERRORS} and {@link hirondelle.web4j.action.ActionImpl#MESSAGES}. 
  */
  public void setName(String aMessageListName){
    Object object = getPageContext().findAttribute(aMessageListName);
    if ( object == null ) {
      String message = "No object named " + Util.quote(aMessageListName) + " found in any scope.";
      fLogger.severe(message);
      throw new IllegalArgumentException(message);
    }
    fMessageList = (MessageList)object;
  }
  
  /**
   Emit given template text for each item in the {@link MessageList}.
    
   <P>Emit the text in this tag's body (which acts as a template), by replacing the 
   special {@link #PLACEHOLDER} text with the content of each message. The configured 
   implementations of both {@link LocaleSource} and {@link Translator} are used to render 
   each item. (This performs "last-second localization".)
  */
  @Override protected String getEmittedText(String aOriginalBody){
    StringBuilder result = new StringBuilder();
    Locale locale = BuildImpl.forLocaleSource().get(getRequest());
    TimeZone timeZone = BuildImpl.forTimeZoneSource().get(getRequest());
    List<AppResponseMessage> messages = fMessageList.getMessages();
    for(AppResponseMessage message: messages){
      String messageText = message.getMessage(locale, timeZone);
      String fullText = replacePlaceholder(aOriginalBody, messageText);
      result.append(fullText);
    }
    return result.toString();
  }

  /**
   Special text used by this class to conveniently identify where message text 
   is placed. 
  */
  public static final String PLACEHOLDER = "placeholder";
   
  // PRIVATE 
  private MessageList fMessageList;
  private static final Logger fLogger = Util.getLogger(Messages.class);
  
  private String replacePlaceholder(String aOriginalBody, String aMessageText){
    return Util.replace(aOriginalBody, PLACEHOLDER, aMessageText); 
  }
}
