/********************************************************************
 *  Oracle JDeveloper
 *  Copyright (c) 1997, 1999, Oracle Corporation. All rights reserved.
 ********************************************************************/


package oracle.jdeveloper.html;

import java.io.PrintWriter;
import java.util.Vector;


/**
 *	This class represents an HTML FORM. It provides methods for configuring and populating
 * the HTML FORM with input elements such as buttons and edit controls. Since it's derived
 * from HTMLElementContainer it can contain any HTMLElements that you would like to add to
 * it's collection.
 *
 * @author  Juan Oropeza
 * @version PUBLIC
 *
 **/
public class HTMLForm extends HTMLElementContainer
{
   protected String   theAction;
   protected String   theName;
   protected boolean  bGenerateLabels = true;
   protected Vector   Fields    =  new Vector();
   protected Vector   theScripts = new Vector();
   protected Vector   topButtons = new Vector();
   protected String   target = null;
   protected boolean  useJS = false;
   protected DHTMLButtonBar buttonBar;
   protected String   sContentType = "application/x-www-form-urlencoded";
   

   {
      setCSSClassName("vrForm");
   }

   /**
   *	Adds an HTMLScript to the form. The script may contain functions that are called by the HTML FORM
   *  and it's fields. The script gets rendered after all the form's content.
   */
   public void addScript(HTMLScript aScript)
   {
      theScripts.addElement(aScript);
   }

   public void useMultiPartFormat()
   {
     sContentType = "multipart/form-data"; 
   }

   public void useDefaultFormat()
   {
     sContentType = "application/x-www-form-urlencoded";
   }

   protected void renderScripts(PrintWriter out) throws Exception
   {
      int         nSize = theScripts.size();
      HTMLElement elem = null;

      for(int i = 0 ; i < nSize ; i++)
      {
         elem = (HTMLElement)theScripts.elementAt(i);
         elem.render(out);
      }
   }

   /**
   *	Constructs the HTML FORM object. You provide the URL via the sAction parameter and
   * the FORM nmae via the sName parameter.
   */
   public HTMLForm(String sAction , String sName)
   {
      theAction = sAction;
      theName = sName;
   }

   public String getFormName()
   {
      return theName;
   }

   /**
   *	Constructs the HTML FORM object. You provide the URL via the sAction parameter and
   * the FORM nmae via the sName parameter. The sTarget parameter refers to the target window
   * of the form when it gets submitted.
   */   
   public HTMLForm(String sAction , String sName, String sTarget)
   {
      theAction = sAction;
      theName = sName;
      target = sTarget;
   }

   protected void renderContainerHeader(PrintWriter out)
   {
      // generate form header , toolbar buttons, ...
      out.println("<FORM enctype=\"" + sContentType + "\" CLASS=" + getCSSClassName() + " NAME=\"" + theName +"\" METHOD=\"POST\" ACTION=\"" + theAction + "\" ");

      if(target != null)
      {
        out.print(" TARGET=\"" + target + "\"");
      }

      out.println(">");
   }

   protected void renderContainerFooter(PrintWriter out) throws Exception
   {
      out.println("</FORM>");
      renderScripts(out);
   }

   public void setUseJS(boolean bSet)
   {
      useJS = bSet;
   }
   
   /**
   *	Sets the FORM's action to use a different URL than the onw provided via the constructor.
   */
   public void setFormAction(String sURL)
   {
      theAction = sURL;
   }

   /**
   *	@return The current value of the FORM action URL
   */
   public String getFormAction()
   {
      return theAction;
   }

   public void addInputField(String sLabel, HTMLInputElement input)
   {
      if (sLabel != null)
      {
         Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
      }
      else
      {
         Fields.addElement(new HTMLFormField(null, input));
      }
   }

   /**
   *	Adds a hidden field to the FORM. This is very useful for passing additional hidden values with the FORM.
   */
   public void addHiddenField(String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
     
      input.setType("HIDDEN");
      input.setName(sName);
      input.setValue(sValue);

      Fields.addElement(input);
   }

   /**
   *	Adds an HTMLElement to the FORM. This is a good method to use when you are providing your own classes that are
   * used to populate the FORM's field collection.
   */
   public void addFieldElement(HTMLElement elem)
   {
       Fields.addElement(elem);
   }

   /**
   *	Adds a password field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param nWidth	The field width
   */
   public void addPasswordField(String sLabel , String sName , String sValue, int nWidth)
   {
      HTMLInputElement input = new HTMLInputElement();
     
      input.setType("PASSWORD");
      input.setSize(nWidth); // Use to be setting WIDTH???
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormPasswordField");
      
      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
   }

   /**
   *	Adds a read-only field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param nWidth	The field width
   */   
   public void addReadOnlyField(String sLabel , String sName , String sValue, int nWidth)
   {
      String sText;

      sText = sValue;

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , new HTMLTextElement(sText), bGenerateLabels));
   }      

   /**
   *	Adds an HTML SELECT  field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param aSelect	The HTMLSelect fiedl to be added.
   */
   public void addSelectField(String sLabel, HTMLSelect aSelect)
   {
      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , aSelect, bGenerateLabels));
   }   


   /**
   *	Adds a text field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param sName	The field name
   *	@param sValue	The field value
   */   
   public void addTextField(String sLabel, String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("TEXT");
      input.setSize(10);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormTextField");

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
   }
   
 /**
   *	Adds a password field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param nWidth	The field width
   */
   public void addTextField(String sLabel, String sName , String sValue, int nWidth)
   {
      // generate hidden field
      addHiddenField("_" + sName , sValue);
      
      HTMLInputElement input = new HTMLInputElement();
     
      input.setType("TEXT");
      input.setSize(nWidth);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormTextField");

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
   }

   /**
   *	Adds a password field.
   *
   *	@param sLabel	The prompt for the field.
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param nWidth	The field width
   *	@param sClass	The CSS class name
   */   
   public void addTextField(String sLabel, String sName , String sValue, String sWidth, String sClass)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("TEXT");
      input.setSize(sWidth);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName(sClass);

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
   }

   /**
   *	Adds a checkbox field.
   *
   *	@param sPrompt	The prompt for the field.
   *	@param sLabel	The label for the field.   
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param bChecked	The field's checked state
   */      
   public void addCheckBoxField(String sPrompt, String sLabel, String sName , String sValue, boolean bChecked)
   {
      // generate visible field edit
      HTMLInputElement input = new HTMLInputElement();

      input.setType("CHECKBOX");
      input.setChecked(bChecked);
      input.setName(sName);
      input.setValue(sValue);
      input.setLabel(sLabel);
      
      addInputField(sPrompt, input);
   }

   /**
   *	Adds a radio button field.
   *
   *	@param sPrompt	The prompt for the field.
   *	@param sLabel	The label for the field.   
   *	@param sName	The field name
   *	@param sValue	The field value
   *	@param bChecked	The field's checked state
   */         
   public void addRadioButtonField(String sPrompt, String sLabel, String sName , String sValue, boolean bChecked)
   {
      // generate visible field edit
      HTMLInputElement input = new HTMLInputElement();

      input.setType("RADIO");
      input.setChecked(bChecked);
      input.setName(sName);
      input.setValue(sValue);
      input.setLabel(sLabel);
      
      addInputField(sPrompt, input);
   }

   /**
   *	Adds a text field.
   *
   *	@param sLabel		The label for the field.   
   *	@param sName		The field name.
   *	@param sValue		The field value.
   *	@param sWidth		The field width.
   *	@param sClass		The field's CSS class name.
   *	@param sMaxLength	The maximum data length for the field.
   */         
   public void addTextField(String sLabel, String sName , String sValue, String sWidth, String sClass, String sMaxLength)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("TEXT");
      input.setMaxLength(sMaxLength);
      input.setSize(sWidth);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName(sClass);

      addInputField(sLabel, input);
   }

   /**
   *	Adds a text URL field.
   *
   *	@param sLabel		The label for the field.
   *	@param URL			The target URL.
   *	@param sName		The field name.
   *	@param sValue		The field value.
   */            
   public void addURLTextField(String sLabel, String URL, String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("TEXT");
      input.setSize(10);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormUrlTextField");

      // generate visible field edit
      Fields.addElement(new HTMLFormField(new HTMLTextURL(sLabel, URL) , input, bGenerateLabels));
   }

   /**
   *	Adds a Wide text field.
   *
   *	@param sLabel		The label for the field.
   *	@param sName		The field name.
   *	@param sValue		The field value.
   */               
   public void addWideTextField(String sLabel, String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("TEXT");
      input.setSize(50);
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormWideTextField");
      
      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , input, bGenerateLabels));
   }

   /**
   *	Adds a multiline text field
   *
   *	@param sLabel		The label for the field.
   *	@param sName		The field name.
   *	@param sValue		The field value.
   */               
   public void addMultilineTextField(String sLabel, String sName , String sValue)
   {
      addMultilineTextField(sLabel, sName , sValue, null);
   }


   /**
   *	Adds a textarea text field with a target number of rows.
   *
   *	@param	sLabel		The label for the field.
   *	@param	sName		The field name.
   *	@param	sValue		The field value.
   *	@param	rows		Number of rows
   */                  
   public void addMultilineTextField(String sLabel, String sName , String sValue, String rows)
   {
      rows = (rows == null) ? "5" : rows;
      
      // generate visible field edit
      String sText;
      
      sText = "<TEXTAREA NAME=\""+ sName + "\" ROWS=" + rows + " CLASS=\"vrFormTextArea\" COLS=50>" + sValue + "</TEXTAREA>";

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , new HTMLTextElement(sText), bGenerateLabels));
   }
   
   /**
   *	Adds a textarea text field with a target number of rows and columns.
   *
   *	@param	sLabel		The label for the field.
   *	@param	sName		The field name.
   *	@param	sValue		The field value.
   *	@param	cols		Number of columns
   *	@param	rows		Number of rows
   *	@param  sClass		CSS class name for field.
   */                  
   public void addMultilineTextField(String sLabel, String sName , String sValue, String cols , String rows, String sClass)
   {
      rows = (rows == null) ? "5" : rows;
      
      // generate visible field edit
      String sText;
      
      sText = "<TEXTAREA NAME=\""+ sName + "\" ROWS=" + rows + " COLS="+ cols +" CLASS=\"" + sClass +"\">" + sValue + "</TEXTAREA>";

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , new HTMLTextElement(sText), bGenerateLabels));
   }


   /**
   *	Adds a textarea text field with a target number of rows and columns.
   *
   *	@param	sLabel		The label for the field.
   *	@param	sName		The field name.
   *	@param	sValue		The field value.
   *	@param	cols		Number of columns
   *	@param	rows		Number of rows
   *	@param  sClass		CSS class name for field.
   *	@param  sMaxLength	Maximum data length
   */                     
   public void addMultilineTextField(String sLabel, String sName , String sValue, String cols , String rows, String sClass, String sMaxLength)
   {
      rows = (rows == null) ? "5" : rows;
      
      // generate visible field edit
      String sText;
      
      sText = "<TEXTAREA NAME=\""+ sName + "\"  MAXLENGTH=\"" + sMaxLength + "\" ROWS=" + rows + " COLS="+ cols +" CLASS=\"" + sClass +"\">" + sValue + "</TEXTAREA>";

      Fields.addElement(new HTMLFormField(new HTMLTextElement(sLabel) , new HTMLTextElement(sText), bGenerateLabels));
   }
   
   /**
   *	Adds a SUBMIT button to the form.
   *
   *	@param sName	button name
   *	@param sValue	button value 
   */
   public void addSubmitButton(String sName , String sValue)
   {
      if (useJS)
      {
         String sText;
         String name;
         
         if (buttonBar == null)
         {
            addHiddenField(sName, sValue);
            HTMLScript scrpt = new HTMLScript();
            scrpt.setVersion("javascript");
            scrpt.addFunction(new HTMLScriptFunction("Mimic a submit", "function submitWithValue(val) { document."+ theName +"."+ sName +".value=val; document."+ theName +".submit(); }"));
            addElement(scrpt);
            buttonBar = new DHTMLButtonBar("submitBar");
            addElement(buttonBar);
            name = "fb1";
         }
         else
         {
            name = "fb2";
         }

         DHTMLButtonElement button = new DHTMLButtonElement(name);
         button.setText(sValue);
         button.setActionType(DHTMLButtonElement.atFunction);
         button.setAction(name + ".submit(\\\"" + sValue + "\\\")");
         button.setGap("wide");
         
         buttonBar.addButton(button);
         sText = name + ".submit = submitWithValue;";
      
         buttonBar.addElement(new HTMLTextElement(sText));
      }
      else
      {
         HTMLInputElement input = new HTMLInputElement();
         
         input.setType("SUBMIT");
         input.setTabIndex(1);
         input.setName(sName);
         input.setValue(sValue);
         input.setClassName("vrFormSubmitButton");

         addElement(input);      
      }
   }

   /**
   *	Adds a RESET button to the form.
   *
   *	@param sName	button name
   *	@param sValue	button value 
   */   
   public void addResetButton(String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("RESET");
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormResetButton");

      addElement(input);      
   }

   /**
   *	Adds a SUBMIT button to the form. This button will show up in the top of the form.
   *
   *	@param sName	button name
   *	@param sValue	button value 
   */
   public void addTopSubmitButton(String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("SUBMIT");
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormSubmitButton");

      topButtons.addElement(input);      
   }

   /**
   *	Adds a RESET button to the form. This button will show up in the top of the form.
   *
   *	@param sName	button name
   *	@param sValue	button value 
   */      
   public void addTopResetButton(String sName , String sValue)
   {
      HTMLInputElement input = new HTMLInputElement();
      
      input.setType("RESET");
      input.setName(sName);
      input.setValue(sValue);
      input.setClassName("vrFormResetButton");

      topButtons.addElement(input);      
   }
   
   /**
   *	This is the main method for invoking the FORM's rendering
   */
   public void render(PrintWriter out) throws Exception
   {
      renderContainerHeader(out);
      
	   renderTopButtons(out);
	  
      out.println("<TABLE NAME=\"tbl1\" CLASS=\"vrFormTableContainer\">");
      renderFields(out);
      out.println("</TABLE>");      
      
      // this will render the buttons added by a user
      int nSize = Elements.size();
      for(int i = 0 ; i < nSize ; i++)
      {
         elementAt(i).render(out);
      }

      renderContainerFooter(out);
   }

   protected void renderFields(PrintWriter out) throws Exception
   {
      // render the table for the fields and also the fields in label, value layout
      int            nSize = Fields.size();
      HTMLElement    elem;
      
      for(int i = 0 ; i < nSize ; i++)
      {
         elem = (HTMLElement)Fields.elementAt(i);

         out.print("<TR>");               
         elem.render(out);
         out.println("</TR>");                        
      }
   }

   protected void renderTopButtons(PrintWriter out) throws Exception
   {
      // render the table for the fields and also the fields in label, value layout
      int            nSize = topButtons.size();
      HTMLElement	 elem;
      
	   if(nSize <= 0)
      {
		   return;
      }
	  
      for(int i = 0 ; i < nSize ; i++)
      {
         elem = (HTMLElement)topButtons.elementAt(i);

         elem.render(out);
      }

   }   
}

