package examples.renderers;

import java.util.ArrayList;

import net.sourceforge.tapestry_jsmenu.api.BasicJSCookMenuItem;
import net.sourceforge.tapestry_jsmenu.api.IJSCookMenuItem;
import net.sourceforge.tapestry_jsmenu.api.IMenuItemRenderer;
import net.sourceforge.tapestry_jsmenu.api.IStatusMessageProvider;

import org.apache.tapestry.IComponent;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.annotations.InjectComponent;
import org.apache.tapestry.annotations.Persist;
import org.apache.tapestry.event.PageBeginRenderListener;
import org.apache.tapestry.event.PageEvent;
import org.apache.tapestry.html.BasePage;

public abstract class DifferentRenderer extends BasePage implements PageBeginRenderListener{

  /*
   * make the current choosen color and goodness values persistent 
   */
  @Persist("client")
  public abstract void setColor(String id);
  @Persist("client")
  public abstract void setGoodness(String goodness);
  
  
  /*
   * inject the renderer components to be used in the itemRenderer.render method
   */
  @InjectComponent("colorLinkRenderer")
  public abstract IComponent getColorLinkRenderer();  
  @InjectComponent("noLinkRenderer")
  public abstract IComponent getNoLinkRenderer();
  @InjectComponent("goodnessLinkRenderer")
  public abstract IComponent getGoodnessLinkRenderer();
  
  /**
   * There are three item types
   */
  public enum ItemType {
    TYPE_COLOR_LINK, TYPE_GOODNESS_LINK, TYPE_NO_LINK;
  }
  
  /**
   * construct a IMenuItemRenderer instance that is used to choose the 
   * renderer component for a given item
   * In this example the items value 
   * is an Array of the items name (String) and the type (ItemType)
   * See the contruction of the model in the pageBeginRender method 
   */
  private IMenuItemRenderer itemRenderer = new IMenuItemRenderer(){
    public IComponent render(IJSCookMenuItem item) {
      Object[] value = (Object[])((BasicJSCookMenuItem)item).getValue();
      ItemType type = (ItemType)(value[1]);
      switch(type){
        case TYPE_COLOR_LINK     : return getColorLinkRenderer();
        case TYPE_GOODNESS_LINK    : return getGoodnessLinkRenderer();
        default            return getNoLinkRenderer();
        }
    }
  };

  /**
   * The 'itemRenderer' field is bound to the 'contentRenderer' parameter of the 
   * menu component. 
   */
  public IMenuItemRenderer getItemRenderer(){
    return itemRenderer ;
  }
  
  /**
   * The 'menuItem' property referenced in the bindings. It holds the current
   * rendered item of the model 
   */
  public abstract IJSCookMenuItem getMenuItem();
  
  
  public static final String[] MY_COLORS ={
    "black",
    "orange",
    "yellow",
    "blue",
    "brown",
    "green",
    "red"
  };
  
  public static final String[] MY_GOODNESS ={
    "good",
    "better",
    "best"
  };
  
    private ArrayList<IJSCookMenuItem> model = null;
  
  /**
   * The menu model provided by the java code 
   * must be an instance of Iterable<IJSCookMenuItem>
   */
  public Iterable<IJSCookMenuItem> getMenuModel(){
    return model;
  }

  /**
   * construct a model when the page instance is new
   */
  public void pageBeginRender(PageEvent arg0) {
    if(model == null){ 
      model = new ArrayList<IJSCookMenuItem>();
      //add the color items
      BasicJSCookMenuItem colors = 
        new BasicJSCookMenuItem(new Object[]{"Choose...", ItemType.TYPE_NO_LINK});
      model.add(colors);
      for (int i = 0; i < MY_COLORS.length; i++) {
        String color = MY_COLORS[i];
        colors.addItem(new BasicJSCookMenuItem(new Object[]{color,ItemType.TYPE_COLOR_LINK}));
      }
      
      model.add(IJSCookMenuItem.MENU_SEPARATOR);
      
            //add the goodness items
      for (int i = 0; i < MY_GOODNESS.length; i++) {
        String goodness = MY_GOODNESS[i];
        model.add(new BasicJSCookMenuItem(new Object[]{goodness,ItemType.TYPE_GOODNESS_LINK}));
      }
      
    }  
  }
  
  /**
   * This is called when one of the good/better/best items is clicked
   */
  public void onDirectLink(IRequestCycle cycle, String goodness){
    setGoodness(goodness);
  }
  
  /**
   * This is called when a color is choosen
   */
  public void onColorChoose(IRequestCycle cycle, String id){
    setColor(id);
  }
  
}