package e4s.tutorial;

import e4s.html.*;
import e4s.html.ajax.E4AjaxData;
import e4s.html.ajax.E4AjaxData_Intf;
import e4s.html.ajax.E4AjaxElementSelectOptionsChanger;
import e4s.html.ajax.E4SelectValuesAjax;
import e4s.html.input.extended.E4Fieldset;
import e4s.html.input.extended.E4InputFieldName;
import e4s.html.input.extended.SELECT;
import e4s.html.input.extended.E4SelectValues;
import e4s.servlet.E4ModuleImplementation;
import e4s.servlet.E4ServletImplementation_Intf;
import e4s.translate.E4LabelApp;
import e4s.util.E4StringBufferHtml;

/**
 * This example shows how a SELECT element can be filled up without
 * reloding it completley.
 *
 * {@tutorial Example_Ajax_SELECT}
 *
 * @see e4s.html.ajax.Ajax_Intf
 * @see e4s.html.input.extended.SELECT
 */
public class Example_Ajax_SELECT extends E4ModuleImplementation
{
   public static E4Method start = null;
   public static E4Method submitted = null;
   
   public final static E4InputFieldName PARAM_PLANET = new E4InputFieldName("PLANET");
   public final static E4InputFieldName PARAM_MOON = new E4InputFieldName("MOON");

   private final static String[] PLANETS = new String[]{"Mercury","Venus","Earth","Mars","Jupiter","Saturn","Uranus","Neptune"};

   private final static String[] MOONS_EARTH = {"Moon"};
   private final static String[] MOONS_SATURN = {"Mimas","Enceladus","Tethys","Dione","Rhea","Titan","Hyperion","Iapetus","Phoebe"};
   private final static String[] MOONS_JUPITER = {"Io","Europa","Ganymed","Kallisto"};
   private final static String[] MOONS_URANUS = {"Ariel","Umbriel","Titania","Miranda","Oberon"};
   private final static String[] MOONS_NEPTUNE = {"Triton","Nereid","Naiad","Thalassa","Despina"};


   private static class MoonsData extends E4AjaxData implements E4AjaxData_Intf
   {
      /**
       * Get an identification for this Ajax data object, for the case that more
       * instances of this object are used within the same session, then a unique
       * identifier is required. 
       */
      public String getDivId()
      {
         return getClass().getName();
      }
      
      /**
       * This function "renders" the content of the <OPTION> for the <SELECT> field. 
       * 
       * Typically, when using Ajax this will be a more sophisticated database read request, 
       * what's going on here is quite simple and could be solved in an easier way. But this
       * section is intended for demonstration and tutorial purpouses.
       * 
       * @param buf the buffer where we write out our conten
       * @param params the CGI parameters constructed by a previous activation of an Ajax interaction
       * @param servlet our actual servlet's context
       */
      public void toHtml( E4StringBufferHtml buf, E4CgiParams params, E4ServletImplementation_Intf servlet, boolean initial )
      {
         // this is the value the user has selected in the first selection box
         String planet = params.get(PARAM_PLANET);
         
         if (isok(planet))
         {
            String moons[] = getMoons(planet);
            E4SelectValuesAjax selMoons = null;
            
            if (moons != null)
            {
               selMoons = new E4SelectValuesAjax(moons);
            }
            else
            {
               selMoons = new E4SelectValuesAjax();
               selMoons.addElement("",new E4LabelApp("# does not have any moon(s)",planet));
            }
            
            if (selMoons != null)
               buf.append(selMoons.toAjaxXml(servlet));
         }
      }
      
      private String[] getMoons(String planet)
      {
         String res[] = null;
         
         if (planet != null)
         {
            if (planet.equals("Earth"))
               res = MOONS_EARTH;
            else if (planet.equals("Saturn"))
               res = MOONS_SATURN;
            else if (planet.equals("Jupiter"))
               res = MOONS_JUPITER;
            else if (planet.equals("Uranus"))
               res = MOONS_URANUS;
            else if (planet.equals("Neptune"))
               res = MOONS_NEPTUNE;
         }
         
         return res;
      }
   }
 
   
   public void start( HTML html )
   {
      html.Message(E4Message.QUESTION,"Welcome to SPACE TRAVEL. Where do you want to go today?");
      html.P();

      // create a form and a fieldset where the two <SELECT> fields shall appear
      FORM form = html.FORM(submitted);
      E4Fieldset fieldset = form.FIELDSET();
      
      // this is the data object, it will be displayed asynchronly whenever
      // the client's timeout indicates a new display refresh
      MoonsData moonsData = new MoonsData();

      // Create a <SELECT> field for the planets.
      SELECT fieldPlanets = fieldset.SELECT(PARAM_PLANET,"Planet",new E4SelectValues(PLANETS));
      fieldPlanets.setValue("Earth");
      
      // Create a <SELECT> field for the moons.
      SELECT fieldMoon = fieldset.SELECT(PARAM_MOON,"Moon",new E4SelectValuesAjax(MOONS_EARTH));

      // Create a E4AjaxElement and add it to our context, even if it does no direct output to HTML,
      // it is required because of some E4JavaScripts. The second <SELECT> (for the monns) is a 
      // parameter on creation of this E4AjaxElement to make the linkage between the field and the data.
      E4AjaxElementSelectOptionsChanger ajaxelement = new E4AjaxElementSelectOptionsChanger(moonsData,form,fieldMoon,getServlet());
      html.addElement(ajaxelement);
      
      // Use the provided event handler to be used for input fields...
      fieldPlanets.setEventHandler(ajaxelement.getOnChange(form));

      // finally, add a submit button to our form
      form.P();
      form.BUTTON_Submit("Continue");
   }

   /**
    * This function has nothing to do with Ajax integration, it is just the submit of the form.
    */
   public void submitted( HTML html, E4CgiParams params )
   {
      String planet = params.get(PARAM_PLANET);
      String moon = params.get(PARAM_MOON);
      
      if (! isok(moon))
      {
         html.Message(E4Message.ERROR,new E4LabelApp("Please choose a moon for planet # if applicable or another planet",planet));
         html.P();
         
         start(html);
      }
      else
      {
         html.print(new E4LabelApp("# on # is a good choice!",moon,planet));
         html.P();
         
         html.A(start).print("back");
      }
   }
}