/*
 * @(#)PickList.java
 *
 * Copyright 1999-2002 by Oracle Corporation,
 * 500 Oracle Parkway, Redwood Shores, California, 94065, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of Oracle Corporation.
 */

package oracle.jdeveloper.html;

import java.util.StringTokenizer;
import oracle.jbo.ApplicationModule;
import oracle.jbo.Row;
import oracle.jbo.RowSet;

/**
 * This class represents a databound picklist. It binds to data from a BC4J view object. It supports various renderings:
 * combobox, listbox,radio group and checbox group.
 *
 * @author  Juan Oropeza
 * @version PUBLIC
 *
 **/
public class PickList extends StaticPickList implements PickListContext
{
   protected   int      addNullEntry = -1;
   protected   String   sQuery = "";
   protected   RowSet   qView;
   protected   String   labelAttr;
   protected   String   dataAttr;
   protected   String   sVOPath;
   
   /**
   *	Constructs object. Default rendering is combo box.
   */
   public PickList()
   {
   }

   protected void prepareForMutliValueListGeneration()
   {
      Row rows[] = qView.getAllRowsInRange();

      allvalues.clear();
      values.clear();

      if (getAllowNulls())
      {
         allvalues.put("", "Null");
      }

      for (int i = 0; i < rows.length; i++)
      {
         allvalues.put(getHTMLValue(rows[i], qView, dataAttr), "");
      }
      // split up the field value
      StringTokenizer tokens = new StringTokenizer(getValue() , ",");

      while (tokens.hasMoreElements())
      {
         values.put(tokens.nextToken(),"");
      }
   }

   /**
   *	  Defines the data source information for the picklist
   *
   *		@param	qView		The View object this list is bound to
   */
   public void setDataSourceInfo(RowSet qView)
   {
      this.qView = qView;
   }

   /**
   *	  Defines the data source information for the picklist
   *
   *		@param	appModule	The Application Module that is used to create the view object
   *		@param	sQuery		The SQL SELECT that retrieves the pciklist values or a ViewObject name
   */
   public void setDataSourceInfo(ApplicationModule appModule, String sQuery)
   {
      try
      {
         // if it's already a view object, use it
         this.qView = appModule.findViewObject(sQuery);
      }
      catch (Exception ex)
      {
         qView = null;
      }

      if (qView == null)
      {
         this.qView = appModule.createViewObjectFromQueryStmt(null, sQuery);
      }
   }

   public void setLovVo(String voName)
   {
      sVOPath = voName;
   }

   public String getLovVo()
   {
      return sVOPath;
   }

   /**
    *		@param	sDataAttributes	The name of the attribute(s) that provides the data values
    */
   public void setDataAttributes(String sDataAttributes)
   {
      dataAttr = sDataAttributes;
   }

   public String getDataAttributes()
   {
      return dataAttr;
   }

   /**
    *		@param	sDisplayAttributes	The name of the attribute(s) that provides the label values
    */
   public void setDisplayAttributes(String sDisplayAttributes)
   {
      labelAttr = sDisplayAttributes;
   }

   public String getDisplayAttributes()
   {
      return labelAttr;
   }
   
   public void setAllowNulls(boolean bSet)
   {
      addNullEntry = (bSet ? 1 : 0);
   }

   public boolean getAllowNulls()
   {
      // If the value is not set (-1), the default is false.
      // If the value is 0 the result is false.
      // If the value is 1 the result is true.
      return (addNullEntry > 0);
   }

   protected String getRenderedString()
   {
      HTMLElementContainer cnt;
      // Remember original range info
      int rangeSize = qView.getRangeSize();
      int rangeStart = qView.getRangeStart();

      qView.setRangeSize(-1);
      
      iter = new PickListIterator();
      
      switch (nType)
      {
         case TYPE_COMBOBOX:
            {
               cnt = new HTMLElementContainer();
               HTMLSelect aSelect = (HTMLSelect) generateComboBox();
               
               if (getAllowNulls())
               {
                  String val = getValue();
      
                  if (val == null || val.length() == 0)
                  {
                     aSelect.addSelectedOption(Res.getString(Res.PROPT_NONE), "");
                  }
                  else
                  {
                     aSelect.addOption(Res.getString(Res.PROPT_NONE), "");
                  }
               }
               
               cnt.addElement(aSelect);
               break;
            }
         case TYPE_LISTBOX:
            {
               cnt = new HTMLElementContainer();
               cnt.addElement(generateListBox());
               break;
            }
         case TYPE_CHECKBOX_GROUP:
            {
               cnt = (HTMLElementContainer) generateCheckBoxGroup();
               break;
            }
         case TYPE_RADIO_GROUP:
            {
               cnt = (HTMLElementContainer) generateRadioGroup();
               
               if (getAllowNulls())
               {
                  String val = getValue();
                  boolean bSelected = (val == null || val.length() == 0);
      
                  HTMLInputElement input = new HTMLInputElement();
      
                  input.setType("RADIO");
                  input.setChecked(bSelected);
                  input.setName(getFieldName());
                  input.setValue("");
                  input.setLabel(Res.getString(Res.PROPT_NONE));
      
                  cnt.addElement(input);
                  if (bUseLineBreaks)
                     cnt.skipLine(1);
               }
               
               break;
            }

         default:
            cnt = new HTMLElementContainer();
      }

      // Add original value for comparison on the submit
      cnt.addElement(getHiddenFieldForValue());
      
      // Restore original range info
      qView.setRangeSize(rangeSize);
      qView.setRangeStart(rangeStart);

      return cnt.getAsString();
   }

   public String renderToString(Row row)
   {
      if (sVOPath != null)
      {
         setDataSourceInfo(ds.getApplicationModule(), sVOPath);
      }

      // Only set the value using the mandatory flag is the value has not
      // already been set.
      if (addNullEntry == -1)
      {
         setAllowNulls(!attrDef.isMandatory());
      }

      setValueFromRow(row);
      return getRenderedString();
   }

   // Internal class used by superclass to iterate through the list of values.
   final class PickListIterator implements ListIterator
   {
      private int i;
      private final Row rows[];

      PickListIterator()
      {
         i = 0;
         rows = qView.getAllRowsInRange();
      }

      public boolean hasNext()
      {
         return (i < rows.length);
      }

      public void next()
      {
         i++;
      }
      
      public String getLabel()
      {
         return getHTMLValue(rows[i], qView, labelAttr);
      }

      public String getValue()
      {
         return getHTMLValue(rows[i], qView, dataAttr);
      }
   }
}

