/*
 * @(#)RowSetDataObjectList.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.RenderingContext;
import oracle.cabo.ui.UIConstants;
import oracle.cabo.ui.data.DataObject;
import oracle.cabo.ui.data.DataObjectList;
import oracle.jbo.AttributeDef;
import oracle.jbo.LocaleContext;
import oracle.jbo.Row;
import oracle.jbo.RowIterator;
import oracle.jbo.RowSet;
import oracle.jbo.ViewObject;
import oracle.ord.common.PropertyConstants;
import oracle.jbo.html.DataSource;
import javax.servlet.jsp.PageContext;
import oracle.jdeveloper.html.HTMLFieldRenderer;

public class RowSetDataObjectList extends Object implements DataObjectList, DataObject
{
   protected DataSource _ds = null;
   public static final String IS_READ_ONLY_ = "_is_read_only_";
   protected int     lastIndex;   
   protected PageContext _pageContext;
   
  
   public RowSetDataObjectList(PageContext pageContext , DataSource ds)
   {
      _ds = ds;
      _pageContext = pageContext;
      RowSet rs = _ds.getRowSet();
      
      // change the view object settings for partial page behavior
      if(rs.getViewObject().getIterMode() != RowIterator.ITER_MODE_LAST_PAGE_PARTIAL)
         rs.getViewObject().setIterMode(RowIterator.ITER_MODE_LAST_PAGE_PARTIAL);

      Row row = rs.getCurrentRow();
      
      if( row == null)
      {
         row = rs.first();
      }

      if(row != null)
         lastIndex = rs.getRangeIndexOf(row);
   }

   public PageContext getPageContext()
   {
      return _pageContext;   
   }

   public void setPageContext(PageContext ctx)
   {
      _pageContext = ctx;   
   }

   public DataSource getDataSource()
   {
      return _ds;   
   }
   
   public RowSet getRowSet()
   {
      return _ds.getRowSet();;
   }

   public int getLength()
   {
      RowSet rs = _ds.getRowSet();
      int nCount = (int)rs.getEstimatedRowCount();
      int nRangeSize = rs.getRangeSize();
      int nRows = 0;
      int nRowsInRange = rs.getRowCountInRange();
            
      if( nRangeSize == -1)
      {
         nRows = nCount;
      }
      else
      {
         // if we have less rows than the range size, return the smaller of the two
         nRows = nCount < nRangeSize ? nCount : nRangeSize;
         // find the minimum
         nRows = nRowsInRange < nRows ? nRowsInRange : nRows;
      }

      return nRows;
   }

   public DataObject getItem(int index)
   {
      lastIndex = index;
      
      return this; 
   }

   public Object selectValue(RenderingContext context, Object select)
   {
      if(select == null)
        return this;

      RowSet rs = _ds.getRowSet();
      Row row = rs.getRowAtRangeIndex(lastIndex);

      if(row != null)
          rs.setCurrentRow(row);
      
      return DataObjectHelper.selectValue(this, row , context, select);
   }
}

class RowDataObjectList implements DataObjectList, DataObject
{
   protected Row     row        = null;
   protected RowSetDataObjectList _rsDOL = null;

   public RowDataObjectList(RowSetDataObjectList  rsDOL, Row row)
   {
      init(rsDOL, row);
   }

   public void init(RowSetDataObjectList  rsDOL, Row row)
   {
      _rsDOL = rsDOL;
      this.row = row;
   }

   public int getLength()
   {
      if(row == null)
         return 0;
      return row.getAttributeCount();
   }

   public DataObject getItem(int index)
   {
      return this;
   }

   public Object selectValue(RenderingContext context, Object select)
   {
      return DataObjectHelper.selectValue(_rsDOL, row , context, select);
   }

}

class DataObjectHelper
{
   static public Object selectValue(RowSetDataObjectList rsDOL, Row row, RenderingContext context, Object select)
   {
       String sName = select.toString();
       DataSource ds = rsDOL.getDataSource();
       RowSet  rs = rsDOL.getRowSet();
       
       LocaleContext locale = rs.getApplicationModule().getSession().getLocaleContext();

        // It might be a UI Hint
        if(sName.startsWith("UIHINT:"))
        {
         String sHint = sName.substring(sName.indexOf(':') + 1);
         int nIndex = sHint.indexOf(':');

         sName = sHint.substring(nIndex+1);
         sHint = sHint.substring(0, nIndex);

         // format the attribute
         AttributeDef aDef = rs.getViewObject().findAttributeDef(sName);

         String sValue = aDef.getUIHelper().getHint(locale, sHint);
         return sValue;
        }

      // return the attribute's edit rendition
      if(sName.startsWith("EDITRENDER:"))
      {
         String sAttributeName = sName.substring(sName.indexOf(':') + 1);
         
         // format the attribute
         AttributeDef aDef = rs.getViewObject().findAttributeDef(sAttributeName);
         String sRendering = "";
         
         HTMLFieldRenderer renderer = ds.getEditFieldRenderer(rsDOL.getPageContext(), row, aDef);
         sRendering = renderer.renderToString(row);
         
         return sRendering;
      }

      // return the attribute's display rendition
      if(sName.startsWith("DISPLAYRENDER:"))
      {
         String sAttributeName = sName.substring(sName.indexOf(':') + 1);
         
         // format the attribute
         AttributeDef aDef = rs.getViewObject().findAttributeDef(sAttributeName);
         String sRendering = "";
         
         HTMLFieldRenderer renderer = ds.getDisplayFieldRenderer(rsDOL.getPageContext(), row, aDef);
         sRendering = renderer.renderToString(row);
         
         return sRendering;
      }
      
      if(sName.startsWith(RowSetDataObjectList.IS_READ_ONLY_))
      {
         sName = sName.substring(RowSetDataObjectList.IS_READ_ONLY_.length());

         ViewObject   view = rs.getViewObject();
         AttributeDef aDef = view.findAttributeDef(sName);
         if(view.isReadOnly())
            return "true";

         if(row.isAttributeUpdateable(aDef.getIndex()))
            return "false";
         else
            return "true";
      }

      // if it's not a hint and we dont have a valid row, return
      if(row == null)
         return null;

      //richard: support ORD objects
      if(sName.equals(PropertyConstants.ORD_UIX_JSP_SELECT_ROW))
      {
         return row;
      }

      if(UIConstants.DISCLOSED_KEY.equals(select))
      {
         String sAttrValue = null;

         try
         {
            sAttrValue = (String)row.getAttribute("UixShowHide");
         }
         catch(oracle.jbo.NoDefException ex)
         {
            // this is an expected exception if the dynamic attribute has not been setup
         }

         if(sAttrValue == null)
            return Boolean.FALSE;

         return sAttrValue.equals("true")? Boolean.TRUE : Boolean.FALSE;
      }

      // see if we need the row key
      if(sName.equalsIgnoreCase("RowKey"))
      {
         return row.getKey().toStringFormat(true);
      }

      boolean bUseFormat = true;
      String  sFormatPrefix = "$noformat_";

      // see if the databinding client asked for the non-formatted version of the dataitem
      if(sName.startsWith(sFormatPrefix))
      {
         sName = sName.substring(sFormatPrefix.length());
         bUseFormat = false;
      }

      Object obj = row.getAttribute(sName);

      // format the attribute
      AttributeDef aDef = rs.getViewObject().findAttributeDef(sName);

      if(bUseFormat && aDef.getUIHelper().hasFormatInformation(locale))
      {
         obj = aDef.getUIHelper().getFormattedAttribute(row, locale);
      }
      if(obj == null)
         return "";

      return obj.toString();
   }
}
