/*
 * @(#)InputRenderTag.java
 *
 * Copyright 2001-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.jbo.html.jsp.blaf;

import oracle.cabo.ui.beans.form.FormBean;
import oracle.cabo.ui.beans.form.ChoiceBean;
import oracle.cabo.ui.beans.form.DateFieldBean;
import oracle.cabo.ui.beans.form.TextInputBean;
import oracle.cabo.ui.beans.form.FileUploadBean;
import oracle.cabo.ui.beans.RawTextBean;
import oracle.cabo.ui.data.BoundValue;
import oracle.cabo.ui.data.bind.ToBooleanBoundValue;
import oracle.cabo.ui.validate.DateValidater;
import oracle.jbo.AttributeDef;
import oracle.jbo.AttributeHints;
import oracle.jbo.LocaleContext;
import oracle.jbo.Row;
import oracle.jbo.ViewObject;
import oracle.jbo.html.DataSource;
import oracle.jbo.html.jsp.datatags.Utils;
import oracle.ord.im.OrdDomainUtil;
import oracle.jbo.common.JboTypeMap;
import oracle.jbo.html.HtmlServices;
import oracle.cabo.ui.UIConstants;
import oracle.bali.share.util.BooleanUtils;
import oracle.jdeveloper.html.HTMLFieldRenderer;
import oracle.cabo.ui.beans.layout.FlowLayoutBean;
import oracle.cabo.ui.jsps.tags.FlowLayoutTag;
import oracle.cabo.ui.MutableUINode;
import javax.servlet.jsp.tagext.TagSupport;
import oracle.cabo.ui.jsps.tags.FormTag;
import javax.servlet.jsp.PageContext;

public class InputRenderTag extends FlowLayoutTag
{
   String datasource;
   String dataitem;
   boolean useContextualBinding = true;
   MutableUINode container;
   
   public InputRenderTag()
   {
   }

   protected void initializeDateField(LocaleContext locale, AttributeDef   aDef, DateFieldBean bean)
   {
       // transfer the formatting informantion to the Cabo control
         String sFormat = aDef.getUIHelper().getHint(locale, AttributeHints.FMT_FORMAT);

         if(sFormat == null)
            sFormat = "yyyy-MM-dd";
            
         DateValidater dateValidater = new DateValidater(sFormat);

         bean.setOnSubmitValidater(dateValidater);

         container.setAttributeValue(oracle.cabo.ui.UIConstants.VALUE_ATTR,
                     new DataSourceBoundValue(getPageContext(), datasource, dataitem));
   }
   
   protected boolean hasCustomEditRenderer(AttributeDef aDef)
   {
      if(aDef.getProperty(HtmlServices.EDIT_RENDERER_KEY) != null)
         return true;
      return false;
   }
   
   protected void selectDefaultControlTypeBasedOnDomainType(DataSource ds, Row row, LocaleContext locale, AttributeDef   aDef)
   {
      if (JboTypeMap.isDateType(aDef.getSQLType()))
      {
         container = new DateFieldBean();

         initializeDateField(locale, aDef, (DateFieldBean)container);
      }
      else if (OrdDomainUtil.isOrdDomainType(aDef))
      {
         FileUploadBean fileUploadBean = new FileUploadBean();
         fileUploadBean.setName(dataitem);
         fileUploadBean.setColumns(20);

         container = fileUploadBean;
      }
      else
      {
         if(hasCustomEditRenderer(aDef))
         {
            container = new RawTextBean();

            if(useContextualBinding)
            {
               container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR,
                           new DataSourceBoundValue(getPageContext(),datasource, "EDITRENDER:" + dataitem));
            }
            else
            {
               // get the renderer and insert it's output now
               HTMLFieldRenderer renderer = ds.getEditFieldRenderer(getPageContext(), row, aDef);
               String sRendering = renderer.renderToString(row);
               container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR, sRendering);
            }
            return;
         }
         else
         {
            container = new TextInputBean();
         }
      }

      if(useContextualBinding)
      {
         container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR,
                           new DataSourceBoundValue(getPageContext(),datasource, dataitem));
      }
      else
      {
         Object obj = null;
         
         if(dataitem.equalsIgnoreCase("rowkey"))
            obj = row.getKey().toStringFormat(true);
         else
            obj = row.getAttribute(dataitem);
                  
         if(obj != null)
            container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR,
                           obj.toString());
      }

       container.setAttributeValue(UIConstants.NAME_ATTR, aDef.getName());
   }

   protected void initializeBeanPropertiesBasedOnObjectInfo(MutableUINode node, ViewObject   view, AttributeDef   aDef, LocaleContext locale)
   {
      container.setAttributeValue(UIConstants.NAME_ATTR, aDef.getName());
      
      // provide a default id
      if(getId() == null)
        container.setID(aDef.getName());
      else
        container.setID(getId());

      int nWidth = aDef.getUIHelper().getDisplayWidth(locale);
      int nHeight = aDef.getUIHelper().getDisplayHeight(locale);

      if(nWidth != 0)
        container.setAttributeValue(oracle.cabo.ui.UIConstants.COLUMNS_ATTR, new Integer(nWidth));
      if(nHeight > 1)
        container.setAttributeValue(oracle.cabo.ui.UIConstants.ROWS_ATTR, new Integer(nHeight));

      // let the data source decide when this field is read-only
      BoundValue bValue = new ToBooleanBoundValue(new DataSourceBoundValue(getPageContext(),datasource, RowSetDataObjectList.IS_READ_ONLY_ + dataitem));
      container.setAttributeValue(UIConstants.READ_ONLY_ATTR , bValue);

      // initialize visibility      
      boolean rendered = aDef.getUIHelper().getDisplayHint(locale).equals(AttributeHints.ATTRIBUTE_DISPLAY_HINT_DISPLAY);
      container.setAttributeValue(UIConstants.RENDERED_ATTR,  BooleanUtils.getBoolean(rendered));
      FlowLayoutBean bean = (FlowLayoutBean)node;
      bean.setAttributeValue(UIConstants.RENDERED_ATTR,  BooleanUtils.getBoolean(rendered));
      bean.addIndexedChild(container);
   }

   /**
    * initializeProperties
    */
   public void setProperties(MutableUINode node) 
   {
      super.setProperties(node);

      if(dataitem != null)
      {
         if(datasource != null)
         {
            useContextualBinding = JboUtil.useUixBoundValue(this, datasource);

            DataSource     ds = Utils.getDataSourceFromContext(getPageContext(), datasource);
            ViewObject     view = ds.getRowSet().getViewObject();
            AttributeDef   aDef = view.findAttributeDef(dataitem);
            LocaleContext  locale =  view.getApplicationModule().getSession().getLocaleContext();
            Row            row = Utils.getRowFromAncestor(this, datasource);

            if(row == null)
               row = ds.getRowSet().getCurrentRow();
          
            // create the bean based on the control type
            int nType = aDef.getUIHelper().getControlType(locale);

            if(OrdDomainUtil.isOrdDomainType(aDef))
            {
              FileUploadBean fileUploadBean = new FileUploadBean();
              fileUploadBean.setName(dataitem);
              fileUploadBean.setColumns(20);

              container = fileUploadBean;
              
              //
              // find the parent form tag, set the enctype="multipart/form-data" and
              // method="POST"
              //
              FormTag parent = (FormTag)TagSupport.findAncestorWithClass(this, FormTag.class);
              FormBean form = (FormBean) parent.getUINode();
              form.setUsesUpload(true);
              form.setMethod("post");
            }
            else
            {
            
            switch(nType)
            {
               case AttributeHints.CTLTYPE_LIST:
               {
                  container = new ChoiceBean();
                  break;
               }
               case AttributeHints.CTLTYPE_DATE:
               {
                  DateFieldBean date = new DateFieldBean();

                  date.setName(aDef.getName());
                  initializeDateField(locale, aDef, (DateFieldBean)container);
                  break;
               }
               case AttributeHints.CTLTYPE_EDIT:
               {
                  container = new TextInputBean();
                  TextInputBean bean = (TextInputBean)container;

                  bean.setName(aDef.getName());
                  
                  // setup the databound values
                  if(useContextualBinding)
                  {
                     container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR,
                        new DataSourceBoundValue(getPageContext(),datasource, dataitem));
                  }
                  else
                  {
                     container.setAttributeValue(oracle.cabo.ui.UIConstants.TEXT_ATTR,
                              row.getAttribute(dataitem));
                  }

                  break;
               }
               case AttributeHints.CTLTYPE_DEFAULT:
               {
                  selectDefaultControlTypeBasedOnDomainType(ds, row , locale, aDef);
                  break;
               }
            }
            }
            initializeBeanPropertiesBasedOnObjectInfo(node, view , aDef, locale);
         }
      }
   }

   public String getDatasource() {
      return datasource;
   }

   public void setDatasource(String newDatasource) {
      datasource = newDatasource;
   }

   public String getDataitem() {
      return dataitem;
   }

   public void setDataitem(String newDataitem) {
      dataitem = newDataitem;
   }

  
   public void release()
   {
      super.release();

      useContextualBinding = true;
      datasource = null;
      dataitem = null;
   }

   protected PageContext getPageContext()
   {
      return super.getPageContext();
   }
}

