package org.apache.struts.util;

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public abstract class MessageResources implements Serializable {
  protected static Log log = LogFactory.getLog(MessageResources.class);
  
  protected String config = null;
  
  public String getConfig() {
    return this.config;
  }
  
  protected Locale defaultLocale = Locale.getDefault();
  
  protected MessageResourcesFactory factory = null;
  
  public MessageResourcesFactory getFactory() {
    return this.factory;
  }
  
  protected HashMap formats = new HashMap();
  
  protected boolean returnNull = false;
  
  public boolean getReturnNull() {
    return this.returnNull;
  }
  
  public void setReturnNull(boolean returnNull) {
    this.returnNull = returnNull;
  }
  
  public MessageResources(MessageResourcesFactory factory, String config) {
    this(factory, config, false);
  }
  
  public MessageResources(MessageResourcesFactory factory, String config, boolean returnNull) {
    this.factory = factory;
    this.config = config;
    this.returnNull = returnNull;
  }
  
  public String getMessage(String key) {
    return getMessage((Locale)null, key);
  }
  
  public String getMessage(String key, Object[] args) {
    return getMessage((Locale)null, key, args);
  }
  
  public String getMessage(String key, Object arg0) {
    return getMessage((Locale)null, key, arg0);
  }
  
  public String getMessage(String key, Object arg0, Object arg1) {
    return getMessage((Locale)null, key, arg0, arg1);
  }
  
  public String getMessage(String key, Object arg0, Object arg1, Object arg2) {
    return getMessage((Locale)null, key, arg0, arg1, arg2);
  }
  
  public String getMessage(String key, Object arg0, Object arg1, Object arg2, Object arg3) {
    return getMessage((Locale)null, key, arg0, arg1, arg2, arg3);
  }
  
  public String getMessage(Locale locale, String key, Object[] args) {
    if (locale == null)
      locale = this.defaultLocale; 
    MessageFormat format = null;
    String formatKey = messageKey(locale, key);
    synchronized (this.formats) {
      format = (MessageFormat)this.formats.get(formatKey);
      if (format == null) {
        String formatString = getMessage(locale, key);
        if (formatString == null) {
          if (this.returnNull)
            return null; 
          return "???" + formatKey + "???";
        } 
        format = new MessageFormat(escape(formatString));
        this.formats.put(formatKey, format);
      } 
    } 
    return format.format(args);
  }
  
  public String getMessage(Locale locale, String key, Object arg0) {
    Object[] args = new Object[1];
    args[0] = arg0;
    return getMessage(locale, key, args);
  }
  
  public String getMessage(Locale locale, String key, Object arg0, Object arg1) {
    Object[] args = new Object[2];
    args[0] = arg0;
    args[1] = arg1;
    return getMessage(locale, key, args);
  }
  
  public String getMessage(Locale locale, String key, Object arg0, Object arg1, Object arg2) {
    Object[] args = new Object[3];
    args[0] = arg0;
    args[1] = arg1;
    args[2] = arg2;
    return getMessage(locale, key, args);
  }
  
  public String getMessage(Locale locale, String key, Object arg0, Object arg1, Object arg2, Object arg3) {
    Object[] args = new Object[4];
    args[0] = arg0;
    args[1] = arg1;
    args[2] = arg2;
    args[3] = arg3;
    return getMessage(locale, key, args);
  }
  
  public boolean isPresent(String key) {
    return isPresent(null, key);
  }
  
  public boolean isPresent(Locale locale, String key) {
    String message = getMessage(locale, key);
    if (message == null)
      return false; 
    if (message.startsWith("???") && message.endsWith("???"))
      return false; 
    return true;
  }
  
  protected String escape(String string) {
    if (string == null || string.indexOf('\'') < 0)
      return string; 
    int n = string.length();
    StringBuffer sb = new StringBuffer(n);
    for (int i = 0; i < n; i++) {
      char ch = string.charAt(i);
      if (ch == '\'')
        sb.append('\''); 
      sb.append(ch);
    } 
    return sb.toString();
  }
  
  protected String localeKey(Locale locale) {
    if (locale == null)
      return ""; 
    return locale.toString();
  }
  
  protected String messageKey(Locale locale, String key) {
    return localeKey(locale) + "." + key;
  }
  
  protected String messageKey(String localeKey, String key) {
    return localeKey + "." + key;
  }
  
  protected static MessageResourcesFactory defaultFactory = null;
  
  public static synchronized MessageResources getMessageResources(String config) {
    if (defaultFactory == null)
      defaultFactory = MessageResourcesFactory.createFactory(); 
    return defaultFactory.createResources(config);
  }
  
  public void log(String message) {
    log.debug(message);
  }
  
  public void log(String message, Throwable throwable) {
    log.debug(message, throwable);
  }
  
  public abstract String getMessage(Locale paramLocale, String paramString);
}
