package org.opengroupware.jope.appserver;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.opengroupware.jope.foundation.NSObject;

/*
 * WOComponentStringTable
 * 
 * This is a helper class used for the 'labels' binding of WOComponent. It
 * locates a translation table for the component and then acts as a trampoline.
 * 
 * Sample:
 *   Ok: WOString { value = labels.ok; }
 */
public class WOComponentStringTable extends NSObject {
  
  protected WOComponent    component      = null;
  protected Class          componentClass = null;
  protected ResourceBundle stringTable    = null;
  
  public WOComponentStringTable(WOComponent _component) {
    this.component      = _component;
    this.componentClass = this.component.getClass();
  }
  
  /* table lookup */
  
  public void loadStringTable() {
    WOResourceManager rm = this.component.resourceManager();
    WOContext ctx   = this.component.context(); 
    String[]  langs = ctx.languages().toArray(new String[0]);
    
    /* first check for a bundle which is named like the component */
    
    if (!"Component".equals(this.component.name())) {
      this.stringTable = rm.stringTableWithName(this.component.name(),
                                                null /* framework */,
                                                langs);
    }
    
    /* next check for a resource which lives besides the class */
    // TODO: replace with a WOPkgResourceManager which does this (or make the
    //       component definition load strings)
    
    if (this.stringTable == null) {
      String rsrcname =
        this.componentClass.getPackage().getName() + ".LocalizableStrings";
      try {
        this.stringTable = 
          ResourceBundle.getBundle
            (rsrcname, 
             WOResourceManager.localeForLanguages(langs),
             this.componentClass.getClassLoader());
      }
      catch (MissingResourceException e) {
        /* no need to do anything, just continue lookup phase */
        //this.log.debug("did not find string table as class resource: " +
        //               rsrcname);
      }
    }
        
    /* then check for a bundle called LocalizableStrings */
    
    if (this.stringTable == null) {
      this.stringTable = rm.stringTableWithName(null /* name */,
                                                null /* framework */,
                                                langs);
    }
    
    // TODO: we have an issue with the WOResourceManager here. We probably
    //       need and additional method on the WOComponent which returns the
    //       manager which was used to instantiate the component?
  }
  
  /* labels */
  
  public String labelForKey(String _key, String _default) {
    if (_key == null)
      return null;
    
    /* a dynamic key (key is determined by evaluating a component binding) */
    
    if (_key.startsWith("$")) {
      Object v = this.component.valueForKey(_key.substring(1));
      if (v == null) return null;
      _key = v.toString();
    }
    
    /* ensure the string table is available */
    
    if (this.stringTable == null) {
      this.loadStringTable();
      if (this.stringTable == null)
        return null;
    }
    
    /* perform a lookup */
    
    try {
      return this.stringTable.getString(_key);
    }
    catch (MissingResourceException e) {
      return _default;
    }    
  }
  public String labelForKey(String _key) {
    return this.labelForKey(_key, _key /* default value */);
  }
  
  /* KVC */
  
  public Object valueForKey(String _key) {
    return this.labelForKey(_key, _key);
  }
}
